test(fspy): regression test for SIGBUS on constrained /dev/shm#354
Draft
branchseer wants to merge 5 commits intomainfrom
Draft
test(fspy): regression test for SIGBUS on constrained /dev/shm#354branchseer wants to merge 5 commits intomainfrom
branchseer wants to merge 5 commits intomainfrom
Conversation
Adds `channel_survives_constrained_dev_shm`, a regression test that reliably reproduces the SIGBUS reported in voidzero-dev/vite-plus#1453 on the shm_open-backed channel implementation. The test runs in a subprocess that enters an unprivileged user+mount namespace and remounts /dev/shm as a 1 MiB tmpfs, then writes past the cap through the real `channel()` API. Today the subprocess dies from SIGBUS when tmpfs can't back the next page; a backing store that escapes /dev/shm (e.g. memfd_create) will make the test pass without modification. No sudo is required; the test self-skips (exit 77) on hosts where unprivileged user namespaces are unavailable.
Replace raw libc calls (unshare, mount, getuid/getgid, SIGBUS) with nix's safe wrappers. Drops all unsafe blocks and the c-string literal juggling from enter_userns_with_small_dev_shm.
Replace the 1024-iteration loop with a single 4 MiB `claim_frame` and `fill()`. The fill walks across the 1 MiB tmpfs boundary on its own and trips SIGBUS just as reliably.
Drop the exit-77 skip path around `enter_userns_with_small_dev_shm` and `.expect()` each step. Environment problems (userns disabled, missing procfs knobs, etc.) now fail the test loudly with a clear panic message pointing at the offending step, rather than silently turning green.
Restore the ENOENT match around the setgroups write that the previous commit dropped along with the userns-skip path. The two cases are different: a missing /proc/self/setgroups means setgroups(2) is already permanently denied in an ancestor user namespace, so the gid_map precondition documented in user_namespaces(7) is already satisfied — not a sign that the environment can't run the test. Everything else keeps `.expect()`, so a genuinely unsupported environment (unshare denied, other procfs writes failing) still panics loudly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a regression test for issue #353, which reproduces a
SIGBUScrash that occurs when the IPC channel's POSIX shared memory backing store exceeds the/dev/shmsize limit (common in containerized environments like Docker with 64 MiB defaults).Key Changes
channel_survives_constrained_dev_shm(): Creates an unprivileged user and mount namespace in a subprocess, remounts/dev/shmas a 1 MiB tmpfs, and attempts to write 16 MiB through the channel API. The test verifies the subprocess completes cleanly rather than crashing withSIGBUS.write_procfs(): Writes to procfs files without theO_CREATflag, which is required on some hosts where synthetic inodes reject the create bit.enter_userns_with_small_dev_shm(): Sets up the constrained environment by:/dev/shmas a 1 MiB tmpfs with size enforcementnixcrate withmount,sched, anduserfeatures for namespace and mount operations.Implementation Details
The test reproduces the issue without requiring
sudoor modifying the test environment's actual/dev/shm. The 16 MiB allocation exceeds the 1 MiB tmpfs cap, causing page faults on writes to un-backed pages. This test is designed to pass once the backing store is switched fromshm_opentomemfd_create, which sizes against RAM + overcommit rather than/dev/shm.The test is Linux-specific and ignored under Miri (which cannot perform mmap or unshare operations).
https://claude.ai/code/session_01CjeJ3LgNb7uxeN2E1VMpY8