code wiki / _hdl_build / _bs_poison.nx

_bs_poison.nx source

↩ module page · 112 lines · 5055 B

1// _bs_poison.nx -- R1-T1-004 / X-CLEAN-002 the "next reproducer": try to make the LATENT nxasm 2// rc=6 uninit-read DETERMINISTIC by POISONING the child's inherited context. R1-T1-004 pinned the 3// class as parent-ctx x output-path (uninit-read in nxasm, value=parent-residue, relevance=path-slot) 4// but the trigger went latent (fresh /tmp, residue gone). This probe floods the nxasm child's 5// inherited ENVIRONMENT (the parent-controlled bytes that survive execve) with several poison 6// patterns x sizes, plus a 1MB poison scratch fill, and assembles ONE real .s to a genuinely 7// WRITABLE output path under each config. CONTROL = clean env (must rc=0). If ANY poison config 8// makes a WRITABLE path fail (rc!=0), the uninit-read picked up poison -> DETERMINISTIC TRIGGER 9// FOUND (then bisect nxasm). If all stay rc=0, the defect is not reachable via this vector 10// (strengthens latent/non-reproducible -> no-overclaim close). Pure diagnostic; NO nxasm edits. 11// license_tier: ORIGINAL 12import "nx_syscalls.nx" 13 14func bp_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 15func bp_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48;k=1}; while m>0 {t[k]=(48+(m%10)) as u8; m=m/10; k=k+1}; var i: i64=0; while i<k {bb[i]=t[k-1-i]; i=i+1}; sys_write(1, bb, k); return 0 } 16 17// fork + execve + wait4 -> WEXITSTATUS (or 128+sig). Faithful copy of rg_run / sbr_run. 18func bp_run(path: *u8, argv: *i64, envp: *i64) -> i64 { 19 let pid: i64 = sys_fork() 20 if pid == 0 { 21 sys_execve(path, argv, envp) 22 sys_exit(127) 23 } 24 let st: *i64 = sys_mmap(16) as *i64 25 sys_wait4(pid, st, 0) 26 let sig: i64 = st[0] & 0x7f 27 if sig != 0 { return 128 + sig } 28 return (st[0] >> 8) & 0xff 29} 30 31func bp_try(asm_tool: *u8, spath: *u8, outpath: *u8, envp: *i64) -> i64 { 32 let aa: *i64 = sys_mmap(8 * 4) as *i64 33 aa[0] = asm_tool as i64; aa[1] = spath as i64; aa[2] = outpath as i64; aa[3] = 0 34 return bp_run(asm_tool, aa, envp) 35} 36 37// build an envp = [PATH, <count> poison vars of slen bytes filled with pattern, 0]. 38func bp_poison_env(pattern: i64, count: i64, slen: i64) -> *i64 { 39 let envp: *i64 = sys_mmap(8 * (count + 2)) as *i64 40 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64 41 var e: i64 = 1 42 while e <= count { 43 let s: *u8 = sys_mmap(slen + 4) 44 s[0] = 90 as u8 // 'Z' 45 s[1] = 61 as u8 // '=' 46 var i: i64 = 2 47 while i < slen { s[i] = pattern as u8; i = i + 1 } 48 s[slen] = 0 as u8 49 envp[e] = s as i64 50 e = e + 1 51 } 52 envp[count + 1] = 0 53 return envp 54} 55 56func main() -> i64 { 57 let asm_tool: *u8 = "_offc/nxasm_x86_main.elf" as *u8 58 let spath: *u8 = "/tmp/repro_in.s" as *u8 // a REAL .s (runner pre-builds it) 59 let validout: *u8 = "/tmp/_bs_out.elf" as *u8 // WRITABLE: rc must be 0 unless the uninit-read corrupts it 60 61 // 1MB poison scratch fill (the literal R1-T1-004 "fill parent w/ pattern pre-execve"). 62 let scratch: *u8 = sys_mmap(1048576) 63 var z: i64 = 0 64 while z < 1048576 { scratch[z] = 0xAA as u8; z = z + 1 } 65 66 // CONTROL: clean env must assemble a writable path cleanly. 67 let clean: *i64 = sys_mmap(8 * 2) as *i64 68 clean[0] = "PATH=/usr/bin:/bin" as *u8 as i64; clean[1] = 0 69 let baseline: i64 = bp_try(asm_tool, spath, validout, clean) 70 71 // poison patterns x (count,slen) combos 72 let pats: *i64 = sys_mmap(8 * 4) as *i64 73 pats[0] = 0xAA; pats[1] = 0xFF; pats[2] = 0x2F; pats[3] = 0x41 74 let cnts: *i64 = sys_mmap(8 * 3) as *i64 75 cnts[0] = 64; cnts[1] = 200; cnts[2] = 8 76 let lens: *i64 = sys_mmap(8 * 3) as *i64 77 lens[0] = 512; lens[1] = 256; lens[2] = 4000 78 79 var configs: i64 = 0 80 var reproduced: i64 = 0 81 var hit_pat: i64 = 0 82 var hit_rc: i64 = 0 83 84 var pi: i64 = 0 85 while pi < 4 { 86 var ci: i64 = 0 87 while ci < 3 { 88 // re-poison the scratch right before the spawn 89 var zz: i64 = 0 90 while zz < 1048576 { scratch[zz] = pats[pi] as u8; zz = zz + 1 } 91 let envp: *i64 = bp_poison_env(pats[pi], cnts[ci], lens[ci]) 92 let rc: i64 = bp_try(asm_tool, spath, validout, envp) 93 configs = configs + 1 94 if rc != 0 { reproduced = 1; hit_pat = pats[pi]; hit_rc = rc } 95 ci = ci + 1 96 } 97 pi = pi + 1 98 } 99 100 bp_puts("BSPOISON baseline_rc=" as *u8); bp_putn(baseline) 101 bp_puts(" configs=" as *u8); bp_putn(configs) 102 bp_puts(" reproduced=" as *u8); bp_putn(reproduced) 103 bp_puts(" hit_pat=" as *u8); bp_putn(hit_pat) 104 bp_puts(" hit_rc=" as *u8); bp_putn(hit_rc) 105 106 // probe is VALID (sound experiment) iff the clean control assembled (rc=0) and configs were swept. 107 var valid: i64 = 0 108 if baseline == 0 { if configs > 0 { valid = 1 } } 109 if valid == 1 { bp_puts(" verdict=GREEN\n" as *u8); return 0 } 110 bp_puts(" verdict=RED\n" as *u8) 111 return 1 112}