brintos

brintos / linux public Read only

0
0

access(2)/faccessat still fails in-browser on deployed linux-6.12-musl — #3 fix not live on served platform (honest Tcl witness) #4

Closed vlad opened this issue · 2 comments
vlad vlad commented

Follow-up to #3. The two-layer fix (kernel 12fce771 + hardwarejs 63a34b9) is verified correct in a locally-booted guest and was reported deployed to the live platform (#3, 2026-07-06 08:50Z close). But the honest access() witness still fails in-browser.

Observed (live platform)

Machine emcraft/linux-6.12-musl-bash-coreutils, Chrome, serial console, after a hard reload. tclsh self-test:

R2-fib15 610
R2-string ABC/5
R2-list 1 2 3 10
R3-utf8 1
R1-encN 4        <- expected 83 (.enc autoload)
R4-exists 0/0    <- expected 1/1

tclsh also still prints Can't find a usable init.tcl at startup. This is byte-identical to the pre-fix behavior.

Why #3's deploy verification did not catch this

#3's step-4 live check used busybox test -e, which — per the maintainer's own note in #3 — is masked: busybox falls back to stat() when access() ENOSYSes, so test -e … -> 0 regardless of whether access() works. Tcl's file exists/file readable call access() directly and are the honest witness; they still read 0/0. So test -e -> T0/N1 does not prove the fix is live; the Tcl result indicates it is not on the path serving this machine.

Hypotheses (either or both)

  1. The rebuilt vmlinux.wasm and/or the worker.mjs bundle carrying the 21/269/439 routing (claimed bundle e1f5d53d7e4604bd) is not what emcraft/linux-6.12-musl-bash-coreutils/launch actually loads.
  2. A stale client-side service worker — a hard reload does not replace an already-registered service worker; not yet excluded via an incognito window.

Requests

  • Re-verify on the live platform with the honest witness, not test -e: the accesstest.c probe (distros/.../tools/access-probe/) or the Tcl self-test above — R4-exists must read 1/1 and R1-encN must exceed 4.
  • Confirm the worker bundle actually served by emcraft/linux-6.12-musl-bash-coreutils/launch carries the 21/269/439 routing.

Original: brintos.io/brintos/linux/issues/3

vlad vlad commented

Incognito confirms this is platform-side, not client cache. Re-ran the Tcl self-test in a fresh Chrome incognito window (no prior service worker registered) on emcraft/linux-6.12-musl-bash-coreutils — identical result: R1-encN 4, R4-exists 0/0, init.tcl-not-found. Hypothesis #2 (stale client service worker) is excluded.

That leaves hypothesis #1: the vmlinux.wasm / worker bundle carrying the 21/269/439 routing (claimed bundle e1f5d53d7e4604bd) is not what this machine's launch path actually serves. Please verify the bundle served by emcraft/linux-6.12-musl-bash-coreutils/launch, and re-check with the honest witness (accesstest.c or the Tcl self-test), not busybox test -e.

jdbrinton jdbrinton commented

(Agent report — Cursor agent working joel's bug queue.)

First: you're right about the masked witness, and I own that. The step-4 "verification" in #3 used test -e, which proves nothing about access(): bash's test -e is sh_stat() (pure stat(2), never touches access), and busybox's is filstat() (stat + in-process permission emulation). That check could not have caught a broken access() under any circumstances. Re-verified tonight with honest witnesses only, at every layer, including live on your machine. Verbatim results below.

1. The served worker bundle carries the routing (hypothesis #1, bundle half)

Fetched what brintos.io actually serves (not the staged copy): /hardwarejs/worker-browser.mjs imports ./worker.mjs?v=e1f5d53d7e4604bd, and the downloaded worker.mjs (278,978 bytes, last-modified 2026-07-06 08:42:57 GMT — tonight's deploy) contains the routing: the __NR_ACCESS = 21 / __NR_FACCESSAT = 269 / __NR_FACCESSAT2 = 439 constants, the brintos/linux#3 routing block, and the AT-family set [257, 262, 267, 269, 439, …].

2. Your machine's kernel already has the fix (hypothesis #1, kernel half — refuted)

I inspected emcraft/linux-6.12-musl-bash-coreutils read-only. /boot/vmlinux.wasm (16,408,750 bytes, Jul 5) banner:

Linux version 6.12.0-wasm32-v0.1-g12fce771e201 (build@5-15-Build) …

That is exactly the access-fix commit (12fce771 = "wasm32: wire access/faccessat/faccessat2") — your own rebuild picked it up, and the w_sys_access wiring symbols are present in the image. (For reference, the brintos-deployed machines run 6.12.0-wasm32-v0.1-00032-geb4d7af27a37, a descendant of the same commit.) So as served right now, both required halves are live on your machine's launch path.

3. Honest live witnesses (serial console, Chrome, tonight)

On your machine (emcraft/linux-6.12-musl-bash-coreutils/launch):

EMCRAFT:/# echo 'puts R4-[file exists /usr/lib/tcl8.6/init.tcl]/[file readable /usr/lib/tcl8.6/init.tcl]; puts R1-encN-[llength [encoding names]]' | tclsh
…
R4-1/1
R1-encN-4

file exists/file readable — Tcl_FSAccess → access(F_OK/R_OK) — read 1/1 on your machine. access() works there now.

On our machines: bash test -r (which is sh_eaccessfaccessat(AT_FDCWD, …, AT_EACCESS), no stat fallback — verified in bash 5.2's lib/sh/eaccess.c + the build's config.h): test -r /etc/hostnameHONEST-R0, test -r /nopeNOPE-R1 on brintos/linux-6.12-musl-bash-coreutils; and busybox which which (file_is_executable requires !access(name, X_OK), nr 21) → /usr/bin/which, rc 0 on brintos/linux-6.12-musl-busybox.

4. What's actually still broken on your machine — and it isn't access()

Note R1-encN-4 and the init.tcl banner persist even with access() proven working. Look at the directory list in the error you quoted:

/usr/local/lib/tcl8.6 /lib/tcl8.6 /lib/tcl8.6 /library /library /tcl8.6.14/library /tcl8.6.14/library

/usr/lib/tcl8.6 — where your init.tcl actually lives — is not in the list, and /lib doesn't exist in your image at all. Your tclsh is installed at /bin/tclsh and its compiled-in library search never reaches /usr/lib. Every candidate directory legitimately doesn't exist, so file exists on them honestly reads 0 — if your self-test's R4 probes [info library] or the candidate dirs (rather than the absolute /usr/lib/tcl8.6/init.tcl), R4-exists 0/0 is the expected answer on this image even with access() fully working, which is what made it look byte-identical to the pre-fix failure. Live proof it's just the search path:

EMCRAFT:/# echo 'puts R1-encN-[llength [encoding names]]; puts INITTCL-OK' | TCL_LIBRARY=/usr/lib/tcl8.6 tclsh
R1-encN-83
INITTCL-OK

encN jumps 4 → 83 (.enc autoload) and init.tcl loads. Concrete fixes on your side (you have write access; boot the machine, or pause it and use the file manager / a brintos-fs mount):

  • export TCL_LIBRARY=/usr/lib/tcl8.6 in your init/profile, or
  • mkdir -p /lib && ln -s /usr/lib/tcl8.6 /lib/tcl8.6 (/lib/tcl8.6 IS in the compiled search list), or
  • rebuild tclsh with --prefix=/usr so the compiled path matches your install layout.

5. On your 15:21Z run

I can't reproduce a failing access() on your machine now, in any window. One mechanism I can't retroactively exclude: the web deploy ran 08:41–08:43Z, and a launch during that window could pin the previous worker.mjs under the new ?v= key at one CDN edge for up to 24h (s-maxage=86400) — your POP isn't mine. If you ever see it again, the distinguishing probe is the absolute-path Tcl check above: file exists /usr/lib/tcl8.6/init.tcl → 0 means access()/routing is genuinely broken (reopen immediately); → 1 with encN-4 means it's the library search path.

One more honesty note: the accesstest probe exists in the superproject (distros/linux-6.12-musl-busybox/tools/access-probe/) but is not baked into the deployed images yet — the honest witnesses that need no extra binary are the ones above (Tcl file readable, bash test -r, busybox which).

Closing (and #3 with it): both layers verified live with honest witnesses on both your machine and ours, and the residual symptoms are fully explained + fixed live via TCL_LIBRARY. Please reopen if the absolute-path probe ever reads anything but 1/1.

jdbrinton closed this as completed