mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
Bind final-message output before running sandboxed tools (#58974)
## Why `codex exec --output-last-message` wrote through a pathname after tools finished, allowing sandbox activity to redirect the final write by replacing that path with a symlink. The related risk is described in https://github.com/openai/codex/pull/25956. ## What changed - Open the destination before starting the agent and retain its handle until the final write. - Reject symlinks, Windows reparse points, and multiply linked files; verify that the pathname still identifies the bound file before truncating and after writing. - Propagate output errors so the command fails when the destination cannot be opened or written safely. - Preserve inherited Unix output streams, FIFOs, devices, and Windows `NUL` support, while avoiding duplicate final answers when human output targets stdout. ## Testing Add regression coverage for sandbox-created symlinks across consecutive invocations, redirected stdout, delayed truncation, hard links, replaced paths, and Windows stream binding and filesystem identity checks. GitOrigin-RevId: 4a31bd28a5eb2d0a9e200cb658eb7d19dc93e933
This commit is contained in:
@@ -151,6 +151,7 @@ async fn file_system_operations_can_reject_symlinks_in_any_path_component(
|
||||
symlink(&real, &directory_link)?;
|
||||
let file_link = tmp_path.join("file-link");
|
||||
symlink(&existing, &file_link)?;
|
||||
assert!(codex_exec_server::BoundOutput::open(&directory_link.join("existing.txt")).is_err());
|
||||
|
||||
let no_follow_read = ReadFileOptions {
|
||||
follow_symlinks: false,
|
||||
|
||||
@@ -103,6 +103,9 @@ async fn file_system_operations_can_reject_junctions_in_any_path_component(
|
||||
std::fs::write(&removable, "keep")?;
|
||||
let directory_junction = tmp.path().join("directory-junction");
|
||||
create_directory_junction(&real, &directory_junction)?;
|
||||
assert!(
|
||||
codex_exec_server::BoundOutput::open(&directory_junction.join("existing.txt")).is_err()
|
||||
);
|
||||
|
||||
let no_follow_read = ReadFileOptions {
|
||||
follow_symlinks: false,
|
||||
|
||||
Reference in New Issue
Block a user