Honor explicit Unix socket grants in the Linux managed sandbox (#45534)

## Why

Linux proxy-routed sandboxing denied standalone Unix sockets even when the effective network policy enabled `dangerously_allow_all_unix_sockets`.

## What changed

- Carry Unix socket permissions in `ManagedNetworkSandboxContext` and pass the prepared context through Linux sandbox launches with `--managed-network`.
- Allow `AF_UNIX` socket creation in proxy-routed mode when `dangerously_allow_all_unix_sockets` is enabled, while preserving network namespace isolation and restrictions on other socket families.
- Keep standalone Unix sockets denied by default and for path-only grants. Default missing fields in older serialized contexts to restrictive values.

## Testing

Add coverage for policy preparation and transport, legacy deserialization, and malformed policy rejection. Add a Linux integration test covering default denial, path-only denial, and explicit allow-all access, while checking that direct TCP access and `AF_NETLINK`/`AF_VSOCK` sockets remain blocked.

GitOrigin-RevId: 2695b945ad3e59fcb3faf7662d852a26650af16c
This commit is contained in:
viyatb-oai
2026-09-14 22:40:20 +00:00
committed by copyberry
parent d39cfa8a2d
commit 99914f4950
18 changed files with 599 additions and 68 deletions
@@ -962,6 +962,8 @@ mod tests {
managed_network: Some(ManagedNetworkSandboxContext {
loopback_ports: vec![43123, 48081],
allow_local_binding: false,
allow_unix_sockets: vec!["/tmp/allowed.sock".to_string()],
dangerously_allow_all_unix_sockets: true,
}),
network_proxy: Some(
RemoteNetworkProxyLaunchConfig::new(
@@ -990,6 +992,8 @@ mod tests {
serde_json::json!({
"loopbackPorts": [43123, 48081],
"allowLocalBinding": false,
"allowUnixSockets": ["/tmp/allowed.sock"],
"dangerouslyAllowAllUnixSockets": true,
})
);
assert_eq!(
@@ -1023,6 +1027,52 @@ mod tests {
assert!(legacy_serialized.get("metadata").is_none());
}
#[test]
fn exec_params_defaults_legacy_managed_network_unix_socket_policy() {
let cwd =
PathUri::from_host_native_path(std::env::current_dir().expect("current directory"))
.expect("cwd URI");
let legacy: ExecParams = serde_json::from_value(serde_json::json!({
"processId": "legacy-managed-network",
"argv": ["true"],
"cwd": cwd,
"env": {},
"tty": false,
"arg0": null,
"enforceManagedNetwork": true,
"managedNetwork": {
"loopbackPorts": [43123],
"allowLocalBinding": true,
},
}))
.expect("deserialize legacy managed network context");
assert_eq!(
legacy,
ExecParams {
process_id: ProcessId::from("legacy-managed-network"),
metadata: None,
argv: vec!["true".to_string()],
cwd,
env_policy: None,
shell_snapshot: None,
env: HashMap::new(),
tty: false,
pipe_stdin: false,
arg0: None,
sandbox: None,
enforce_managed_network: true,
managed_network: Some(ManagedNetworkSandboxContext {
loopback_ports: vec![43123],
allow_local_binding: true,
allow_unix_sockets: Vec::new(),
dangerously_allow_all_unix_sockets: false,
}),
network_proxy: None,
}
);
}
#[test]
fn environment_info_accepts_legacy_response_without_cwd() {
let info: EnvironmentInfo = serde_json::from_value(serde_json::json!({