mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Harden unsandboxed patch filesystem access (#39659)
## Why An `apply_patch` path can be replaced with a symlink after verification, allowing an unsandboxed patch operation to reach a different file than the one that was approved. ## What changed - Add `follow_symlinks` options to executor filesystem reads, writes, metadata lookups, directory creation, and removal, including the corresponding `followSymlinks` protocol fields. - Implement no-follow filesystem operations on Unix and Windows that reject links in any path component and restrict file access to regular files. - Run `apply_patch` with symlink traversal disabled when an otherwise-required sandbox is bypassed, while retaining the existing follow-symlink default for standalone callers. ## Testing - Cover leaf and ancestor symlinks across patch add, update, delete, and move operations, including a path swap after verification. - Exercise local and remote no-follow filesystem behavior, concurrent directory creation, special-file rejection, and Windows reparse points. GitOrigin-RevId: 43fd479084891493ce13564fbd894b98f329c6dd
This commit is contained in:
@@ -361,6 +361,8 @@ pub struct TerminateResponse {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FsReadFileParams {
|
||||
pub path: PathUri,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub follow_symlinks: Option<bool>,
|
||||
pub sandbox: Option<FileSystemSandboxContext>,
|
||||
}
|
||||
|
||||
@@ -414,6 +416,8 @@ pub struct FsCloseResponse {}
|
||||
pub struct FsWriteFileParams {
|
||||
pub path: PathUri,
|
||||
pub data_base64: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub follow_symlinks: Option<bool>,
|
||||
pub sandbox: Option<FileSystemSandboxContext>,
|
||||
}
|
||||
|
||||
@@ -426,6 +430,8 @@ pub struct FsWriteFileResponse {}
|
||||
pub struct FsCreateDirectoryParams {
|
||||
pub path: PathUri,
|
||||
pub recursive: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub follow_symlinks: Option<bool>,
|
||||
pub sandbox: Option<FileSystemSandboxContext>,
|
||||
/// Atomically restrict a newly created, non-recursive directory to its owner.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
@@ -440,6 +446,8 @@ pub struct FsCreateDirectoryResponse {}
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FsGetMetadataParams {
|
||||
pub path: PathUri,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub follow_symlinks: Option<bool>,
|
||||
pub sandbox: Option<FileSystemSandboxContext>,
|
||||
}
|
||||
|
||||
@@ -504,6 +512,8 @@ pub struct FsRemoveParams {
|
||||
pub path: PathUri,
|
||||
pub recursive: Option<bool>,
|
||||
pub force: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub follow_symlinks: Option<bool>,
|
||||
pub sandbox: Option<FileSystemSandboxContext>,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user