Conversation
|
One improvement worth carrying over from #4061: preserve the original In Please also add |
The seccomp notification probes install their listener on a launcher thread and receive it over a channel. When the install fails, the launcher drops the sender and exits, so the broker only sees a closed channel and returns a generic "launcher disappeared" error. The thread is never joined, so the kernel's errno is discarded. That collapses several distinct failures into one opaque string: a notification struct size mismatch, a failed PR_SET_NO_NEW_PRIVS, and any non-EINVAL SECCOMP_SET_MODE_FILTER rejection all look identical to a pre-5.19 kernel refusing WAIT_KILLABLE_RECV, which the install path already retries without the flag. Join the launcher on the recv() failure path and propagate its error unchanged, so both the ErrorKind and raw_os_error survive to the qualification report. Apply this to all three probes. Signed-off-by: Russell Bryant <rbryant@redhat.com>
82f3522 to
834922c
Compare
|
Done in 834922c.
match launcher.join() {
Ok(Err(error)) => error,
Ok(Ok(_)) => io::Error::other(format!("{role} launcher exited before sending its listener")),
Err(_) => io::Error::other(format!("{role} launcher panicked")),
}
Added One tradeoff worth naming: the Verified in a Linux container (podman, aarch64,
|
Summary
The seccomp notification probes hide the kernel error that actually caused them to fail. When
install_listenerfails on the launcher thread, the broker only observes a closed channel and reportsnotification launcher disappeared, discarding the errno. This makes several unrelated failures indistinguishable from the pre-5.19WAIT_KILLABLE_RECVrejection fixed in 293fab7, which is why #3842 looks like a regression of that fix. This PR joins the launcher thread and propagates its real error.Related Issue
Refs #3842
This is a diagnostics change that unblocks triage of #3842 (currently
state:triage-needed). Investigation found no regression of 293fab7 — theEINVALfallback, thecancellation || task_memory_writes_disabledlaunch invariant, and thelegacy_read_onlyevidence plumbing are all intact inv0.1.2and onmain. The report cannot be diagnosed further until the probe surfaces the underlying errno. Analysis posted at #3842 (comment).Changes
launcher_failure()incrates/openshell-isolation-interface/src/linux/seccomp_notify.rs, which joins the launcher thread on handover failure and returns its error with the originalErrorKindpreserved, so the errno reaches the qualification report.recv()failure path of all three probes:probe_scalar_round_trip,probe_addfd_send, andprobe_connected_sendto_fast_path.No behavior change for successful qualification. The probes fail in exactly the same cases as before; they now say why.
Testing
Linux verification ran in a
rust:1.95-bookwormcontainer with--security-opt seccomp=unconfined(thelinuxmodule does not build on the macOS host).New test
notification_probe_reports_rejected_listener_install. It spawns a disposable child process, installs a filter that refusesSECCOMP_SET_MODE_FILTERwithEPERMwhile leaving the notification size query working, and asserts the probe surfacesPermissionDeniedwithos error 1. This models a restrictive host, which theEINVALfallback cannot retry — distinct from a pre-5.19 kernel.Watched it fail before the fix with
left: Other, right: PermissionDenied, confirming it catches the swallowed error rather than passing vacuously.cargo test -p openshell-isolation-interface: 29 lib + 25 integration tests pass.cargo clippy -p openshell-isolation-interface --all-targets -- -D warningsandcargo fmt --check: clean.cargo check -p openshell-sandbox -p openshell-sandbox-backend -p openshell-supervisor --all-targets: clean.mise run pre-commit: passes.mise run pre-commitpassesUnit tests added/updated
E2E tests added/updated (if applicable) — not applicable; the change is confined to probe error reporting and is covered by the unit test above
Checklist