mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
Fix macOS system-alias matching in patch permission checks (#47879)
## Why Local `apply_patch` permission checks can treat a macOS system alias and its canonical spelling as different locations, sending writes covered by temporary-directory grants for unnecessary approval. ## What changed - Normalize trusted top-level aliases in local policy roots and patch targets, reusing a prepared matcher for permission requests and patch safety checks. - Share alias normalization with Seatbelt and the macOS executor sandbox while preserving mutable symlinks and missing descendants. - Preserve read-only and deny precedence, protected metadata restrictions, and remote URI matching. Propagate normalization failures from fallible permission checks. ## Testing Add macOS regressions for multi-file patches with missing parent directories through both direct `apply_patch` calls and shell interception, asserting automatic approval and file contents. Add unit coverage for alias restriction precedence, mutable symlink preservation, missing descendants, and remote permission isolation. GitOrigin-RevId: 0822ff951eaab728cb1ad91281745fa1b8809f15
This commit is contained in:
@@ -18,7 +18,7 @@ use codex_sandboxing::SandboxManager;
|
||||
use codex_sandboxing::SandboxTransformRequest;
|
||||
use codex_sandboxing::SandboxType;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
||||
use codex_utils_absolute_path::canonicalize_preserving_symlinks;
|
||||
#[cfg(any(windows, test))]
|
||||
use codex_utils_path_uri::LegacyAppPathString;
|
||||
@@ -130,7 +130,7 @@ impl FileSystemSandboxRunner {
|
||||
// Linux resolves aliases in the sandbox helper. Doing it here also probes
|
||||
// unrelated permission roots synchronously on the executor's runtime thread.
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
normalize_file_system_policy_root_aliases(&mut file_system_policy);
|
||||
normalize_file_system_policy_root_aliases(&mut file_system_policy)?;
|
||||
#[cfg(windows)]
|
||||
bind_windows_cwd_relative_deny_read_globs(&mut file_system_policy, &cwd.uri)?;
|
||||
let network_policy = NetworkSandboxPolicy::Restricted;
|
||||
@@ -296,19 +296,34 @@ fn bind_windows_cwd_relative_deny_read_globs(
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn normalize_file_system_policy_root_aliases(file_system_policy: &mut FileSystemSandboxPolicy) {
|
||||
fn normalize_file_system_policy_root_aliases(
|
||||
file_system_policy: &mut FileSystemSandboxPolicy,
|
||||
) -> Result<(), JSONRPCErrorError> {
|
||||
for entry in &mut file_system_policy.entries {
|
||||
// Alias normalization uses this executor's filesystem; leave foreign
|
||||
// or opaque PathUris unchanged.
|
||||
if let FileSystemPath::Path { path } = &mut entry.path
|
||||
&& let Ok(native_path) = path.to_abs_path()
|
||||
{
|
||||
*path = normalize_top_level_alias(native_path).into();
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
*path = native_path
|
||||
.normalize_system_aliases()
|
||||
.map_err(|error| {
|
||||
invalid_request(format!("failed to normalize {path}: {error}"))
|
||||
})?
|
||||
.into();
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
*path = normalize_top_level_alias(native_path).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
|
||||
fn normalize_top_level_alias(path: AbsolutePathBuf) -> AbsolutePathBuf {
|
||||
let raw_path = path.to_path_buf();
|
||||
for ancestor in raw_path.ancestors() {
|
||||
|
||||
Reference in New Issue
Block a user