Skip to content

mnt: reject untrusted staging work directories - #327

Open
mcc0nnell wants to merge 1 commit into
google:masterfrom
mcc0nnell:patch-reward/workdir-trust
Open

mcc0nnell wants to merge 1 commit into
google:masterfrom
mcc0nnell:patch-reward/workdir-trust

Conversation

@mcc0nnell

Copy link
Copy Markdown

Summary

Reject untrusted pre-existing work directories before nsjail uses them as mount-tree staging roots.

findWorkDir() tries predictable paths in shared locations such as /tmp/nsjail.<uid>.root. tryCreateDir() previously treated mkdir(...)=EEXIST as success and then used access(R_OK), which follows symlinks and does not establish that the existing object is a directory owned by the invoking user.

These paths are subsequently used as mount targets and, for the root staging tree, as the path passed into the mount/pivot-root setup.

This change requires a work directory to be:

  • a real directory, not a symlink or another file type;
  • owned by the effective user running nsjail; and
  • not group- or world-writable.

If a predictable candidate is untrusted, nsjail skips it and continues through the existing fallback candidates.

Security rationale

A different local user can pre-create a predictable shared-location candidate as a symlink or foreign-owned directory. The old EEXIST + access() check accepted that object. On Linux, a mount using a symlink path as the target resolves the symlink and operates on its target, so this allowed another local user to influence which filesystem object nsjail selected for staging.

The patch removes that precreation primitive at the point where the staging path enters the mount setup. This is a trust-boundary hardening change; I am not claiming a demonstrated sandbox escape.

Validation

  • Full make -j2: PASS.
  • make test-cmdline: PASS.
  • Existing tests/path_containment_test: PASS with new cases for an owned directory, a symlink, and a group/world-writable directory.
  • git diff --check: PASS.
  • Kernel behavior check in an unprivileged user+mount namespace confirmed that mounting on a symlink path follows the symlink target.
  • Actual patched nsjail run with /tmp/nsjail.<uid>.root pre-planted as a symlink logs Refusing untrusted work directory, falls back to another candidate, executes /bin/true, and exits 0.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant