mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Preserve filesystem permission path conventions (#39084)
## Why Filesystem permission paths can use a convention that differs from the host running Codex. Converting them immediately to native absolute paths can change the meaning of ambiguous paths such as `/C:/secret` or Windows UNC paths. ## What changed - Store literal filesystem permission paths as `PathUri` values through the runtime policy and execution protocol. - Keep legacy string-based serialization at explicit protocol boundaries and reject conversions that cannot be represented losslessly. - Encode native paths as opaque URIs when a normal file URI would imply the wrong path convention. ## Testing Added coverage for cross-platform and ambiguous path round trips, UNC path variants, permission-profile serialization, and deny-policy enforcement. GitOrigin-RevId: 5247713796d1f2bb4e02f94eb9fc82d4698060f0
This commit is contained in:
@@ -236,8 +236,12 @@ fn add_helper_runtime_permissions(
|
||||
|
||||
fn normalize_file_system_policy_root_aliases(file_system_policy: &mut FileSystemSandboxPolicy) {
|
||||
for entry in &mut file_system_policy.entries {
|
||||
if let FileSystemPath::Path { path } = &mut entry.path {
|
||||
*path = normalize_top_level_alias(path.clone());
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,7 +452,7 @@ mod tests {
|
||||
fn remote_sandbox_context_drops_unused_cwd() {
|
||||
let policy = FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Path {
|
||||
path: absolute_test_path("remote-root"),
|
||||
path: absolute_test_path("remote-root").into(),
|
||||
},
|
||||
access: FileSystemAccessMode::Read,
|
||||
missing_path_behavior: None,
|
||||
|
||||
@@ -15,8 +15,6 @@ use codex_protocol::models::PermissionProfile;
|
||||
#[cfg(unix)]
|
||||
use codex_protocol::permissions::FileSystemAccessMode;
|
||||
#[cfg(unix)]
|
||||
use codex_protocol::permissions::FileSystemPath;
|
||||
#[cfg(unix)]
|
||||
use codex_protocol::permissions::FileSystemSandboxEntry;
|
||||
#[cfg(unix)]
|
||||
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
||||
@@ -214,7 +212,7 @@ async fn sandboxed_discovery_follows_only_permitted_external_symlinks() -> anyho
|
||||
let root_path = AbsolutePathBuf::from_absolute_path(root.path())?;
|
||||
let external_root = AbsolutePathBuf::from_absolute_path(external.path())?;
|
||||
let path_entry =
|
||||
|path, access| FileSystemSandboxEntry::new(FileSystemPath::Path { path }, access);
|
||||
|path: AbsolutePathBuf, access| FileSystemSandboxEntry::new(path.into(), access);
|
||||
let read_root = path_entry(root_path, FileSystemAccessMode::Read);
|
||||
let read_external = path_entry(external_root.clone(), FileSystemAccessMode::Read);
|
||||
let deny_external_skill = path_entry(external_root.join("skill"), FileSystemAccessMode::Deny);
|
||||
|
||||
@@ -364,7 +364,6 @@ fn read_only_sandbox(path: std::path::PathBuf) -> codex_exec_server::FileSystemS
|
||||
use codex_exec_server::FileSystemSandboxContext;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::permissions::FileSystemAccessMode;
|
||||
use codex_protocol::permissions::FileSystemPath;
|
||||
use codex_protocol::permissions::FileSystemSandboxEntry;
|
||||
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
||||
use codex_protocol::permissions::NetworkSandboxPolicy;
|
||||
@@ -374,7 +373,7 @@ fn read_only_sandbox(path: std::path::PathBuf) -> codex_exec_server::FileSystemS
|
||||
.unwrap_or_else(|err| panic!("sandbox path should be absolute: {err}"));
|
||||
FileSystemSandboxContext::from_permission_profile(PermissionProfile::from_runtime_permissions(
|
||||
&FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Path { path },
|
||||
path: path.into(),
|
||||
access: FileSystemAccessMode::Read,
|
||||
missing_path_behavior: None,
|
||||
}]),
|
||||
|
||||
@@ -85,7 +85,7 @@ pub(crate) fn read_only_sandbox(readable_root: std::path::PathBuf) -> FileSystem
|
||||
let readable_root = absolute_path(readable_root);
|
||||
sandbox_context(vec![FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Path {
|
||||
path: readable_root,
|
||||
path: readable_root.into(),
|
||||
},
|
||||
access: FileSystemAccessMode::Read,
|
||||
missing_path_behavior: None,
|
||||
@@ -98,7 +98,7 @@ pub(crate) fn workspace_write_sandbox(
|
||||
let writable_root = absolute_path(writable_root);
|
||||
sandbox_context(vec![FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Path {
|
||||
path: writable_root,
|
||||
path: writable_root.into(),
|
||||
},
|
||||
access: FileSystemAccessMode::Write,
|
||||
missing_path_behavior: None,
|
||||
|
||||
Reference in New Issue
Block a user