mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
changes
changes Update codex-rs/core/src/config/mod.rs Co-authored-by: Michael Bolin <mbolin@openai.com> changes
This commit is contained in:
@@ -1302,6 +1302,67 @@ fn add_dir_override_extends_workspace_writable_roots() -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restricted_read_implicitly_allows_helper_executables() -> std::io::Result<()> {
|
||||
let temp_dir = TempDir::new()?;
|
||||
let cwd = temp_dir.path().join("workspace");
|
||||
let codex_home = temp_dir.path().join(".codex");
|
||||
let zsh_path = temp_dir.path().join("runtime").join("zsh");
|
||||
let arg0_root = codex_home.join("tmp").join("arg0");
|
||||
let execve_wrapper = arg0_root
|
||||
.join("codex-arg0-session")
|
||||
.join("codex-execve-wrapper");
|
||||
std::fs::create_dir_all(&cwd)?;
|
||||
std::fs::create_dir_all(zsh_path.parent().expect("zsh path should have parent"))?;
|
||||
std::fs::create_dir_all(
|
||||
execve_wrapper
|
||||
.parent()
|
||||
.expect("wrapper path should have parent"),
|
||||
)?;
|
||||
std::fs::write(&zsh_path, "")?;
|
||||
std::fs::write(&execve_wrapper, "")?;
|
||||
|
||||
let config = Config::load_from_base_config_with_overrides(
|
||||
ConfigToml {
|
||||
default_permissions: Some("workspace".to_string()),
|
||||
permissions: Some(PermissionsToml {
|
||||
entries: BTreeMap::from([(
|
||||
"workspace".to_string(),
|
||||
PermissionProfileToml {
|
||||
filesystem: Some(FilesystemPermissionsToml {
|
||||
entries: BTreeMap::new(),
|
||||
}),
|
||||
network: None,
|
||||
},
|
||||
)]),
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
ConfigOverrides {
|
||||
cwd: Some(cwd.clone()),
|
||||
zsh_path: Some(zsh_path.clone()),
|
||||
main_execve_wrapper_exe: Some(execve_wrapper),
|
||||
..Default::default()
|
||||
},
|
||||
codex_home,
|
||||
)?;
|
||||
|
||||
let expected_zsh = AbsolutePathBuf::try_from(zsh_path)?;
|
||||
let expected_arg0_root = AbsolutePathBuf::try_from(arg0_root)?;
|
||||
let policy = &config.permissions.file_system_sandbox_policy;
|
||||
|
||||
assert!(
|
||||
policy.can_read_path_with_cwd(expected_zsh.as_path(), &cwd),
|
||||
"expected zsh helper path to be readable, policy: {policy:?}"
|
||||
);
|
||||
assert!(
|
||||
policy.can_read_path_with_cwd(expected_arg0_root.as_path(), &cwd),
|
||||
"expected arg0 helper root to be readable, policy: {policy:?}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sqlite_home_defaults_to_codex_home_for_workspace_write() -> std::io::Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
|
||||
@@ -1940,6 +1940,68 @@ fn add_additional_file_system_writes(
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns implicit readable roots for runtime-managed helper executables that
|
||||
/// must stay usable under restricted filesystem policies without requiring
|
||||
/// explicit user permission-profile entries.
|
||||
///
|
||||
/// When the execve wrapper lives under `$CODEX_HOME/tmp/arg0`, we allowlist the
|
||||
/// shared arg0 temp root instead of a single session-specific wrapper path so
|
||||
/// future helper paths created in that tree remain readable too.
|
||||
fn helper_readable_roots(
|
||||
codex_home: &Path,
|
||||
zsh_path: Option<&PathBuf>,
|
||||
main_execve_wrapper_exe: Option<&PathBuf>,
|
||||
) -> Vec<AbsolutePathBuf> {
|
||||
let arg0_root = AbsolutePathBuf::from_absolute_path(codex_home.join("tmp").join("arg0")).ok();
|
||||
let zsh_path = zsh_path.and_then(|path| AbsolutePathBuf::from_absolute_path(path).ok());
|
||||
let execve_wrapper_root = main_execve_wrapper_exe.and_then(|path| {
|
||||
let path = AbsolutePathBuf::from_absolute_path(path).ok()?;
|
||||
if let Some(arg0_root) = arg0_root.as_ref()
|
||||
&& path.as_path().starts_with(arg0_root.as_path())
|
||||
{
|
||||
Some(arg0_root.clone())
|
||||
} else {
|
||||
Some(path)
|
||||
}
|
||||
});
|
||||
|
||||
let mut readable_roots = Vec::new();
|
||||
if let Some(zsh_path) = zsh_path {
|
||||
readable_roots.push(zsh_path);
|
||||
}
|
||||
if let Some(execve_wrapper_root) = execve_wrapper_root {
|
||||
readable_roots.push(execve_wrapper_root);
|
||||
}
|
||||
readable_roots
|
||||
}
|
||||
|
||||
fn add_additional_file_system_reads(
|
||||
file_system_sandbox_policy: &mut FileSystemSandboxPolicy,
|
||||
additional_readable_roots: &[AbsolutePathBuf],
|
||||
) {
|
||||
if file_system_sandbox_policy.has_full_disk_read_access() {
|
||||
return;
|
||||
}
|
||||
|
||||
for path in additional_readable_roots {
|
||||
let exists = file_system_sandbox_policy.entries.iter().any(|entry| {
|
||||
matches!(
|
||||
&entry.path,
|
||||
codex_protocol::permissions::FileSystemPath::Path { path: existing }
|
||||
if existing == path && entry.access == codex_protocol::permissions::FileSystemAccessMode::Read
|
||||
)
|
||||
});
|
||||
if !exists {
|
||||
file_system_sandbox_policy.entries.push(
|
||||
codex_protocol::permissions::FileSystemSandboxEntry {
|
||||
path: codex_protocol::permissions::FileSystemPath::Path { path: path.clone() },
|
||||
access: codex_protocol::permissions::FileSystemAccessMode::Read,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Optional overrides for user configuration (e.g., from CLI flags).
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct ConfigOverrides {
|
||||
@@ -2646,8 +2708,13 @@ impl Config {
|
||||
} else {
|
||||
network.enabled().then_some(network)
|
||||
};
|
||||
let helper_readable_roots = helper_readable_roots(
|
||||
&codex_home,
|
||||
zsh_path.as_ref(),
|
||||
main_execve_wrapper_exe.as_ref(),
|
||||
);
|
||||
let effective_sandbox_policy = constrained_sandbox_policy.value.get().clone();
|
||||
let effective_file_system_sandbox_policy =
|
||||
let mut effective_file_system_sandbox_policy =
|
||||
if effective_sandbox_policy == original_sandbox_policy {
|
||||
file_system_sandbox_policy
|
||||
} else {
|
||||
@@ -2656,6 +2723,10 @@ impl Config {
|
||||
&resolved_cwd,
|
||||
)
|
||||
};
|
||||
add_additional_file_system_reads(
|
||||
&mut effective_file_system_sandbox_policy,
|
||||
&helper_readable_roots,
|
||||
);
|
||||
let effective_network_sandbox_policy =
|
||||
if effective_sandbox_policy == original_sandbox_policy {
|
||||
network_sandbox_policy
|
||||
|
||||
Reference in New Issue
Block a user