brintos

brintos / linux public Read only

0
0

wasm32: kernel `current->blocked` never reflects the user-side signal mask (host-routed rt_sigprocmask) — signal-gated kernel paths judge stale-empty masks #9

Open jdbrinton opened this issue · 1 comment
jdbrinton jdbrinton commented

[filed by the maintainer's AI agent, split out of #7's fix round, 2026-07-15]

Divergence

On the wasm32 port, rt_sigprocmask is host-routed in hardwarejs (worker.mjs, K8 model — the mask lives in the per-Worker user region) and never reaches the kernel, so current->blocked is permanently stale-empty. Any kernel path that judges the blocked mask sees the wrong answer.

Witnessed consequence (the #7 fix round)

bash's give_terminal_to blocks SIGTTOU/SIGTTIN/SIGTSTP/SIGCHLD (user-side) then calls tcsetpgrp from a not-yet-foreground pgrp. __tty_check_change (drivers/tty/tty_jobctrl.c) consults current->blocked, sees SIGTTOU unblocked (stale) and not ignored → kill_pgrp(SIGTTOU) + latched TIF_SIGPENDING + -ERESTARTSYS, where real Linux would have proceeded silently (blocked SIGTTOU ⇒ tcsetpgrp allowed). glibc d1abbc1387 makes this survivable (the resched loop now decodes −512/−513/−514 → reconcile + park + re-issue, −516 → −EINTR, musl parity — restart-until-parent-hands-over converges), but the kernel still takes the wrong branch first: a spurious SIGTTOU is generated and consumed, and the syscall pays park/retry laps it shouldn't need.

Other paths that judge blocked

complete_signal/wants_signal (delivery targeting), sigtimedwait/sigsuspend semantics if ever wired, SIGTTIN/SIGTTOU/SIGTSTP tty checks, ptrace/job-control stop decisions. Today's userspace mostly survives via the −512-class restart protocol, but every one of these is quietly mis-judging.

Fix shape (needs its own validation pass — deliberately NOT bundled with #7)

Mirror nr-14 into the kernel: keep host-side routing as the source of truth for the user-visible mask, but forward mask updates (SIG_BLOCK/UNBLOCK/SETMASK deltas) to current->blocked so kernel judgments match. Risk surface: changing complete_signal/wants_signal behavior alters delivery targeting for multi-thread processes and the park/wake protocol's pending-signal reconciliation (__wasm32_signal_park_reconcile) — needs the dualcon/jobcontrol gate suite at cpu=1 and cpu=2 plus the #85-class pthread workloads before it lands.

Refs: #7 (fixed round, 2026-07-15), glibc d1abbc1387, hardwarejs 7612eb4.

D dmitry commented

Concrete userspace impact that looks like a manifestation of this (stale kernel view of the signal mask) — surfaced picking up procps into core-image-brintos-emcraft (Emcraft, BRINTOS-112).

/proc reads intermittently return EINTR and are not restarted. Reproduced with plain busybox cat (no procps, no installed handlers), same file back-to-back:

a2$ cat /proc/sys/kernel/ostype
Linux
a2$ cat /proc/sys/kernel/ostype
cat: /proc/sys/kernel/ostype: Interrupted system call

One read succeeds, the next returns EINTR — exactly the shape expected if the kernel thinks nothing is blocked: a signal that should be masked is delivered mid-read and the read returns EINTR instead of restarting.

Impact on procps 4.0.4 (wasm32-hwjs glibc): tools that poll many /proc files per run hang or fail — top, vmstat, pgrep, sysctl, and intermittently ps -e (full scan). Tools that read only one or two /proc files work reliably — free, uptime, pkill --version, ps -p <pid>. The correlation with per-invocation /proc-read count matches an intermittent per-read EINTR probability.

Two related observations from the same runtime:

  • A hung tool does not clear via timeout 5 <tool> / SIGTERM within the window — signal delivery to a busy task looks unreliable too (possibly the same root cause).
  • /proc/diskstats is absent (ENOENT) — vmstat's disk source; probably a separate missing-node gap, noted for completeness.

Candidate direction: restart interrupted /proc reads (SA_RESTART semantics), or — per this issue — fix the kernel's view of current->blocked so the masked scheduling/timer signal isn't delivered mid-syscall. Happy to split the procps-visible EINTR into its own issue if you'd rather track it separately.

(Reported from Emcraft BRINTOS-112. No distro submodule pins moved.)