code wiki / (root) / nx_syscall_sanity_kat.nx

nx_syscall_sanity_kat.nx source

↩ module page · 67 lines · 2998 B

1// nx_syscall_sanity_kat.nx -- T11 class: the SYSCALL-NUMBER COLLISION gate that 2// would have caught the whole class. The x86 backend feeds const syscall numbers 3// through an RV64->x86_64 translator; an x86_64 number that collides with an RV64 4// key was silently mistranslated (clone56->openat, execve59->pipe, wait4 61-> 5// getdents, socket41->unshare, kill62->lseek). Each miscompile produces WRONG 6// RUNTIME BEHAVIOR, so exercising every collision-prone wrapper and asserting a 7// sane result catches any regression. Self-checking: exit 0 == all correct. 8// See reference-syscall-number-rv64-x86-collision-2026-07-16. 9// license_tier: ORIGINAL No hw writes (Rule 26). 10import "nx_syscalls_x86_64.nx" 11 12func main() -> i64 { 13 // socket (was 41->unshare): a real AF_INET stream socket returns a fd >= 0. 14 let fd: i64 = sys_socket(2, 1, 0) 15 if fd < 0 { return 1 } 16 sys_close(fd) 17 18 // pipe2 (293, control -- must not have regressed): returns 0 + two fds. ⚠PACKED-INT32: the kernel 19 // writes BOTH int32 fds into fds[0] (read=low half, write=HIGH half); fds[1] is never written. 20 // The old form read fds[1] and false-passed on the -1 sentinel's low bits (2026-07-16 fix, caught 21 // by nx_syscalls_gate K8 hanging on the garbage write fd). Behavioral: close must SUCCEED on both. 22 let fds: *i64 = sys_mmap(16) as *i64 23 fds[0] = 0 - 1; fds[1] = 0 - 1 24 let pr: i64 = sys_pipe2(fds, 0) 25 if pr != 0 { return 2 } 26 let rfd: i64 = (fds[0]) & 0xffffffff 27 let wfd: i64 = ((fds[0]) / 4294967296) & 0xffffffff 28 if rfd < 0 { return 3 } 29 if wfd < 0 { return 4 } 30 if sys_close(rfd) != 0 { return 3 } 31 if sys_close(wfd) != 0 { return 4 } 32 33 // getuid/getgid (102/104, control): non-negative. 34 if sys_getuid() < 0 { return 5 } 35 if sys_getgid() < 0 { return 6 } 36 37 // clone(220)+wait4(260): fork a child that exits 7; the parent must capture 7. 38 // A clone->openat miscompile makes fork return -14 (EFAULT); a wait4->getdents 39 // miscompile makes the captured code garbage. 40 let pid: i64 = sys_fork() 41 if pid < 0 { return 7 } 42 if pid == 0 { sys_exit(7) } 43 let st: *i64 = sys_mmap(16) as *i64 44 *st = 0 45 sys_wait4(pid, st, 0) 46 let code: i64 = (*st >> 8) & 0xFF 47 if code != 7 { return 8 } 48 49 // execve(221): fork a child that execs /bin/true (exit 0); parent captures 0. 50 // execve->pipe miscompile makes the child NOT exec (falls through, wrong exit). 51 let pid2: i64 = sys_fork() 52 if pid2 < 0 { return 9 } 53 if pid2 == 0 { 54 let ep: *u8 = "/bin/true" as *u8 55 let av: *i64 = sys_mmap(16) as *i64 56 av[0] = ep as i64; av[1] = 0 57 sys_execve(ep, av, 0 as *i64) 58 sys_exit(42) // only reached if execve FAILED (or was miscompiled to pipe) 59 } 60 let st2: *i64 = sys_mmap(16) as *i64 61 *st2 = 0 62 sys_wait4(pid2, st2, 0) 63 let code2: i64 = (*st2 >> 8) & 0xFF 64 if code2 != 0 { return 10 } // /bin/true exits 0; 42 means execve did not exec 65 66 return 0 67}