nx_proc_ctl_gate.nx source
↩ module page · 42 lines · 3111 B
1// nx_proc_ctl_gate.nx -- proves the canonical full-cmdline matcher, including the EXACT disaster case: a 22-char
2// binary name that /proc/<pid>/comm truncates to 15 (so the old nx_proc_kill silently matched nothing). And the
3// safety: an arg mention of the same name (no leading '/') is NOT matched, so it never kills its own command.
4// Uses canonical nx_gate; no live kill (matcher is the safety-critical, deterministic part). license_tier: ORIGINAL
5import "nx_proc_ctl_cmdl.nx" // REPLACES nx_proc_ctl.nx here ONLY -- shares one symbol with it, so
6 // importing both would duplicate. Other consumers keep nx_proc_ctl.nx.
7import "nx_gate.nx"
8
9func tb(buf: *u8, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){ buf[i]=s[i]; i=i+1 } return i }
10
11func main() -> i64 {
12 gw("=== nx_proc_ctl_gate: full-cmdline matcher (the disaster fix) ===\n" as *u8)
13 let buf: *u8=sys_mmap(256)
14 var pass: i64=0; var tot: i64=0
15
16 // T1 -- the disaster case: "nx_gallery_gateway.elf" is 22 chars; comm truncates to "nx_gallery_gat" (15) and the
17 // old comm-substring match FAILS. Full cmdline "/.../nx_gallery_gateway.elf" matches "/"+name.
18 let n1: i64=tb(buf, "/volume1/nishihost/nx_gallery_gateway.elf" as *u8)
19 tot=tot+1; if nx_pctl_cmdl_has(buf, n1, "nx_gallery_gateway.elf" as *u8)==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
20 gw("T1 22-char binary path MATCHED (comm would truncate to 15 + miss = the 2026-06-29 bug)\n" as *u8)
21
22 // T2 -- safety: an arg mention (no leading '/') of the same name is NOT matched.
23 let n2: i64=tb(buf, "nx_hostctl restart nx_gallery_gateway.elf" as *u8)
24 tot=tot+1; if nx_pctl_cmdl_has(buf, n2, "nx_gallery_gateway.elf" as *u8)==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
25 gw("T2 arg mention (no leading /) NOT matched -- won't kill its own command\n" as *u8)
26
27 // T3 -- empty name never matches (an empty needle must not match every process).
28 tot=tot+1; if nx_pctl_cmdl_has(buf, n2, "" as *u8)==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
29 gw("T3 empty name -> no match (no kill-everything)\n" as *u8)
30
31 // T4/T5 -- prefix boundary: "/bin/sleep" matches "sleep"; "asleep" does NOT (must be preceded by '/').
32 let n4: i64=tb(buf, "/bin/sleep" as *u8)
33 tot=tot+1; if nx_pctl_cmdl_has(buf, n4, "sleep" as *u8)==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
34 gw("T4 \"/bin/sleep\" matches \"sleep\"\n" as *u8)
35 let n5: i64=tb(buf, "asleep zzz" as *u8)
36 tot=tot+1; if nx_pctl_cmdl_has(buf, n5, "sleep" as *u8)==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
37 gw("T5 \"asleep\" does NOT match \"sleep\" (boundary-safe)\n" as *u8)
38
39 gw("\n=== nx_proc_ctl_gate " as *u8); gn(pass); gw("/" as *u8); gn(tot); gw(" ===\n" as *u8)
40 if pass==tot { gw("PROC-CTL GREEN -- full-cmdline match fixes the comm-truncation disaster; boundary-safe; importable\n" as *u8); sys_exit(0); return 0 }
41 gw("PROC-CTL RED\n" as *u8); sys_exit(1); return 1
42}