Skip to content

fix(sandbox): the four calls a compiler tree makes and a module does not - #4

Merged
CesarManzoCode merged 1 commit into
mainfrom
claude/context-tests-seccomp-fixes-uvq9tg
Aug 30, 2026
Merged

fix(sandbox): the four calls a compiler tree makes and a module does not#4
CesarManzoCode merged 1 commit into
mainfrom
claude/context-tests-seccomp-fixes-uvq9tg

Conversation

@CesarManzoCode

Copy link
Copy Markdown
Owner

dev/verify.sh finally ran stages 58 and 59 under a kernel that denies rather than watches, and both died: cargo exited 159, and `initialize`: the server stopped. Neither sentence names a syscall, because SECCOMP_RET_KILL_PROCESS tells the program nothing — it tells the kernel's audit log, and that is where these came from:

comm="cargo"     syscall=73   flock
comm="rustc"     syscall=265  linkat
comm="cargo"     syscall=219  restart_syscall
comm="VfsLoader" syscall=294  inotify_init1

Reproduced here by installing the real filter and running a real cargo check and a real rust-analyzer over LSP: every one of the four was found by running the thing, and not one is visible in the source of anything Thalyx wrote. dev/foreign-agent-needs.sh named the first two on its own; dmesg named the rest.

  • restart_syscall goes to module_standard, because the kernel issues it: a signal that interrupts a blocking call rewrites the register and re-enters, and the filter sees the re-entry. Without it any module inside futex or poll when a signal lands is killed at a moment nothing in the module chose. It permits nothing new — the only call it can resume is one this filter already let through.
  • flock, linkat and the three inotify calls go to a filter of the provider's own, built from the module's rather than written out beside it. Cargo locks its package cache, rustc hard-links its output into place, and rust-analyzer's VfsLoader thread opens an inotify descriptor the moment the server answers initialize — a thread, so KILL_PROCESS took the whole server down.
  • socketpair is guarded to AF_UNIX rather than allowed: Rust's std::process hands a child's execve errno back over one of these, and a compiler tree is nothing but spawned children. socket stays denied on both filters, which is the decree the guard exists to keep, and a_socket_pair_is_not_a_socket is the test that keeps it.

The rust check's Cargo now runs under semantic_provider too. It was running under the module profile, which is what killed it — and a whole cargo check does not fit in a module's gigabyte or its 512 processes either. A check that names somebody else's program still gets the module profile; widening that to suit Cargo would hand every named program a compiler tree's filter for nothing.

Also: the five contexto tests had their own $HOME/.rustup search, which is the exact failure toolchain.rs exists to end. Under sudo, HOME is /root, so all five reported NOT PROVEN about a machine whose analyzer verify.sh had just found and named in THALYX_RUST_ANALYZER. They ask thalyx_rust::analyzer::find() now, like every other caller.

Still denied, and named here so it is not rediscovered as a bug: rust-analyzer's cargo metadata over the sysroot calls socket(AF_INET6) and is killed. It is a child, not the server — the server survives and finishes loading — so it costs standard-library metadata and nothing else. Allowing socket to buy it back would be the one door Sandbox-Ejecucion.md refuses.

Claude-Session: https://claude.ai/code/session_0186Yyjz7VQsekbhvtFxQs4x

`dev/verify.sh` finally ran stages 58 and 59 under a kernel that denies
rather than watches, and both died: `cargo exited 159`, and
`` `initialize`: the server stopped``. Neither sentence names a syscall,
because `SECCOMP_RET_KILL_PROCESS` tells the program nothing — it tells
the kernel's audit log, and that is where these came from:

    comm="cargo"     syscall=73   flock
    comm="rustc"     syscall=265  linkat
    comm="cargo"     syscall=219  restart_syscall
    comm="VfsLoader" syscall=294  inotify_init1

Reproduced here by installing the real filter and running a real
`cargo check` and a real `rust-analyzer` over LSP: every one of the four
was found by running the thing, and not one is visible in the source of
anything Thalyx wrote. `dev/foreign-agent-needs.sh` named the first two
on its own; `dmesg` named the rest.

- `restart_syscall` goes to `module_standard`, because the *kernel*
  issues it: a signal that interrupts a blocking call rewrites the
  register and re-enters, and the filter sees the re-entry. Without it
  any module inside `futex` or `poll` when a signal lands is killed at a
  moment nothing in the module chose. It permits nothing new — the only
  call it can resume is one this filter already let through.
- `flock`, `linkat` and the three `inotify` calls go to a filter of the
  provider's own, built from the module's rather than written out beside
  it. Cargo locks its package cache, `rustc` hard-links its output into
  place, and rust-analyzer's VfsLoader thread opens an inotify
  descriptor the moment the server answers `initialize` — a thread, so
  `KILL_PROCESS` took the whole server down.
- `socketpair` is **guarded to `AF_UNIX`** rather than allowed: Rust's
  `std::process` hands a child's `execve` errno back over one of these,
  and a compiler tree is nothing but spawned children. `socket` stays
  denied on both filters, which is the decree the guard exists to keep,
  and `a_socket_pair_is_not_a_socket` is the test that keeps it.

The `rust` check's Cargo now runs under `semantic_provider` too. It was
running under the module profile, which is what killed it — and a whole
`cargo check` does not fit in a module's gigabyte or its 512 processes
either. A check that names somebody else's program still gets the module
profile; widening that to suit Cargo would hand every named program a
compiler tree's filter for nothing.

Also: the five `contexto` tests had their own `$HOME/.rustup` search,
which is the exact failure `toolchain.rs` exists to end. Under `sudo`,
`HOME` is `/root`, so all five reported NOT PROVEN about a machine whose
analyzer `verify.sh` had just found and named in `THALYX_RUST_ANALYZER`.
They ask `thalyx_rust::analyzer::find()` now, like every other caller.

Still denied, and named here so it is not rediscovered as a bug:
rust-analyzer's `cargo metadata` over the *sysroot* calls `socket(AF_INET6)`
and is killed. It is a child, not the server — the server survives and
finishes loading — so it costs standard-library metadata and nothing else.
Allowing `socket` to buy it back would be the one door `Sandbox-Ejecucion.md`
refuses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186Yyjz7VQsekbhvtFxQs4x
@CesarManzoCode
CesarManzoCode merged commit fb75c8b into main Aug 30, 2026
1 check failed
@CesarManzoCode
CesarManzoCode deleted the claude/context-tests-seccomp-fixes-uvq9tg branch September 5, 2026 03:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants