Files
OpenShell/crates/openshell-supervisor-process
Varsha 8a14b3a477 fix(sandbox): skip read-only mounts during recursive chown of /sandbox (#2341)
* fix(sandbox): skip read-only mounts during recursive chown of /sandbox

The sandbox supervisor crashed with EROFS when the recursive chown of
/sandbox encountered read-only submounts. This is common in gVisor-based
Kubernetes deployments where read-only volume mounts are the only way to
enforce per-directory immutability (Landlock is unavailable under gVisor).

The fix adds two guards to the ownership walk:

1. Mount-boundary detection via st_dev comparison — paths on a different
   filesystem than /sandbox are skipped entirely, avoiding the chown
   call on nested read-only mounts.

2. EROFS tolerance — if chown still returns EROFS (e.g. the root mount
   itself is read-only), the error is logged at debug level and startup
   continues.

Symlink skipping (already present) is preserved and extracted into the
recursive walker for consistency.

Manually verified on a kind cluster with a read-only PVC mounted at
/sandbox/readonly-data: the pod starts successfully, writable paths are
owned by the sandbox user, and the read-only mount retains root
ownership. Kubernetes e2e test coverage is a separate follow-up.

Closes #2294

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* refactor(sandbox): consolidate symlink check into chown_recursive

Move the per-child symlink guard from the directory iteration loop into
the top of chown_recursive, reusing the symlink_metadata call that is
already performed there. This centralizes all three skip guards
(symlink, mount boundary, EROFS) in one place and eliminates a redundant
symlink_metadata call per child entry.

Suggested-by: elezar
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* fix(sandbox): recurse into children after EROFS and fix doc comment

When chown returns EROFS on a directory, the code previously returned
early without recursing into children. This skipped writable submounts
nested under a read-only directory on the same device (e.g., a writable
emptyDir inside a read-only ConfigMap mount sharing the same st_dev).

Now the EROFS case falls through to the directory recursion so that
writable children are still chowned.

Also fixes the doc comment which said EROFS errors are "logged as
warnings" when they are actually logged at debug level.

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* fix(sandbox): allow similar_names clippy lint in chown test

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* fix(sandbox): remove cross-device skip and inject chown for EROFS tests

Remove the unconditional st_dev boundary check that prevented chown on
writable PVC mounts with a different device ID. Rely solely on EROFS
errors to skip read-only paths while continuing traversal into children
and siblings.

Inject the chown operation into chown_recursive to enable unit testing
the EROFS recovery path without requiring root or mount privileges.

Signed-off-by: Varsha Prasad Narsing <vnarsing@nvidia.com>
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* style(sandbox): apply rustfmt to chown test closures

Signed-off-by: Varsha Prasad Narsing <vnarsing@nvidia.com>
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* fix(sandbox): stop descending into EROFS subtrees to prevent TOCTOU race

After chown returns EROFS, return immediately instead of recursing into
the read-only directory's children. Descending into a mount we cannot
own creates a TOCTOU window where an attacker could swap a child for a
symlink between symlink_metadata and chown (CWE-367/CWE-59). Siblings
of the EROFS path are still visited by the caller's loop.

Signed-off-by: Varsha Prasad Narsing <vnarsing@nvidia.com>
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

* fix(sandbox): hard-error on root EROFS, log read_dir failures, eliminate double stat

Chown root directly in chown_sandbox_home so EROFS on /sandbox itself
is a hard startup error rather than being silently swallowed. Extract
chown_children to log read_dir failures instead of silently skipping
them. This also eliminates the redundant symlink_metadata syscall on
the root path.

Signed-off-by: Varsha Prasad Narsing <vnarsing@nvidia.com>
Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>

---------

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
Signed-off-by: Varsha Prasad Narsing <vnarsing@nvidia.com>
2026-07-22 21:37:07 +00:00
..