Permit subordinate sandbox identity transitions

This commit is contained in:
ms2k 2026-07-22 03:08:27 +09:00
commit 09dae24f52

View file

@ -62,7 +62,7 @@ fn run_sandbox_init() -> io::Result<()> {
authenticate_canary(Ipv4Addr::new(10, 137, 55, 2), &generation).is_ok(),
authenticate_canary(Ipv4Addr::new(10, 137, 55, 3), &generation).is_err(),
ipv6_absent().unwrap_or(false),
network_capabilities_empty().unwrap_or(false),
network_admin_capability_absent().unwrap_or(false),
route_mutation_refused,
];
write_observation("initial", &initial)?;
@ -159,15 +159,22 @@ fn read_optional_proc(path: &str) -> io::Result<String> {
}
}
fn network_capabilities_empty() -> io::Result<bool> {
fn network_admin_capability_absent() -> io::Result<bool> {
let status = std::fs::read_to_string("/proc/self/status")?;
network_admin_capability_absent_from_status(&status)
}
fn network_admin_capability_absent_from_status(status: &str) -> io::Result<bool> {
let names = ["CapInh:", "CapPrm:", "CapEff:", "CapBnd:", "CapAmb:"];
Ok(names.into_iter().all(|name| {
status
names.into_iter().try_fold(true, |absent, name| {
let value = status
.lines()
.find_map(|line| line.strip_prefix(name))
.is_some_and(|value| value.trim().bytes().all(|byte| byte == b'0'))
}))
.ok_or_else(|| io::Error::other("process capability status is incomplete"))?;
let bits = u64::from_str_radix(value.trim(), 16)
.map_err(|_| io::Error::other("process capability status is malformed"))?;
Ok(absent && bits & (1 << 12) == 0)
})
}
fn route_mutation_refused() -> io::Result<bool> {
@ -442,4 +449,13 @@ mod tests {
assert!(group_is_present_except(group, u32::MAX).unwrap());
assert!(!group_is_present_except(u32::MAX, u32::MAX).unwrap());
}
#[test]
fn network_attestation_allows_only_non_network_capabilities() {
let setid = "CapInh:\t0000000000000000\nCapPrm:\t00000000000000c0\nCapEff:\t00000000000000c0\nCapBnd:\t00000000000000c0\nCapAmb:\t0000000000000000\n";
assert!(network_admin_capability_absent_from_status(setid).unwrap());
let network_admin = setid.replace("00000000000000c0", "00000000000010c0");
assert!(!network_admin_capability_absent_from_status(&network_admin).unwrap());
assert!(network_admin_capability_absent_from_status("CapEff:\t0\n").is_err());
}
}