code wiki / (root) / nx_scratch_gate.nx

nx_scratch_gate.nx source

↩ module page · 122 lines · 5581 B

1// nx_scratch_gate.nx -- proves the sovereign scratch arena on the resource it exists to protect. 2// 3// Every tooth is designed so that a BROKEN arena fails it. T1 and T6 are a matched pair: T6 runs 4// the OLD idiom in this same process and REQUIRES it to grow, so if T1 reports "no growth" we know 5// that is the arena working and not the instrument being blind. A gate that cannot see the defect 6// cannot certify the fix. 7// 8// nx_scratch_gate -- 6 teeth, exit 0 = GREEN 9// license_tier: ORIGINAL layer: gate module: nishi-core.gate.scratch 10import "nx_scratch.nx" 11 12const SG_ITERS: i64 = 5000 13 14static SG_T: i64 15static SG_O: i64 16 17func sg_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 18func sg_n(v: i64) -> i64 { 19 if SG_T == 0 { SG_T = sys_mmap(64) as i64; SG_O = sys_mmap(64) as i64 } 20 let t: *u8 = SG_T as *u8 21 let o: *u8 = SG_O as *u8 22 var m: i64=v; var k: i64=0 23 if m==0 { t[0]=48 as u8; k=1 } 24 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 25 var i: i64=0; while i<k { o[i]=t[k-1-i]; i=i+1 } 26 sys_write(1,o,k); return 0 27} 28func sg_statm(buf: *u8) -> i64 { 29 let fd: i64 = sys_openat_rd("/proc/self/statm" as *u8) 30 if fd < 0 { return 0 - 1 } 31 let n: i64 = sys_read(fd, buf, 256) 32 sys_close(fd) 33 if n < 1 { return 0 - 1 } 34 var v: i64 = 0; var i: i64 = 0; var go: i64 = 1 35 while go == 1 { 36 if i >= n { go = 0 } else { 37 let c: i64 = buf[i] as i64 38 if c >= 48 { if c <= 57 { v = v*10 + (c-48); i = i + 1 } else { go = 0 } } else { go = 0 } 39 } 40 } 41 return v 42} 43 44func main(argc: i64, argv: *i64) -> i64 { 45 let sb: *u8 = sys_mmap(256) 46 var red: i64 = 0 47 nxs_init(NXS_CAP_DEFAULT) 48 49 // ---- T1: a full work iteration, repeated, must not grow the process ---- 50 let base: i64 = sg_statm(sb) 51 if base < 0 { sg_p("[RED] /proc/self/statm unreadable -- instrument blind, refusing to certify\n" as *u8); sys_exit(1); return 1 } 52 var i: i64 = 0 53 while i < SG_ITERS { 54 nxs_reset() 55 let a: *u8 = nxs_alloc(128) 56 let b: *u8 = nxs_alloc(4096) 57 let c: *u8 = nxs_alloc(28) 58 a[0] = 65 as u8; b[0] = 66 as u8; c[0] = 67 as u8 59 i = i + 1 60 } 61 let after: i64 = sg_statm(sb) 62 let grow: i64 = after - base 63 sg_p("T1 "); sg_n(SG_ITERS); sg_p(" reset+3-alloc iterations must grow 0 pages: grew=" as *u8); sg_n(grow) 64 if grow == 0 { sg_p(" GREEN\n" as *u8) } else { sg_p(" [RED]\n" as *u8); red = red + 1 } 65 66 // ---- T2: 16-byte alignment on every hand-out ---- 67 nxs_reset() 68 var bad_align: i64 = 0 69 var j: i64 = 0 70 while j < 200 { 71 let p: *u8 = nxs_alloc(j + 1) 72 if (p as i64) % NXS_ALIGN != 0 { bad_align = bad_align + 1 } 73 j = j + 1 74 } 75 sg_p("T2 every alloc 16-byte aligned: misaligned=" as *u8); sg_n(bad_align) 76 if bad_align == 0 { sg_p(" GREEN\n" as *u8) } else { sg_p(" [RED]\n" as *u8); red = red + 1 } 77 78 // ---- T3: distinct live allocations must not overlap ---- 79 nxs_reset() 80 let p1: *u8 = nxs_alloc(64) 81 let p2: *u8 = nxs_alloc(64) 82 p1[0] = 11 as u8 83 p2[0] = 22 as u8 84 sg_p("T3 two live allocs distinct: p1[0]=" as *u8); sg_n(p1[0] as i64) 85 sg_p(" p2[0]=" as *u8); sg_n(p2[0] as i64) 86 if p1[0] == (11 as u8) { if p2[0] == (22 as u8) { if (p2 as i64) >= (p1 as i64) + 64 { sg_p(" GREEN\n" as *u8) } else { sg_p(" [RED] overlap\n" as *u8); red = red + 1 } } else { sg_p(" [RED] clobber\n" as *u8); red = red + 1 } } else { sg_p(" [RED] clobber\n" as *u8); red = red + 1 } 87 88 // ---- T4: reset must actually REUSE, not advance ---- 89 nxs_reset() 90 let r1: *u8 = nxs_alloc(256) 91 nxs_reset() 92 let r2: *u8 = nxs_alloc(256) 93 sg_p("T4 reset reuses the same address: same=" as *u8) 94 if (r1 as i64) == (r2 as i64) { sg_p("1 GREEN\n" as *u8) } else { sg_p("0 [RED] reset did not rewind\n" as *u8); red = red + 1 } 95 96 // ---- T5: NEG-CONTROL. Overflow must FAIL SAFE -- usable memory, counted, never null ---- 97 let ovf_before: i64 = nxs_overflows() 98 let big: *u8 = nxs_alloc(NXS_CAP_DEFAULT * 2) 99 var usable: i64 = 0 100 if (big as i64) != 0 { big[0] = 99 as u8; if big[0] == (99 as u8) { usable = 1 } } 101 let ovf_after: i64 = nxs_overflows() 102 sg_p("T5 NEG-CONTROL oversized request falls back usably: usable=" as *u8); sg_n(usable) 103 sg_p(" overflow_counted=" as *u8); sg_n(ovf_after - ovf_before) 104 if usable == 1 { if ovf_after == ovf_before + 1 { sg_p(" GREEN\n" as *u8) } else { sg_p(" [RED] not counted\n" as *u8); red = red + 1 } } else { sg_p(" [RED] returned unusable memory\n" as *u8); red = red + 1 } 105 106 // ---- T6: NEG-CONTROL. The OLD idiom must still visibly leak on this same instrument ---- 107 let lb: i64 = sg_statm(sb) 108 var k2: i64 = 0 109 while k2 < 2000 { let junk: *u8 = sys_mmap(28); junk[0] = 1 as u8; k2 = k2 + 1 } 110 let la: i64 = sg_statm(sb) 111 let lgrow: i64 = la - lb 112 sg_p("T6 NEG-CONTROL old idiom must still grow >= 2000 pages: grew=" as *u8); sg_n(lgrow) 113 if lgrow >= 2000 { sg_p(" GREEN\n" as *u8) } else { sg_p(" [RED] instrument cannot see the defect it certifies against\n" as *u8); red = red + 1 } 114 115 sg_p("arena hwm_bytes=" as *u8); sg_n(nxs_hwm()) 116 sg_p(" cap_bytes=" as *u8); sg_n(nxs_cap_bytes()) 117 sg_p(" overflows=" as *u8); sg_n(nxs_overflows()); sg_p("\n" as *u8) 118 119 if red == 0 { sg_p("NX-SCRATCH-GATE 6/6 GREEN -- arena is correct, bounded, and fail-safe\n" as *u8); sys_exit(0); return 0 } 120 sg_p("NX-SCRATCH-GATE RED teeth=" as *u8); sg_n(red); sg_p("\n" as *u8) 121 sys_exit(1); return 1 122}