feat: add support for read-only bind mounts in the linux sandbox#9112
feat: add support for read-only bind mounts in the linux sandbox#9112
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70efa7f7e8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
bolinfest
left a comment
There was a problem hiding this comment.
Can we maybe separate the .git -> .git/config && .git/hooks change from the bind mounts stuff and get that in first since I think it's uncontroversial?
|
@viyatb-oai Also, the |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70efa7f7e8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f77ddef574
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if is_running_as_root() { | ||
| unshare_mount_namespace()?; | ||
| } else { | ||
| unshare_user_and_mount_namespaces()?; | ||
| write_user_namespace_maps()?; |
There was a problem hiding this comment.
Handle hosts without unprivileged user namespaces
On non‑root runs this unconditionally calls unshare(CLONE_NEWUSER|CLONE_NEWNS) and bails on failure. On hosts where unprivileged user namespaces are disabled (e.g., kernel.unprivileged_userns_clone=0 or container runtimes that block CLONE_NEWUSER), that returns EPERM/ENOSYS, so the sandbox now aborts before applying Landlock even though Landlock‑only would still work. That’s an availability regression for workspace‑write in those environments; consider falling back to Landlock‑only or skipping the mount step when user‑namespace unshare fails.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 15bac577ed
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Drop ambient capabilities acquired from the user namespace so the | ||
| // sandboxed command cannot remount or create new bind mounts. | ||
| if !is_running_as_root() { | ||
| drop_caps()?; |
There was a problem hiding this comment.
Drop CAP_SYS_ADMIN even when running as root
When codex-linux-sandbox is launched as root (common in containerized CI), this branch skips drop_caps, so the sandboxed command keeps CAP_SYS_ADMIN in the host user namespace and can remount the read‑only bind mounts as read‑write, undoing the new .git protection. This means the read‑only mount enforcement only works for non‑root runs; consider dropping capabilities (or switching to an unprivileged UID) even when is_running_as_root() is true.
Useful? React with 👍 / 👎.
| let sandbox_program = env!("CARGO_BIN_EXE_codex-linux-sandbox"); | ||
| let codex_linux_sandbox_exe = Some(PathBuf::from(sandbox_program)); |
There was a problem hiding this comment.
Use absolute cargo_bin path for sandbox binary
The test pulls the sandbox binary path from CARGO_BIN_EXE_*, which is project‑relative under Buck2; if the test runs with a working directory outside the repo root, process_exec_tool_call will fail to spawn the binary and the test will panic even though the sandbox is fine. Prefer codex_utils_cargo_bin::cargo_bin("codex-linux-sandbox") to resolve an absolute path and keep Buck2 runs stable.
Useful? React with 👍 / 👎.
bolinfest
left a comment
There was a problem hiding this comment.
This is looking really good!
| // Worktrees and submodules store `.git` as a pointer file; add the | ||
| // referenced gitdir as an extra read-only target. | ||
| if is_git_pointer_file(ro_subpath) { | ||
| let gitdir = resolve_gitdir_from_file(ro_subpath)?; |
There was a problem hiding this comment.
Does it matter if gitdir is under another writable root or not? I believe this would matter in Seatbelt because of how (require-all) works there?
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7c74e970d2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if is_git_pointer_file(ro_subpath) { | ||
| let gitdir = resolve_gitdir_from_file(ro_subpath)?; |
There was a problem hiding this comment.
Treat non-pointer .git files as read-only, not fatal
This path treats any .git file as a worktree pointer and immediately errors if resolve_gitdir_from_file can’t parse gitdir: <path>. That means a workspace that happens to contain a regular .git file (or a corrupted worktree pointer) will now fail to start the sandbox, even though the .git file itself could still be safely bind‑mounted read‑only and the command could proceed. This is a new availability regression for non‑Git directories or damaged worktrees; consider skipping gitdir resolution (or logging) when the file doesn’t match the expected pointer format instead of aborting.
Useful? React with 👍 / 👎.
Motivation
.git/when the repo root is writable, so explicit mount restrictions are required for those paths.Description
linux-sandboxhelperapply_read_only_mountsinlinux-sandbox/src/mounts.rsthat: unshares namespaces, maps uids/gids when required, makes mounts private, bind-mounts targets, and remounts them read-only.apply_read_only_mounts(...)before network/seccomp and before applying Landlock rules inlinux-sandbox/src/landlock.rs.