mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Windows Sandbox: support network_access and exclude_tmpdir_env_var (#7030)
This commit is contained in:
@@ -18,6 +18,13 @@ pub fn compute_allow_paths(
|
|||||||
allow.push(p);
|
allow.push(p);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let include_tmp_env_vars = matches!(
|
||||||
|
policy,
|
||||||
|
SandboxPolicy::WorkspaceWrite {
|
||||||
|
exclude_tmpdir_env_var: false,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if matches!(policy, SandboxPolicy::WorkspaceWrite { .. }) {
|
if matches!(policy, SandboxPolicy::WorkspaceWrite { .. }) {
|
||||||
add_path(command_cwd.to_path_buf());
|
add_path(command_cwd.to_path_buf());
|
||||||
@@ -33,7 +40,7 @@ pub fn compute_allow_paths(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !matches!(policy, SandboxPolicy::ReadOnly) {
|
if include_tmp_env_vars {
|
||||||
for key in ["TEMP", "TMP"] {
|
for key in ["TEMP", "TMP"] {
|
||||||
if let Some(v) = env_map.get(key) {
|
if let Some(v) = env_map.get(key) {
|
||||||
let abs = PathBuf::from(v);
|
let abs = PathBuf::from(v);
|
||||||
@@ -80,4 +87,32 @@ mod tests {
|
|||||||
"additional writable root should be allowed"
|
"additional writable root should be allowed"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn excludes_tmp_env_vars_when_requested() {
|
||||||
|
let command_cwd = PathBuf::from(r"C:\Workspace");
|
||||||
|
let temp_dir = PathBuf::from(r"C:\TempDir");
|
||||||
|
let _ = fs::create_dir_all(&command_cwd);
|
||||||
|
let _ = fs::create_dir_all(&temp_dir);
|
||||||
|
|
||||||
|
let policy = SandboxPolicy::WorkspaceWrite {
|
||||||
|
writable_roots: vec![],
|
||||||
|
network_access: false,
|
||||||
|
exclude_tmpdir_env_var: true,
|
||||||
|
exclude_slash_tmp: false,
|
||||||
|
};
|
||||||
|
let mut env_map = HashMap::new();
|
||||||
|
env_map.insert("TEMP".into(), temp_dir.to_string_lossy().to_string());
|
||||||
|
|
||||||
|
let allow = compute_allow_paths(&policy, &command_cwd, &command_cwd, &env_map);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
allow.iter().any(|p| p == &command_cwd),
|
||||||
|
"command cwd should be allowed"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
!allow.iter().any(|p| p == &temp_dir),
|
||||||
|
"TEMP should be excluded when exclude_tmpdir_env_var is true"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ mod windows_impl {
|
|||||||
|
|
||||||
type PipeHandles = ((HANDLE, HANDLE), (HANDLE, HANDLE), (HANDLE, HANDLE));
|
type PipeHandles = ((HANDLE, HANDLE), (HANDLE, HANDLE), (HANDLE, HANDLE));
|
||||||
|
|
||||||
|
fn should_apply_network_block(policy: &SandboxPolicy) -> bool {
|
||||||
|
!policy.has_full_network_access()
|
||||||
|
}
|
||||||
|
|
||||||
fn ensure_dir(p: &Path) -> Result<()> {
|
fn ensure_dir(p: &Path) -> Result<()> {
|
||||||
if let Some(d) = p.parent() {
|
if let Some(d) = p.parent() {
|
||||||
std::fs::create_dir_all(d)?;
|
std::fs::create_dir_all(d)?;
|
||||||
@@ -214,9 +218,12 @@ mod windows_impl {
|
|||||||
timeout_ms: Option<u64>,
|
timeout_ms: Option<u64>,
|
||||||
) -> Result<CaptureResult> {
|
) -> Result<CaptureResult> {
|
||||||
let policy = parse_policy(policy_json_or_preset)?;
|
let policy = parse_policy(policy_json_or_preset)?;
|
||||||
|
let apply_network_block = should_apply_network_block(&policy);
|
||||||
normalize_null_device_env(&mut env_map);
|
normalize_null_device_env(&mut env_map);
|
||||||
ensure_non_interactive_pager(&mut env_map);
|
ensure_non_interactive_pager(&mut env_map);
|
||||||
apply_no_network_to_env(&mut env_map)?;
|
if apply_network_block {
|
||||||
|
apply_no_network_to_env(&mut env_map)?;
|
||||||
|
}
|
||||||
ensure_codex_home_exists(codex_home)?;
|
ensure_codex_home_exists(codex_home)?;
|
||||||
|
|
||||||
let current_dir = cwd.to_path_buf();
|
let current_dir = cwd.to_path_buf();
|
||||||
@@ -447,6 +454,36 @@ mod windows_impl {
|
|||||||
timed_out,
|
timed_out,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::should_apply_network_block;
|
||||||
|
use crate::policy::SandboxPolicy;
|
||||||
|
|
||||||
|
fn workspace_policy(network_access: bool) -> SandboxPolicy {
|
||||||
|
SandboxPolicy::WorkspaceWrite {
|
||||||
|
writable_roots: Vec::new(),
|
||||||
|
network_access,
|
||||||
|
exclude_tmpdir_env_var: false,
|
||||||
|
exclude_slash_tmp: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn applies_network_block_when_access_is_disabled() {
|
||||||
|
assert!(should_apply_network_block(&workspace_policy(false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn skips_network_block_when_access_is_allowed() {
|
||||||
|
assert!(!should_apply_network_block(&workspace_policy(true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn applies_network_block_for_read_only() {
|
||||||
|
assert!(should_apply_network_block(&SandboxPolicy::ReadOnly));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
|||||||
Reference in New Issue
Block a user