code wiki / (root) / nx_container_rootless_test.nx

nx_container_rootless_test.nx source

↩ module page · 50 lines · 2076 B

1// nx_container_rootless_test.nx -- proof that nx_container runs a process in a 2// FULLY ROOTLESS container: CLONE_NEWUSER + uid/gid map (host id -> 0 inside) 3// THEN unshare(mount|pid|uts|ipc), NO sudo, NO CAP_SYS_ADMIN. This is the 4// oracle-container lane (bench/racing_crew/vendor/ORACLES.md v2): the racing 5// suites run in sovereign nx_container jails that spin up/down as any user. 6// The entrypoint (nx_exit42) returns 42; a rootless container that captures 42 7// proves the whole unprivileged namespace stack + the sovereign fork/exec/wait 8// path (clone/execve/wait4 rv64-number fix). expect_exit: 0. 9// license_tier: ORIGINAL No hw writes (Rule 26). 10import "nx_syscalls_x86_64.nx" 11import "nx_container.nx" 12 13const CLONE_NEWNS: i64 = 0x00020000 14const CLONE_NEWUTS: i64 = 0x04000000 15const CLONE_NEWIPC: i64 = 0x08000000 16 17func main() -> i64 { 18 let ep: *u8 = "/tmp/nx_exit42.sov.elf" as *u8 19 var epl: i64 = 0 20 while ep[epl] != (0 as u8) { epl = epl + 1 } 21 22 let argv: *i64 = sys_mmap(16) as *i64 23 argv[0] = ep as i64 24 argv[1] = 0 25 26 let host: *u8 = sys_mmap(64) 27 host[0]=110 as u8; host[1]=105 as u8; host[2]=115 as u8; host[3]=104 as u8 28 host[4]=105 as u8; host[5]=45 as u8; host[6]=114 as u8; host[7]=108 as u8 29 host[8]=115 as u8; host[9]=0 as u8 30 31 let spec: *ContainerSpec = sys_mmap(128) as *ContainerSpec 32 spec.rootfs_path = "/" as *u8 33 spec.rootfs_path_len = 1 34 spec.entry_path = ep 35 spec.entry_path_len = epl 36 spec.argv = argv 37 spec.hostname = host 38 // mount + uts + ipc, all unprivileged BECAUSE rootless=1 enters the user 39 // namespace first (PID omitted: CLONE_NEWPID needs a fork-after-unshare to 40 // actually enter, out of scope for this single-exec proof). 41 spec.namespace_flags = CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWNS 42 spec.rootless = 1 43 44 let res: *ContainerResult = sys_mmap(64) as *ContainerResult 45 nx_container_run(spec, res) 46 47 // proof: the rootless container executed our process and captured exit 42. 48 if res.exit_code != 42 { return 50 + res.verdict } 49 return 0 50}