Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
8f4c066
fix: mandatory denies cover nested hooks at repo depth, submodule git…
ronleizrowice-ant Sep 2, 2026
b51fe2a
Merge main into fix/linux-nested-repo-hooks-depth
ronleizrowice-ant Sep 10, 2026
1dbfe26
fix: bound the .git pointer create allow to the write roots; scan rel…
ronleizrowice-ant Sep 10, 2026
e6ea51c
fix(sandbox): close the git-metadata gaps in the mandatory denies
ronleizrowice-ant Sep 10, 2026
af1e241
test: cover the git-metadata deny paths and the NUL-delimited scan
ronleizrowice-ant Sep 10, 2026
af8a067
docs(readme): what the git denies cover and which git operations break
ronleizrowice-ant Sep 10, 2026
c36ee8b
fix(sandbox): read a .git pointer and commondir the way git reads them
ronleizrowice-ant Sep 11, 2026
ea00b2e
test: check the pointer and commondir parse against real git
ronleizrowice-ant Sep 11, 2026
0824c94
docs(readme): how a .git pointer is read, and when a wrap is refused
ronleizrowice-ant Sep 11, 2026
7f33786
test: build the invalid-UTF-8 parity case only where a name can hold it
ronleizrowice-ant Sep 11, 2026
7d43e9c
fix(sandbox): resolve a pointer's .. the way the kernel does, not on …
ronleizrowice-ant Sep 11, 2026
d258cc5
fix(sandbox): deny the directory the .git/modules walk stops at
ronleizrowice-ant Sep 12, 2026
2db36ad
fix(sandbox): deny the modules beneath a bound git directory, not the…
ronleizrowice-ant Sep 12, 2026
8fad968
docs: the three whole-directory denies under .git/modules, and what o…
ronleizrowice-ant Sep 12, 2026
14de67f
Merge remote-tracking branch 'origin/main' into srt515-work
ronleizrowice-ant Sep 16, 2026
d843dec
test: the git directories read off disk compile to literal filters
ronleizrowice-ant Sep 16, 2026
5b8fe26
Merge remote-tracking branch 'origin/main' into srt515-work
ronleizrowice-ant Sep 17, 2026
951f08a
test: take the namespace probe from the shared helper
ronleizrowice-ant Sep 17, 2026
466e011
linux: deny a git directory's commondir without breaking git
ronleizrowice-ant Sep 17, 2026
2b9de7c
Merge remote-tracking branch 'origin/main' into fix/linux-nested-repo…
ronleizrowice-ant Sep 17, 2026
cc7ec6b
Merge remote-tracking branch 'origin/main' into fix/linux-nested-repo…
ronleizrowice-ant Sep 17, 2026
a7f016b
Merge remote-tracking branch 'origin/main' into fix/linux-nested-repo…
ronleizrowice-ant Sep 17, 2026
1b191c5
linux: take the git redirect placeholders off one table, and decide f…
ronleizrowice-ant Sep 17, 2026
15e482f
linux: keep the host's git working while a deny stands in for a redir…
ronleizrowice-ant Sep 17, 2026
e275b42
violations: do not fail the monitor's start-up over one repository
ronleizrowice-ant Sep 17, 2026
41aa1f9
linux: refuse the wrap when the mandatory-deny scan cannot deliver it…
ronleizrowice-ant Sep 18, 2026
5adab23
Cover the mandatory-deny scan's failure paths, whatever the uid
ronleizrowice-ant Sep 18, 2026
dc45013
linux: read a failed scan's error codes, and find the unreadable dire…
ronleizrowice-ant Sep 18, 2026
a407e9e
Refuse with a typed error where git's metadata cannot be followed, an…
ronleizrowice-ant Sep 18, 2026
7c06b58
linux: the files a git redirect deny leaves on the host
ronleizrowice-ant Sep 18, 2026
e50e5d8
Cover all of it, and say so
ronleizrowice-ant Sep 18, 2026
9748510
The submodule walk has no depth bound, and spends the scan's own time
ronleizrowice-ant Sep 18, 2026
09461f7
Collapse the submodule denies rather than refuse a repository that has
ronleizrowice-ant Sep 18, 2026
a024b94
Tests: size the two walk cases to the platform rather than to the clock
ronleizrowice-ant Sep 18, 2026
b44e67d
Degrade the submodule denies by what the profile costs, not by a mode…
ronleizrowice-ant Sep 19, 2026
73deb06
Tests: the degraded levels, what the walk answers, and the two deadlines
ronleizrowice-ant Sep 19, 2026
88ec43a
README: what a degrade gives up, and what it takes to reach the cap
ronleizrowice-ant Sep 19, 2026
cb1c2c7
Tests: give the two macOS arms back what this round took from them
ronleizrowice-ant Sep 19, 2026
307fa80
Deny both halves of a git directory entry that is a symlink
ronleizrowice-ant Sep 19, 2026
710cbae
Tests: the link, what it leads to, and what a degrade keeps
ronleizrowice-ant Sep 19, 2026
ae0f0cb
README: what a symlinked git entry is denied by, and what it costs
ronleizrowice-ant Sep 19, 2026
070f061
Keep a repository denied whole for its own entry out of the submodule…
ronleizrowice-ant Sep 19, 2026
a300d6f
Hold the link in a git directory a pointer leads to as well
ronleizrowice-ant Sep 19, 2026
516e012
Hold every hop of a symlinked git directory entry's chain
ronleizrowice-ant Sep 20, 2026
fb4bc9c
Tests: the hops between an entry and what it leads to
ronleizrowice-ant Sep 20, 2026
829fcc5
README: a chain is held hop by hop, and three limits that are not
ronleizrowice-ant Sep 20, 2026
d9e01c8
Hold the links a gitdir: pointer's value walks through
ronleizrowice-ant Sep 20, 2026
6319e2b
Tests: the links between a pointer and the git directory it names
ronleizrowice-ant Sep 20, 2026
d5e0eb2
README: a chain is held hop by hop whichever end names it
ronleizrowice-ant Sep 20, 2026
60d844e
Merge origin/main into fix/linux-nested-repo-hooks-depth
ronleizrowice-ant Sep 20, 2026
14b869f
Reflow the note this round's rename left wrapped short
ronleizrowice-ant Sep 20, 2026
e233a89
Deny where a git deny path lands, not only how it is spelled
ronleizrowice-ant Sep 20, 2026
e362065
Tests: the git directory a macOS deny reaches only through a link
ronleizrowice-ant Sep 20, 2026
176da8d
README: a filter and a bind hold a path through a link by different ends
ronleizrowice-ant Sep 20, 2026
cbe6558
A chain hop keeps its own name and only its own name
ronleizrowice-ant Sep 20, 2026
66553d1
Merge origin/main into fix/linux-nested-repo-hooks-depth
ronleizrowice-ant Sep 20, 2026
b3b2bb5
README: a hop keeps its own name alone
ronleizrowice-ant Sep 20, 2026
b6c79e0
Record which mount points a running sandbox relies on, and let the ke…
ronleizrowice-ant Sep 20, 2026
ec16c45
Remove a mount point only when no running sandbox relies on it
ronleizrowice-ant Sep 20, 2026
935350d
Cover what keeps a mount point, across processes and cleanups
ronleizrowice-ant Sep 20, 2026
957d150
Say in the README when a host mount point goes
ronleizrowice-ant Sep 20, 2026
70c9868
A git chain that reaches nothing is held by the links it went through
ronleizrowice-ant Sep 21, 2026
52e894d
Hold a `modules` directory that is a symlink
ronleizrowice-ant Sep 21, 2026
b6186b2
No deny may take the work tree, and no killed scan may pass for a who…
ronleizrowice-ant Sep 21, 2026
3fe8334
Tests: chains that reach nothing, denies aimed at the project, and th…
ronleizrowice-ant Sep 21, 2026
38190cd
README: what a deny may not take, and what a killed scan is worth
ronleizrowice-ant Sep 21, 2026
4750e50
README: the rest of what this round changed
ronleizrowice-ant Sep 21, 2026
bbb87cb
linux: count wraps before releasing mount points, and harden the mani…
ronleizrowice-ant Sep 21, 2026
2805ea8
test: cover the manifest collector, the wrap count and the directory …
ronleizrowice-ant Sep 21, 2026
3f14b21
docs: describe when mount points are released, and commandId
ronleizrowice-ant Sep 21, 2026
ed98405
linux: mount nothing else inside a git directory that is bound whole
ronleizrowice-ant Sep 21, 2026
ad5b7c3
linux: repair a placeholder through the file that was checked, not it…
ronleizrowice-ant Sep 21, 2026
115109a
The .git/modules walk goes on past a directory that looks like a git …
ronleizrowice-ant Sep 21, 2026
d62d3f1
linux: bound the profile rebuild loop and the walk of a symlink chain
ronleizrowice-ant Sep 21, 2026
fcbb885
Deny a linked worktree's git directory from the repository that keeps it
ronleizrowice-ant Sep 21, 2026
fe8d039
linux: keep a deny off the work tree by where it lands, and refuse less
ronleizrowice-ant Sep 21, 2026
a7caee2
README: what the latest round changed, and six claims corrected
ronleizrowice-ant Sep 21, 2026
6b5adca
test: fit the long-chain fixture into a macOS link target
ronleizrowice-ant Sep 21, 2026
f614f84
Deny a submodule's linked worktrees too, and walk an entry link once
ronleizrowice-ant Sep 21, 2026
62efa8d
README: a submodule's linked worktrees, and what git worktree prune does
ronleizrowice-ant Sep 21, 2026
a928ebe
linux: only a manifest makes a path a mount point, and the library's …
ronleizrowice-ant Sep 27, 2026
8136d90
test: mount points known by their manifest, pinned library directorie…
ronleizrowice-ant Sep 27, 2026
61d3c5f
README: what makes a path a mount point, liveMountPoints(), and what …
ronleizrowice-ant Sep 27, 2026
632eb20
linux: the manifest directory is worked out from the user id, not the…
ronleizrowice-ant Sep 27, 2026
4c904f4
test: processes with different environments see each other; no suite …
ronleizrowice-ant Sep 27, 2026
99e1b2c
README: where the mount point manifests are kept, and whose are believed
ronleizrowice-ant Sep 27, 2026
aa2a2d5
Merge branch 'main' into fix/linux-manifest-directory-from-uid
ronleizrowice-ant Sep 27, 2026
7651646
Shorten the comments around the mount point manifests
ronleizrowice-ant Sep 28, 2026
0795878
Shorten the comments around the manifest directories
ronleizrowice-ant Sep 28, 2026
3553578
Merge branch 'fix/linux-placeholder-liveness-lock' into fix/linux-man…
ronleizrowice-ant Sep 28, 2026
1312f18
linux: a sandbox vouches for its own mount points; no lock file, no d…
ronleizrowice-ant Sep 28, 2026
efc401c
test: liveness by the sandbox's own record, claims, and refused starts
ronleizrowice-ant Sep 28, 2026
6f6be30
linux: list before every removal of an ordinary clean-up, and bind a …
ronleizrowice-ant Sep 28, 2026
0eaf352
linux: a wrap names every directory it relies on, and any empty file …
ronleizrowice-ant Sep 28, 2026
0ec2c8e
test: what a wrap relies on, old bubblewrap's mount points, the per-c…
ronleizrowice-ant Sep 28, 2026
7873452
Merge branch 'main' into fix/linux-placeholder-liveness-lock
ronleizrowice-ant Sep 28, 2026
ab17aad
linux: a plan agrees with itself, a plan given up is released, and no…
ronleizrowice-ant Sep 28, 2026
14d0b4c
test: pin the hour, a manifest's fields, and the record past the grace
ronleizrowice-ant Sep 28, 2026
2c1141e
Merge branch 'fix/linux-placeholder-liveness-lock' into fix/linux-man…
ronleizrowice-ant Sep 29, 2026
2551cec
linux: the manifests live under /var/tmp, by the user id, and have an…
ronleizrowice-ant Sep 29, 2026
6e1756a
Merge branch 'main' into fix/linux-placeholder-liveness-lock
claude Oct 20, 2026
db4ac8c
Merge branch 'fix/linux-manifest-directory-from-uid' into fix/linux-p…
claude Oct 20, 2026
825276b
test: join main's newer suites with the manifests
claude Oct 20, 2026
7f0dc43
linux: a clean-up is on record while it removes, and a command line m…
claude Oct 20, 2026
9268612
test: no awaited `rejects`, and a helper that loads where there is no…
claude Oct 20, 2026
cdfb8a8
linux: a clean-up says which manifests are finished, for those that c…
claude Oct 20, 2026
6e356e3
Merge branch 'fix/linux-placeholder-liveness-lock' into fix/linux-nes…
claude Oct 20, 2026
4884e4e
Merge branch 'fix/linux-placeholder-liveness-lock' into fix/linux-nes…
claude Oct 20, 2026
9f5b108
linux: the record step leaves the caller's variables alone
claude Oct 20, 2026
fa15c63
README: a paragraph the merge of main doubled
claude Oct 20, 2026
90312c6
linux: a manifest directory that has two names is one directory
claude Oct 20, 2026
b6b0b7c
linux: every run on a started record is asked after, not the last two…
claude Oct 20, 2026
db2308a
linux: what a plan makes on a 9p drive is kept track of until a manif…
claude Oct 20, 2026
7f00bf3
linux: a manifest directory that a read deny hides stays hidden
claude Oct 20, 2026
d805bf7
test: four more child processes keep out of the user's own manifest d…
claude Oct 20, 2026
e147a73
linux: no command is handed out while a manifest directory cannot be …
claude Oct 20, 2026
2491361
linux: a clean-up times itself by both clocks, from before its record…
claude Oct 20, 2026
46657e8
test: drop cases that assert nothing or what another asserts, and fol…
claude Oct 20, 2026
cd437df
linux: a flag that was never read as set, an explicit release, named …
claude Oct 20, 2026
c278205
test: the four mount point suites share their fixtures
claude Oct 20, 2026
255a220
linux: the protocol is told once in the source
claude Oct 20, 2026
35d5852
linux: say what the listing before each removal is for
claude Oct 20, 2026
016902b
test: the two zombie cases no longer race the shell that makes the zo…
claude Oct 20, 2026
f2f10a2
linux: a plan reads the manifests before it makes anything on the host
claude Oct 20, 2026
81468f9
linux: what a wrap could record nowhere is kept while another of its …
claude Oct 20, 2026
2753345
linux: a clean-up is waited for by its record's own name, and a place…
claude Oct 20, 2026
2dbbf55
test: three lines that no case held
claude Oct 20, 2026
de39d0d
test: a process that is gone and a record's name come from the fixtur…
claude Oct 20, 2026
3276893
test: the cases on open descriptors leave out the runtime's sockets
claude Oct 20, 2026
fcd46bc
linux: the manifest directories are made before a plan reads them
claude Oct 20, 2026
fdce419
linux: a manifest takes over all that its plan made, and nothing anot…
claude Oct 20, 2026
f203eb6
linux: the manifest directories are made once in a plan
claude Oct 20, 2026
8997f0d
linux: what mount points bind from goes with the last command
claude Oct 20, 2026
fa247d2
test: junk that stays in doubt, and the refusal fixture where it was …
claude Oct 20, 2026
260e0dc
linux: where a manifest goes is settled before the pins again
claude Oct 20, 2026
b936bc7
Revert "linux: what mount points bind from goes with the last command"
claude Oct 20, 2026
273ea90
test: one more case whose junk stays in doubt
claude Oct 20, 2026
5bb12e9
linux: a directory of the process's own does not stay when it cannot …
claude Oct 20, 2026
57a7678
linux: a manifest directory is resolved as the plan makes sure of it
claude Oct 20, 2026
917b89e
linux: ensureManifestDirectory does nothing off Linux, and says what …
claude Oct 20, 2026
7a31540
test: the last case whose junk was in doubt for half a second
claude Oct 20, 2026
5d5faf5
linux: the source goes back to fdce419
claude Oct 20, 2026
db71e7c
test: the case of a link put at a shared name holds in any order
claude Oct 20, 2026
b163513
Merge branch 'fix/linux-placeholder-liveness-lock' into fix/linux-nes…
claude Oct 21, 2026
5cf3747
linux: the mount point of a file git reads back is bound onto itself
claude Oct 21, 2026
1146c21
deny what a kept git directory keeps in turn, from either end
claude Oct 21, 2026
f691c11
the walk of a chain or a pointer's value: no overflow, no lossy link
claude Oct 21, 2026
0a23ab6
small fixes from the review, and a monitor fallback that follows nothing
claude Oct 21, 2026
0630ac1
linux: two slow paths of the collapse that a command could choose the…
claude Oct 21, 2026
a56c5e0
README: the mandatory git denies in about half the words
claude Oct 21, 2026
e43d93d
shorter comments, and two helpers fewer
claude Oct 21, 2026
e992a35
tests: repair the cases the review found wanting, drop what proves no…
claude Oct 21, 2026
2e7e8e7
mend what the last round of fixes broke
claude Oct 21, 2026
48e04eb
walk each git directory from where it is, whatever links lead there
claude Oct 21, 2026
ab26e00
hold each link by its own name, and go by what git needs to open a di…
claude Oct 21, 2026
f3cdda2
take back what the last round broke, and name a whole deny by where i…
claude Oct 21, 2026
cac279c
deny what shuts a git directory off behind the link, not around it
claude Oct 21, 2026
5de9ab5
test: do not resolve a directory that cannot be read
claude Oct 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,11 @@ jobs:
test/sandbox/path-canonicalization.test.ts \
test/sandbox/credential-deny.test.ts \
test/sandbox/symlink-boundary.test.ts \
test/sandbox/stale-mount-point.test.ts
test/sandbox/mount-point-manifests.test.ts \
test/sandbox/mount-point-liveness.test.ts \
test/sandbox/mount-point-passes.test.ts \
test/sandbox/stale-mount-point.test.ts \
test/sandbox/linux-bwrap-args-file.test.ts

- name: Run Node.js fallback tests
if: matrix.os != 'windows'
Expand Down
118 changes: 105 additions & 13 deletions README.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[test]
# Gives the run directories of its own for the mount point manifests, before any
# test file is loaded: see test/preload.ts.
preload = ["./test/preload.ts"]
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export default [
'eslint.config.js',
'test/fixtures/tunnel-ends.mjs',
'test/utils/which-node-test.mjs',
'test/helpers/isolated/dist-cli.mjs',
'vendor/build-common.ts',
'vendor/seccomp/build.ts',
'vendor/srt-win/build.ts',
Expand Down
14 changes: 14 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ export {
LinuxSandboxProfileError,
type LinuxSandboxProfileErrorCode,
} from './sandbox/linux-sandbox-utils.js'
// The macOS profile generator's own wrap-time refusal: a `.git` pointer or a
// `commondir` whose target cannot be worked out the way git works it out. On
// Linux the same condition arrives as a LinuxSandboxProfileError carrying
// `deny_git_metadata_unreadable`.
// The other refusal the shared producers raise: the `.git/modules` walk ran
// out of the time it was given, which on Linux arrives as a
// LinuxSandboxProfileError carrying `deny_scan_failed`.
export {
GitMetadataError,
SubmoduleWalkBudgetError,
} from './sandbox/mandatory-deny-paths.js'
// The mount points a running sandbox relies on (Linux), as a snapshot, for an
// embedder that removes paths itself after a command to leave out.
export { liveMountPoints } from './sandbox/bwrap-mount-manifests.js'

// Windows install/status API
export {
Expand Down
Loading
Loading