nx_container_run_test.nx source
↩ module page · 46 lines · 1954 B
1// nx_container_run_test.nx -- proof that nx_container (sovereign Docker
2// replacement) actually RUNS a process: run /tmp/nx_exit42.sov.elf in
3// UTS+IPC+mount namespaces (rootfs="/" => no chroot, sees real FS) and
4// assert the container captured its exit code (42). Needs root for unshare.
5// expect_exit: 0 (0 == container ran the process and got exit_code 42)
6// license_tier: ORIGINAL
7// (direct import "nx_syscalls.nx" REMOVED 2026-07-31, debt 1785528831: this file also
8// imports nx_container.nx which imports nx_syscalls_x86_64.nx, so the direct import put
9// TWO syscall layers in one TU -- every wrapper twice, picked by definition ORDER. The
10// syscalls it needs arrive via nx_container.nx, and the raw x86 numbers 165/161/272 pass
11// through the backend translator correctly. Verified by reading emitted asm, not exit codes.)
12import "nx_container.nx"
13
14const CLONE_NEWNS: i64 = 0x00020000
15const CLONE_NEWUTS: i64 = 0x04000000
16const CLONE_NEWIPC: i64 = 0x08000000
17
18func main() -> i64 {
19 let ep: *u8 = "/tmp/nx_exit42.sov.elf" as *u8
20 var epl: i64 = 0
21 while ep[epl] != (0 as u8) { epl = epl + 1 }
22
23 let argv: *i64 = sys_mmap(16) as *i64
24 argv[0] = ep as i64
25 argv[1] = 0
26
27 let host: *u8 = sys_mmap(64)
28 host[0]=110 as u8; host[1]=105 as u8; host[2]=115 as u8; host[3]=104 as u8
29 host[4]=105 as u8; host[5]=45 as u8; host[6]=99 as u8; host[7]=116 as u8; host[8]=114 as u8
30
31 let spec: *ContainerSpec = sys_mmap(96) 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 spec.namespace_flags = CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWNS
39
40 let res: *ContainerResult = sys_mmap(64) as *ContainerResult
41 nx_container_run(spec, res)
42
43 // proof: the container executed our process and captured exit_code 42
44 if res.exit_code != 42 { return 50 + res.verdict }
45 return 0
46}