test(linux-sandbox): cover host namespace guard

Co-authored-by: Codex noreply@openai.com
This commit is contained in:
viyatb-oai
2026-07-08 12:49:56 -07:00
co-authored by Codex noreply@openai.com
parent 4a534cd1f8
commit 9c1debcc05
5 changed files with 36 additions and 27 deletions
-2
View File
@@ -410,10 +410,8 @@ fn anonymous_data_file(contents: &[u8]) -> io::Result<File> {
// SAFETY: pipe2 initialized both descriptors, and each is moved into exactly one File.
let read_file = unsafe { File::from_raw_fd(pipe_fds[0]) };
// SAFETY: see above.
let mut write_file = unsafe { File::from_raw_fd(pipe_fds[1]) };
write_file.write_all(contents)?;
drop(write_file);
Ok(read_file)
}
+5 -7
View File
@@ -35,7 +35,11 @@ struct SystemBwrapCapabilities {
}
pub(crate) fn exec_bwrap(argv: Vec<String>, preserved_files: Vec<File>) -> ! {
if requests_setup_capabilities(&argv) {
if argv
.iter()
.take_while(|arg| arg.as_str() != "--")
.any(|arg| arg == "--cap-add")
{
clear_loader_environment();
}
match preferred_bwrap_launcher() {
@@ -52,12 +56,6 @@ pub(crate) fn exec_bwrap(argv: Vec<String>, preserved_files: Vec<File>) -> ! {
}
}
fn requests_setup_capabilities(argv: &[String]) -> bool {
argv.iter()
.take_while(|arg| arg.as_str() != "--")
.any(|arg| arg == "--cap-add")
}
fn clear_loader_environment() {
let keys = std::env::vars_os()
.map(|(key, _)| key)
@@ -830,6 +830,7 @@ mod tests {
use pretty_assertions::assert_eq;
use std::collections::HashMap;
use std::net::SocketAddr;
use std::os::unix::fs::MetadataExt;
use std::path::PathBuf;
#[test]
@@ -973,6 +974,23 @@ mod tests {
);
}
#[test]
fn transparent_routes_refuse_the_host_network_namespace() {
let spec = ProxyRouteSpec {
routes: vec![ProxyRouteEntry {
env_key: String::new(),
uds_path: PathBuf::new(),
}],
host_netns_inode: std::fs::metadata("/proc/self/ns/net")
.expect("network namespace metadata")
.ino(),
transparent_networking: true,
};
let serialized = serde_json::to_string(&spec).expect("serialize proxy route spec");
let err = super::activate_proxy_routes_in_netns(&serialized).expect_err("must fail closed");
assert_eq!(err.kind(), std::io::ErrorKind::PermissionDenied);
}
#[test]
fn parse_proxy_socket_dir_owner_pid_reads_owner_pid() {
assert_eq!(
@@ -93,9 +93,7 @@ impl FakeIpPool {
return Some(*address);
}
let slot = u32::try_from(self.ip_to_host.len()).ok()?.checked_add(1)?;
if slot >= 1 << 16 {
return None;
}
(slot < 1 << 16).then_some(())?;
let address = Ipv4Addr::from(FAKE_POOL_BASE + slot);
self.host_to_ip.insert(hostname.clone(), address);
self.ip_to_host.insert(address, hostname);
@@ -293,21 +293,18 @@ async fn managed_proxy_mode_routes_proxy_aware_and_direct_ipv4_traffic() {
stdout.ends_with("pong"),
"expected HTTPS tunnel payload, got: {stdout}"
);
let request = request_rx
.recv_timeout(Duration::from_secs(3))
.expect("expected direct HTTP request at proxy");
assert!(
request.starts_with("GET /direct HTTP/1.1\r\n"),
"expected captured origin-form request, got request: {request}"
);
let request = request_rx
.recv_timeout(Duration::from_secs(3))
.expect("expected CONNECT request at proxy");
assert!(
request.starts_with("CONNECT example.com:443 HTTP/1.1\r\n"),
"expected captured hostname in CONNECT request, got: {request}"
);
for expected in [
"GET /direct HTTP/1.1\r\n",
"CONNECT example.com:443 HTTP/1.1\r\n",
] {
let request = request_rx
.recv_timeout(Duration::from_secs(3))
.expect("expected direct request at proxy");
assert!(
request.starts_with(expected),
"expected captured request starting with {expected:?}, got: {request}"
);
}
}
#[tokio::test]