Repository navigation
linux: keep the mount point manifests where the user id says, first under /var/tmp - #615
Merged
ronleizrowice-ant merged 8 commits intoOct 20, 2026
Conversation
… environment Two processes of one user keep each other's mount points only when each reads what the other writes. Where the manifests went followed XDG_RUNTIME_DIR and TMPDIR, which differ between a login shell and what a service, an IDE or cron starts: such processes did not see each other, the second took the first's mount point for the user's own file, and the first's clean-up removed it from under the second sandbox. The candidates are now /run/user/<uid>/srt-mount-points, where /run/user/<uid> is a real directory of the user's alone, then /tmp/srt-mount-points-<uid>, and only then the two names the environment gives. A process writes to the first it can use. It believes the manifests under the first two, and under the environment's names only when it can use neither of the first two, which is when it writes there, and in the directory it has settled on. What the environment names is kept out of a sandbox's reach only by processes with that environment, so a manifest found there is not taken on trust by a process that has somewhere else to look. Every candidate is still made when missing, bound read-only and pinned by every wrap that restricts writes, whether or not the process writes there: a command that may write /tmp would otherwise make the directory itself and be believed. A clean-up makes one pass per directory under that directory's lock, and a live manifest in any of them keeps a path.
…touches the user's own manifest directories Real bubblewrap runs with two real processes, in a mount namespace where a private directory stands at /tmp and at /run/user: the deny holds in a second sandbox after the first has ended, with different XDG_RUNTIME_DIR and with different TMPDIR; a command that may write /tmp can neither make, write nor move aside the directory under it; a manifest forged under one process's TMPDIR by the sandbox of another gets nothing removed. bunfig.toml preloads stand-ins for the four places before any test file is loaded, and children are handed a module or a program that does the same, so no suite reads, writes or collects where the user's own sandboxes keep their manifests. Several did.
Closed
Comments only: the JavaScript emitted with comments removed is byte-identical for every file, and the test names are unchanged. The same standard as on the branch this one is stacked on, applied to the comments this branch rewrites and adds.
…ifest-directory-from-uid
This was referenced Sep 28, 2026
…ifest-directory-from-uid
… end The manifest directory was taken from XDG_RUNTIME_DIR or TMPDIR, so two processes of one user with different environments did not see each other, and a logout, which empties /run/user/<uid>, left a killed process's mount points in the project for good. A process now writes in the first usable of /var/tmp/srt-mount-points-<uid>, /run/user/<uid>/srt-mount-points and /tmp/srt-mount-points-<uid>, and reads all three; what the environment names counts only when none of them can be written. Every place is made, bound read-only and pinned by every wrap, so that the sandboxed command cannot bring one into being. Not the home directory: a network home caches listings, which the claim by rename relies on. Ends. A manifest carries the boot id: of another boot, it is finished. Of another PID namespace, it is live for seven days. What can be a manifest of no version (zero bytes, not JSON) is spent after the grace. The boot id counts only on kinds of file system that one kernel owns, by an allowlist; elsewhere a manifest is this kernel's only when both boot ids can be read and are equal, since two hosts' PID namespaces can be named alike, and any other is live for the seven days. The permission bits of /run/user/<uid> count for writing under it, not for reading: where it is a write root the command can chmod it, and must not make other processes read less by that.
ronleizrowice-ant
merged commit Oct 20, 2026
db4ac8c
into
fix/linux-placeholder-liveness-lock
8 checks passed
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.
Stacked on #584 (retarget to
mainonce merged). Ships with the first release that writes manifests: none may write elsewhere.Why
XDG_RUNTIME_DIRandTMPDIR. Processes with different environments did not read each other's: 27 of 40 denied writes landed./run/user/<uid>goes at the last logout: a dropped SSH connection left 12 mount points for good.What changes
/var/tmp/srt-mount-points-<uid>;/run/user/<uid>/srt-mount-points, where/run/user/<uid>is the user's (alone, to be written under: achmodfrom inside makes nobody read less);/tmp/srt-mount-points-<uid>; then the environment's two names. Checks unchanged.docker restart). What is no JSON at a manifest's name (a crash) counts half a second, not an hour.Seen
Same runs: 0 of 40 writes; nothing left after the logout. #584's end-to-end runs: unchanged.
Known limits (README)
A missing parent that the command may make; links inside a write root; another user taking a name; processes that share a project and none of the three places; over seven days in another PID namespace.
Tests
No suite reaches the real places (one did on #584): a seam, wrapper modules for child processes, a private mount namespace for three runs at the real names. 63 mutations each fail a test, on both runtimes.