Skip to content

tests: cover sandbox link write behavior#21819

Open
bolinfest wants to merge 1 commit intomainfrom
pr21819
Open

tests: cover sandbox link write behavior#21819
bolinfest wants to merge 1 commit intomainfrom
pr21819

Conversation

@bolinfest
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest commented May 8, 2026

Why

PR #1705 moved apply_patch execution under the configured sandbox and called out the need for integration coverage. We already covered textual ../ escapes, but did not have coverage for link aliases that live inside a writable workspace while pointing at, or aliasing, files visible outside it.

This PR locks in the current sandbox boundary without changing production write semantics. Symlink escapes into a read-only outside root should fail and leave the outside file unchanged. Existing hard links are characterized separately: if a user-created hard link already exists inside the writable root, sandboxed writes preserve normal hard-link semantics rather than replacing the link and silently breaking that relationship.

What Changed

  • Added apply_patch_cli_does_not_write_through_symlink_escape_outside_workspace to verify apply_patch cannot update a symlink that targets a file outside the writable workspace.
  • Added apply_patch_cli_preserves_existing_hard_link_outside_workspace to verify apply_patch intentionally writes through an existing hard link and does not unlink or replace it.
  • Added file_system_sandboxed_write_preserves_existing_hard_link to verify sandboxed fs/writeFile preserves an existing hard link and writes the shared inode.

Testing

  • cargo test -p codex-exec-server file_system_sandboxed_write
  • cargo test -p codex-core apply_patch_cli_does_not_write_through_symlink_escape_outside_workspace
  • cargo test -p codex-core apply_patch_cli_preserves_existing_hard_link_outside_workspace
  • just fix -p codex-exec-server -p codex-core
  • just fix -p codex-core

Stack created with Sapling. Best reviewed with ReviewStack.

@bolinfest bolinfest requested a review from a team as a code owner May 8, 2026 20:27
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f811565a3

ℹ️ 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".

Comment thread codex-rs/exec-server/src/protocol.rs Outdated
pub is_directory: bool,
pub is_file: bool,
pub is_symlink: bool,
pub link_count: u64,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve compatibility with older exec servers

When a newer client talks to an already-running remote exec-server via CODEX_EXEC_SERVER_URL, older servers will still return fs/getMetadata results without linkCount; because this new field is required during deserialization and initialize has no protocol-version/capability negotiation, every remote get_metadata call starts failing before the caller can decide whether the hard-link check actually needs the value. This breaks normal metadata users during rolling upgrades or mixed client/server deployments; make the field backward-compatible/defaulted or version-gated, and fail closed only in the apply-patch hard-link check when the count is unavailable.

Useful? React with 👍 / 👎.

Comment thread codex-rs/apply-patch/src/lib.rs Outdated
Comment on lines +567 to +569
let Some(sandbox) = sandbox.filter(|sandbox| sandbox.should_run_in_sandbox()) else {
return Ok(());
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Don't let hard-link refusals retry unsandboxed

With approval policies that allow no-sandbox retries (on-failure, on-request, or preapproved patch permissions), a hard-link write first returns PermissionDenied with Failed to write file..., which is_likely_sandbox_denied classifies as a sandbox denial; the orchestrator can then rerun the same patch with SandboxType::None, and this early return disables the hard-link guard so the second attempt writes through the hard link. The hard-link refusal needs to be treated as a terminal policy error, or the guard must also run/fail closed on no-sandbox retries for apply_patch.

Useful? React with 👍 / 👎.

@bolinfest bolinfest changed the title apply-patch: reject sandbox hard-link writes apply-patch: avoid sandbox link write-through May 8, 2026
@bolinfest bolinfest force-pushed the pr21819 branch 3 times, most recently from 7402d29 to b6dc57e Compare May 8, 2026 21:45
Copy link
Copy Markdown
Collaborator

@viyatb-oai viyatb-oai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum WorkspaceLinkKind {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can this be a bool? codex overreacted here a bit it feels

"{FS_WRITE_FILE_METHOD} requires valid base64 dataBase64: {err}"
))
})?;
file_system
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is file_system.write_file still used?

Copy link
Copy Markdown
Collaborator

@pakrym-oai pakrym-oai May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to keep the pattern or all logic living in local_file_system eventually and keep this file purely a router.

@bolinfest
Copy link
Copy Markdown
Collaborator Author

Update: I think this is not an appropriate fix, as written. Sandboxed Codex cannot create hard links outside the sandbox, but if the user created such a hardlink, then I think (1) we should preserve it rather than de-link it by doing a rename() over it and (2) Codex is "within its rights" to write to such a hardlink such that changes it makes will be visible from other paths outside the writable folder.

@bolinfest bolinfest changed the title apply-patch: avoid sandbox link write-through tests: cover sandbox link write behavior May 9, 2026
@bolinfest bolinfest force-pushed the pr21819 branch 2 times, most recently from b50e4f8 to a38c847 Compare May 9, 2026 00:19
@bolinfest bolinfest requested a review from starr-openai May 9, 2026 00:25
@bolinfest bolinfest force-pushed the pr21819 branch 2 times, most recently from 16614d5 to ebddba6 Compare May 9, 2026 01:16
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.

4 participants