code wiki / _hdl_build / _galx_serve_gate_prod.nx

_galx_serve_gate_prod.nx source

↩ module page · 374 lines · 21043 B

1import "nx_gate_gn.nx" 2import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 3// _galx_serve_gate_prod.nx -- NO-FAKE-GREEN gate for the PRODUCTION gallery daemon at FULL CORPUS SCALE. 4// Asserts against the REAL corpus served from knowledge/store/galx-prod- (target ~5722 images), NOT a 256 sample: 5// (1) BIND -- the long-lived production daemon (started detached) is LISTENing on 18090. 6// (2) SCALE -- GET / -> 200 AND browse_count (distinct cell anchors '<a class="cell" href="/img/') 7// is in the THOUSANDS (>= GATE_MIN_BROWSE). Proves the 256 cap is GONE -- the full 8// manifest is read via ss_manifest_cap, not ss_manifest. 9// (3) UPPER-CID -- the sampled CID is read off-band from knowledge/status/galx_sample_cid.txt; it was 10// sampled from an UPPER row (>= 4000) of the sidecar (proof its row >= 4000 is in 11// knowledge/status/galx_sample_row.txt). GET / MUST list it -- proves NO 256-truncation: 12// a CID this deep would be invisible under the old cap. 13// (4) IMG-BYTES -- GET /img/<sampledCID> -> 200 image/png AND the served body is byte-identical (memcmp 14// full) to the on-disk source PNG (path read off-band from galx_sample_path.txt). 15// (5) RATE -- snapshot eval_lanes.log linecount; POST /rate (same-origin) score=861 -> EXACTLY one 16// new line == "EVAL img=<sampledCID> lane=O score=861". 17// (6) SAME-ORIG -- POST /rate with a FOREIGN Origin -> 403 AND linecount UNCHANGED (no write). 18// (7) TAMPER-RED -- re-author the daemon spec with tamper=1 (the /img route literal flipped), rewrite its 19// bind port to 18091, recompile (sovereign cc + gcc-as-assembler), spawn it; GET / 20// still 200 (alive) but GET /img/<CID> MUST 404 -- the route is SYNTHESIZED from the 21// spec, not baked. If a spec tamper does NOT change behavior, this arm goes RED. 22// Reads the running prod daemon (does NOT take it down -- persistence is the deliverable). The tamper 23// daemon is a SEPARATE throwaway on 18091. 24// Sovereign (nx_cc/sovereign cc; gcc off-band assembler). license_tier: ORIGINAL 25import "nx_syscalls.nx" 26 27func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 28func gfp(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 29func gfn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m; sys_write(fd,"-" as *u8,1)}; 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(fd,bb,k); return 0 } 30 31func g_run(prog: *u8, a1: *u8, a2: *u8, a3: *u8) -> i64 { 32 let pid: i64 = sys_fork() 33 if pid == 0 { 34 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 35 if dn >= 0 { sys_dup3(dn, 1, 0) } 36 if dn >= 0 { sys_dup3(dn, 2, 0) } 37 let argv: *i64 = sys_mmap(64) as *i64 38 argv[0] = prog as i64 39 var k: i64 = 1 40 if a1 != (0 as *u8) { argv[k] = a1 as i64; k = k + 1 } 41 if a2 != (0 as *u8) { argv[k] = a2 as i64; k = k + 1 } 42 if a3 != (0 as *u8) { argv[k] = a3 as i64; k = k + 1 } 43 argv[k] = 0 44 let envp: *i64 = sys_mmap(16) as *i64 45 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 46 sys_execve(prog, argv, envp) 47 sys_exit(127) 48 } 49 let st: *i64 = sys_mmap(16) as *i64 50 sys_wait4(pid, st, 0) 51 return (st[0] >> 8) & 0xff 52} 53 54func g_spawn(prog: *u8) -> i64 { 55 let pid: i64 = sys_fork() 56 if pid == 0 { 57 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 58 if dn >= 0 { sys_dup3(dn, 1, 0) } 59 let argv: *i64 = sys_mmap(32) as *i64 60 argv[0] = prog as i64; argv[1] = 0 61 let envp: *i64 = sys_mmap(16) as *i64 62 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 63 sys_execve(prog, argv, envp) 64 sys_exit(127) 65 } 66 return pid 67} 68 69func g_kill(pid: i64, sig: i64) -> i64 { nx_kill(pid, sig); return 0 } 70 71func g_addr(port: i64) -> *u8 { 72 let addr: *u8 = sys_mmap(16) 73 addr[0] = 2 as u8 74 addr[1] = 0 as u8 75 addr[2] = ((port >> 8) & 0xff) as u8 76 addr[3] = (port & 0xff) as u8 77 addr[4] = 127 as u8 78 addr[5] = 0 as u8 79 addr[6] = 0 as u8 80 addr[7] = 1 as u8 81 addr[8] = 0 as u8 82 addr[9] = 0 as u8 83 addr[10] = 0 as u8 84 addr[11] = 0 as u8 85 addr[12] = 0 as u8 86 addr[13] = 0 as u8 87 addr[14] = 0 as u8 88 addr[15] = 0 as u8 89 return addr 90} 91 92func g_connect(port: i64) -> i64 { 93 let fd: i64 = sys_socket(2, 1, 0) 94 if fd < 0 { return 0 - 1 } 95 let addr: *u8 = g_addr(port) 96 let rc: i64 = nx_connect_bounded(fd, addr, 16, NX_CONN_DEFAULT_MS) 97 if rc < 0 { sys_close(fd); return 0 - 1 } 98 return fd 99} 100 101func g_wait_listen(port: i64) -> i64 { 102 var tries: i64 = 0 103 while tries < 50 { 104 let fd: i64 = g_connect(port) 105 if fd >= 0 { sys_close(fd); return 1 } 106 sys_sleep_ms(100) 107 tries = tries + 1 108 } 109 return 0 110} 111 112func g_http(port: i64, req: *u8, reqlen: i64, out: *u8, cap: i64) -> i64 { 113 let fd: i64 = g_connect(port) 114 if fd < 0 { return 0 - 1 } 115 sys_write(fd, req, reqlen) 116 var n: i64 = 0 117 var go: i64 = 1 118 while go == 1 { 119 let r: i64 = sys_read(fd, (out as i64 + n) as *u8, cap - 1 - n) 120 if r <= 0 { go = 0 } else { n = n + r } 121 if n >= cap - 1 { go = 0 } 122 } 123 sys_close(fd) 124 return n 125} 126 127func g_find(buf: *u8, n: i64, pat: *u8, plen: i64) -> i64 { 128 var i: i64 = 0 129 while i + plen <= n { 130 var j: i64 = 0 131 var ok: i64 = 1 132 while j < plen { if buf[i+j] != pat[j] { ok = 0 } j = j + 1 } 133 if ok == 1 { return 1 } 134 i = i + 1 135 } 136 return 0 137} 138 139// count non-overlapping occurrences of pat in buf 140func g_count(buf: *u8, n: i64, pat: *u8, plen: i64) -> i64 { 141 var cnt: i64 = 0 142 var i: i64 = 0 143 while i + plen <= n { 144 var j: i64 = 0 145 var ok: i64 = 1 146 while j < plen { if buf[i+j] != pat[j] { ok = 0 } j = j + 1 } 147 if ok == 1 { cnt = cnt + 1; i = i + plen } else { i = i + 1 } 148 } 149 return cnt 150} 151 152func g_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 153 154func g_linecount(path: *u8) -> i64 { 155 let szp: *i64 = sys_mmap(16) as *i64 156 let b: *u8 = sys_read_file(path, szp) 157 let sz: i64 = szp[0] 158 if (b as i64) == 0 { return 0 } 159 var c: i64 = 0 160 var i: i64 = 0 161 while i < sz { if b[i] == (10 as u8) { c = c + 1 } i = i + 1 } 162 return c 163} 164 165// read a one-line oracle file, strip trailing newline, null-terminate into out; return length. 166func g_readline_file(path: *u8, out: *u8, cap: i64) -> i64 { 167 let szp: *i64 = sys_mmap(16) as *i64 168 let b: *u8 = sys_read_file(path, szp) 169 let sz: i64 = szp[0] 170 if (b as i64) == 0 { out[0] = 0 as u8; return 0 } 171 var L: i64 = sz 172 var i: i64 = 0 173 var found: i64 = 0 174 while i < sz { if found == 0 { if b[i] == (10 as u8) { L = i; found = 1 } } i = i + 1 } 175 var n: i64 = 0 176 while n < L { if n < cap - 1 { out[n] = b[n] } n = n + 1 } 177 out[L] = 0 as u8 178 return L 179} 180 181func g_atoi(s: *u8) -> i64 { 182 var v: i64 = 0 183 var i: i64 = 0 184 while s[i] != (0 as u8) { if s[i] >= (48 as u8) { if s[i] <= (57 as u8) { v = v * 10 + ((s[i] as i64) - 48) } } i = i + 1 } 185 return v 186} 187 188func main() -> i64 { 189 let CAP: i64 = 8388608 190 // data-driven minimum browse_count: the gate FAILS if the grid is still the 256 sample. 191 let GATE_MIN_BROWSE: i64 = 4000 192 let GATE_MIN_ROW: i64 = 4000 193 gp("=== gallery-serve PRODUCTION gate @ FULL CORPUS (live daemon @ knowledge/store/galx-prod-) ===\n" as *u8) 194 let lfd: i64 = sys_openat_append("knowledge/status/galx_serve.log" as *u8, 0x1a4) 195 196 // off-band oracle: the sampled UPPER-ROW production CID + its on-disk path + its sidecar row. 197 let cidA: *u8 = sys_mmap(128) 198 let cidlen: i64 = g_readline_file("knowledge/status/galx_sample_cid.txt" as *u8, cidA, 128) 199 let pathA: *u8 = sys_mmap(1024) 200 let pathlen: i64 = g_readline_file("knowledge/status/galx_sample_path.txt" as *u8, pathA, 1024) 201 let rowbuf: *u8 = sys_mmap(64) 202 let rowlen: i64 = g_readline_file("knowledge/status/galx_sample_row.txt" as *u8, rowbuf, 64) 203 let samplerow: i64 = g_atoi(rowbuf) 204 if cidlen != 69 { gp("GALXPROD RED: sample CID oracle not 69 bytes (got "); gn(cidlen); gp(")\n" as *u8); sys_exit(1); return 1 } 205 if pathlen < 8 { gp("GALXPROD RED: sample path oracle empty\n" as *u8); sys_exit(1); return 1 } 206 if samplerow < GATE_MIN_ROW { gp("GALXPROD RED: sample row "); gn(samplerow); gp(" < "); gn(GATE_MIN_ROW); gp(" -- not an UPPER-row CID, cannot prove no-256-truncation\n" as *u8); sys_exit(1); return 1 } 207 208 // ---- ARM 1: BIND -- the live production daemon must be LISTENing on 18090 ---- 209 let up: i64 = g_wait_listen(18090) 210 if up != 1 { gp("GALXPROD RED: production daemon not LISTENing on 127.0.0.1:18090\n" as *u8); sys_exit(1); return 1 } 211 gp("GATE ROW bind: GREEN -- live production daemon LISTEN 127.0.0.1:18090\n" as *u8) 212 213 let resp: *u8 = sys_mmap(CAP) 214 215 // ---- ARM 2: SCALE -- GET / 200 and browse_count in the THOUSANDS ---- 216 let getroot: *u8 = "GET / HTTP/1.1\r\nHost: 127.0.0.1:18090\r\nConnection: close\r\n\r\n" as *u8 217 let rn2: i64 = g_http(18090, getroot, g_strlen(getroot), resp, CAP) 218 var ok200: i64 = g_find(resp, rn2, "HTTP/1.1 200" as *u8, 12) 219 if ok200 != 1 { gp("GALXPROD RED: GET / not 200\n" as *u8); sys_exit(1); return 1 } 220 let browse_count: i64 = g_count(resp, rn2, "<a class=\"cell\" href=\"/img/" as *u8, 27) 221 if browse_count < GATE_MIN_BROWSE { gp("GALXPROD RED: browse_count "); gn(browse_count); gp(" < "); gn(GATE_MIN_BROWSE); gp(" -- grid still capped near 256 (ss_manifest_cap NOT in effect)\n" as *u8); sys_exit(1); return 1 } 222 gp("GATE ROW scale: GREEN -- GET / 200 and browse_count = "); gn(browse_count); gp(" (thousands; 256 cap GONE)\n" as *u8) 223 224 // also confirm lazy-load attribute is present (does not fetch all PNGs at once) 225 var haslazy: i64 = g_find(resp, rn2, "<img loading=lazy src=\"/img/" as *u8, 28) 226 if haslazy != 1 { gp("GALXPROD RED: grid img tags missing loading=lazy\n" as *u8); sys_exit(1); return 1 } 227 gp("GATE ROW lazy: GREEN -- grid img tags carry loading=lazy\n" as *u8) 228 229 // ---- ARM 3: BROWSE lists the UPPER-ROW sampled CID (no 256-truncation) ---- 230 var hasA: i64 = g_find(resp, rn2, cidA, 69) 231 if hasA != 1 { gp("GALXPROD RED: GET / grid missing the UPPER-row sampled CID (row "); gn(samplerow); gp(") -- TRUNCATED\n" as *u8); sys_exit(1); return 1 } 232 gp("GATE ROW upper-cid: GREEN -- GET / lists the row-"); gn(samplerow); gp(" CID (proves full manifest read, no 256-truncation)\n" as *u8) 233 234 // ---- ARM 4: IMG byte-identical to on-disk PNG ---- 235 let getimg: *u8 = sys_mmap(512) 236 var gio: i64 = g_strlen("GET /img/") 237 var w: i64 = 0 238 let p1: *u8 = "GET /img/" as *u8 239 while w < gio { getimg[w] = p1[w]; w = w + 1 } 240 var c: i64 = 0 241 while c < 69 { getimg[gio + c] = cidA[c]; c = c + 1 } 242 let p2: *u8 = " HTTP/1.1\r\nHost: 127.0.0.1:18090\r\nConnection: close\r\n\r\n" as *u8 243 var p2l: i64 = g_strlen(p2) 244 var w2: i64 = 0 245 while w2 < p2l { getimg[gio + 69 + w2] = p2[w2]; w2 = w2 + 1 } 246 let imgreqlen: i64 = gio + 69 + p2l 247 let rn3: i64 = g_http(18090, getimg, imgreqlen, resp, CAP) 248 var imgok: i64 = g_find(resp, rn3, "HTTP/1.1 200" as *u8, 12) 249 var imgct: i64 = g_find(resp, rn3, "Content-Type: image/png" as *u8, 23) 250 if imgok != 1 { gp("GALXPROD RED: GET /img/<A> not 200\n" as *u8); sys_exit(1); return 1 } 251 if imgct != 1 { gp("GALXPROD RED: GET /img/<A> missing image/png content-type\n" as *u8); sys_exit(1); return 1 } 252 var bi: i64 = 0 253 var bodyat: i64 = 0 - 1 254 while bi + 4 <= rn3 { 255 var okb: i64 = 1 256 if resp[bi] != (13 as u8) { okb = 0 } 257 if resp[bi+1] != (10 as u8) { okb = 0 } 258 if resp[bi+2] != (13 as u8) { okb = 0 } 259 if resp[bi+3] != (10 as u8) { okb = 0 } 260 if okb == 1 { if bodyat < 0 { bodyat = bi + 4 } } 261 bi = bi + 1 262 } 263 if bodyat < 0 { gp("GALXPROD RED: GET /img/<A> no body delimiter\n" as *u8); sys_exit(1); return 1 } 264 let szp: *i64 = sys_mmap(16) as *i64 265 let disk: *u8 = sys_read_file(pathA, szp) 266 let dlen: i64 = szp[0] 267 let servedlen: i64 = rn3 - bodyat 268 if servedlen != dlen { gp("GALXPROD RED: served PNG length != on-disk ("); gn(servedlen); gp(" vs "); gn(dlen); gp(")\n" as *u8); sys_exit(1); return 1 } 269 var bc: i64 = 0 270 var bmatch: i64 = 1 271 while bc < dlen { if resp[bodyat + bc] != disk[bc] { bmatch = 0 } bc = bc + 1 } 272 if bmatch != 1 { gp("GALXPROD RED: served PNG bytes != on-disk source\n" as *u8); sys_exit(1); return 1 } 273 gp("GATE ROW img-bytes: GREEN -- GET /img/<A> 200 image/png byte-identical to on-disk source ("); gn(dlen); gp(" bytes)\n" as *u8) 274 275 // ---- ARM 5: RATE writes EXACTLY one EVAL O-line ---- 276 let before: i64 = g_linecount("knowledge/status/eval_lanes.log" as *u8) 277 let body4: *u8 = sys_mmap(256) 278 var b4: i64 = 0 279 let bp1: *u8 = "img=" as *u8 280 var t1: i64 = 0; while bp1[t1]!=(0 as u8){body4[b4]=bp1[t1]; b4=b4+1; t1=t1+1} 281 c = 0; while c < 69 { body4[b4] = cidA[c]; b4 = b4 + 1; c = c + 1 } 282 let bp2: *u8 = "&score=861" as *u8 283 var t2: i64 = 0; while bp2[t2]!=(0 as u8){body4[b4]=bp2[t2]; b4=b4+1; t2=t2+1} 284 let post: *u8 = sys_mmap(1024) 285 var po: i64 = 0 286 let hp: *u8 = "POST /rate HTTP/1.1\r\nHost: 127.0.0.1:18090\r\nOrigin: http://127.0.0.1:18090\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: " as *u8 287 var th: i64 = 0; while hp[th]!=(0 as u8){post[po]=hp[th]; po=po+1; th=th+1} 288 let clbuf: *u8 = sys_mmap(28); var clm: i64 = b4; var clk: i64 = 0; if clm==0{clbuf[0]=48;clk=1}; let clt: *u8=sys_mmap(28); while clm>0{clt[clk]=(48+(clm%10)) as u8;clm=clm/10;clk=clk+1}; var cli: i64=0; while cli<clk{post[po]=clt[clk-1-cli];po=po+1;cli=cli+1} 289 let hp2: *u8 = "\r\nConnection: close\r\n\r\n" as *u8 290 var th2: i64 = 0; while hp2[th2]!=(0 as u8){post[po]=hp2[th2]; po=po+1; th2=th2+1} 291 var bb4: i64 = 0; while bb4 < b4 { post[po] = body4[bb4]; po = po + 1; bb4 = bb4 + 1 } 292 let rn4: i64 = g_http(18090, post, po, resp, CAP) 293 var rateok: i64 = g_find(resp, rn4, "HTTP/1.1 200" as *u8, 12) 294 if rateok != 1 { gp("GALXPROD RED: POST /rate (same-origin) not 200\n" as *u8); sys_exit(1); return 1 } 295 let after: i64 = g_linecount("knowledge/status/eval_lanes.log" as *u8) 296 if after != before + 1 { gp("GALXPROD RED: POST /rate did not append EXACTLY one line ("); gn(before); gp(" -> "); gn(after); gp(")\n" as *u8); sys_exit(1); return 1 } 297 let lszp: *i64 = sys_mmap(16) as *i64 298 let lb: *u8 = sys_read_file("knowledge/status/eval_lanes.log" as *u8, lszp) 299 let lsz: i64 = lszp[0] 300 let exp: *u8 = sys_mmap(256) 301 var eo: i64 = 0 302 let e1: *u8 = "EVAL img=" as *u8 303 var te1: i64=0; while e1[te1]!=(0 as u8){exp[eo]=e1[te1];eo=eo+1;te1=te1+1} 304 c = 0; while c < 69 { exp[eo] = cidA[c]; eo = eo + 1; c = c + 1 } 305 let e2: *u8 = " lane=O score=861\n" as *u8 306 var te2: i64=0; while e2[te2]!=(0 as u8){exp[eo]=e2[te2];eo=eo+1;te2=te2+1} 307 var tailmatch: i64 = 1 308 if lsz < eo { tailmatch = 0 } 309 if tailmatch == 1 { 310 var em: i64 = 0 311 while em < eo { if lb[lsz - eo + em] != exp[em] { tailmatch = 0 } em = em + 1 } 312 } 313 if tailmatch != 1 { gp("GALXPROD RED: appended line != 'EVAL img=<A> lane=O score=861'\n" as *u8); sys_exit(1); return 1 } 314 gp("GATE ROW rate: GREEN -- POST /rate (same-origin) appended EXACTLY one line == 'EVAL img=<A> lane=O score=861'\n" as *u8) 315 316 // ---- ARM 6: SAME-ORIGIN -- foreign Origin -> 403 AND no write ---- 317 let before6: i64 = g_linecount("knowledge/status/eval_lanes.log" as *u8) 318 let post6: *u8 = sys_mmap(1024) 319 var po6: i64 = 0 320 let fp: *u8 = "POST /rate HTTP/1.1\r\nHost: 127.0.0.1:18090\r\nOrigin: http://evil.example.com\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: " as *u8 321 var tf: i64 = 0; while fp[tf]!=(0 as u8){post6[po6]=fp[tf]; po6=po6+1; tf=tf+1} 322 var cli6: i64=0; while cli6<clk{post6[po6]=clt[clk-1-cli6];po6=po6+1;cli6=cli6+1} 323 var tf2: i64 = 0; while hp2[tf2]!=(0 as u8){post6[po6]=hp2[tf2]; po6=po6+1; tf2=tf2+1} 324 var bb6: i64 = 0; while bb6 < b4 { post6[po6] = body4[bb6]; po6 = po6 + 1; bb6 = bb6 + 1 } 325 let rn6: i64 = g_http(18090, post6, po6, resp, CAP) 326 var forbidden: i64 = g_find(resp, rn6, "HTTP/1.1 403" as *u8, 12) 327 let after6: i64 = g_linecount("knowledge/status/eval_lanes.log" as *u8) 328 if forbidden != 1 { gp("GALXPROD RED: cross-origin POST /rate not 403\n" as *u8); sys_exit(1); return 1 } 329 if after6 != before6 { gp("GALXPROD RED: cross-origin POST /rate WROTE to the log ("); gn(before6); gp(" -> "); gn(after6); gp(")\n" as *u8); sys_exit(1); return 1 } 330 gp("GATE ROW same-origin: GREEN -- cross-origin POST /rate -> 403 and eval_lanes.log unchanged (no write)\n" as *u8) 331 332 // ---- ARM 7: TAMPER-RED -- flip the /img route spec field -> GET /img 404 (route synthesized) ---- 333 // Author a tamper variant (tamper=1 flips the rl_img route literal), rewrite its bind port to 18091, 334 // recompile sovereignly, spawn it; GET / on 18091 still 200 (alive) but GET /img/<A> MUST 404. 335 let at: i64 = g_run("/tmp/nx_eg.sov.elf" as *u8, "2" as *u8, "nx_gallery_serve_tamper" as *u8, "1" as *u8) 336 if at != 0 { gp("GALXPROD RED: tamper author failed rc="); gn(at); gp("\n" as *u8); sys_exit(1); return 1 } 337 // rewrite "let port: i64 = 18090" -> 18091 in the throwaway tamper source so it binds a free port 338 let sr: i64 = g_run("/bin/sed" as *u8, "-i" as *u8, "s/let port: i64 = 18090/let port: i64 = 18091/" as *u8, "runtime/_hdl_build/nx_gallery_serve_tamper.nx" as *u8) 339 if sr != 0 { gp("GALXPROD RED: tamper port rewrite failed rc="); gn(sr); gp("\n" as *u8); sys_exit(1); return 1 } 340 let bt: i64 = g_run("runtime/_hdl_build/_galx_build_one.sh" as *u8, "nx_gallery_serve_tamper" as *u8, 0 as *u8, 0 as *u8) 341 if bt != 0 { gp("GALXPROD RED: tamper compile failed rc="); gn(bt); gp("\n" as *u8); sys_exit(1); return 1 } 342 let tpid: i64 = g_spawn("/tmp/nx_gallery_serve_tamper.elf" as *u8) 343 let tup: i64 = g_wait_listen(18091) 344 if tup != 1 { gp("GALXPROD RED: tamper daemon never bound 18091\n" as *u8); nx_kill(tpid, 9); sys_exit(1); return 1 } 345 // tamper daemon is alive: GET / must still be 200 346 let getroot2: *u8 = "GET / HTTP/1.1\r\nHost: 127.0.0.1:18091\r\nConnection: close\r\n\r\n" as *u8 347 let rnT0: i64 = g_http(18091, getroot2, g_strlen(getroot2), resp, CAP) 348 var tamperalive: i64 = g_find(resp, rnT0, "HTTP/1.1 200" as *u8, 12) 349 if tamperalive != 1 { gp("GALXPROD RED: tamper daemon GET / not 200 (cannot isolate the route flip)\n" as *u8); nx_kill(tpid, 9); sys_exit(1); return 1 } 350 // GET /img/<A> on the tamper daemon MUST 404 -- the route was synthesized from the (flipped) spec 351 let getimgT: *u8 = sys_mmap(512) 352 var gioT: i64 = g_strlen("GET /img/") 353 var wT: i64 = 0 354 let p1T: *u8 = "GET /img/" as *u8 355 while wT < gioT { getimgT[wT] = p1T[wT]; wT = wT + 1 } 356 var cT: i64 = 0 357 while cT < 69 { getimgT[gioT + cT] = cidA[cT]; cT = cT + 1 } 358 let p2T: *u8 = " HTTP/1.1\r\nHost: 127.0.0.1:18091\r\nConnection: close\r\n\r\n" as *u8 359 var p2lT: i64 = g_strlen(p2T) 360 var w2T: i64 = 0 361 while w2T < p2lT { getimgT[gioT + 69 + w2T] = p2T[w2T]; w2T = w2T + 1 } 362 let rnT: i64 = g_http(18091, getimgT, gioT + 69 + p2lT, resp, CAP) 363 var tamper404: i64 = g_find(resp, rnT, "HTTP/1.1 404" as *u8, 12) 364 var tamper200: i64 = g_find(resp, rnT, "HTTP/1.1 200" as *u8, 12) 365 nx_kill(tpid, 9) 366 if tamper200 == 1 { gp("GALXPROD RED: TAMPER -- GET /img/<A> still 200 after /img route flip (route is BAKED, not synthesized)\n" as *u8); sys_exit(1); return 1 } 367 if tamper404 != 1 { gp("GALXPROD RED: TAMPER -- GET /img/<A> not 404 after /img route flip\n" as *u8); sys_exit(1); return 1 } 368 gp("GATE ROW tamper-red: GREEN -- flipping the /img route spec field -> GET /img/<A> now 404 (route synthesized from spec, not baked)\n" as *u8) 369 370 gp("GALXPROD 7/7 GREEN -- FULL-corpus production daemon: binds 18090, browse_count="); gn(browse_count); gp(" (thousands), lists row-"); gn(samplerow); gp(" CID, /img byte-identical PNG, /rate one O-line (same-origin enforced, cross-origin 403 no-write), tamper-of-/img-route -> behavioral RED\n" as *u8) 371 if lfd >= 0 { gfp(lfd, "GALXPROD verdict=GREEN scale=FULL daemon=nx_gallery_serve namespace=knowledge/store/galx-prod- port=18090 browse_count=" as *u8); gfn(lfd, browse_count); gfp(lfd, " sample_row=" as *u8); gfn(lfd, samplerow); gfp(lfd, " img_byte_identical=1 rate_one_oline=1 same_origin_enforced=1 tamper_red=1 epoch=" as *u8); gfn(lfd, sys_now_realtime_sec()); gfp(lfd, "\n" as *u8); sys_close(lfd) } 372 sys_exit(0) 373 return 0 374}