Skip to content

fix(sandbox): create the jail's HOME directory with bwrap --dir - #3

Merged
clhodapp merged 1 commit into
mainfrom
fix/sandbox-home-dir
Sep 19, 2026
Merged

clhodapp merged 1 commit into
mainfrom
fix/sandbox-home-dir

Conversation

@clhodapp

Copy link
Copy Markdown
Owner

The bug

parenting--sandbox-command-wrapper points HOME at <socket-directory>/home and its comment said that was "a writable HOME on the tmpfs". Nothing created the directory, and it is not on the tmpfs: the socket directory is a read-write bind at the same path, and /tmp is the tmpfs. A --batch child never writes to HOME, so the sandbox tests passed; a --fg-daemon child does (savehist, recentf, the native-comp cache, user-emacs-directory) and fails on the missing directory.

The fix

The wrapper now emits --dir <home> after the socket-directory --bind (so the mount exists when the directory is created inside it) and before --clearenv and --setenv HOME. bwrap's --dir creates the directory in the jail; it lives under the read-write bind and goes away with the socket directory at shutdown. The docstrings and comments that said "tmpfs" now say that.

Tests

parenting-sandbox-wrapper-core-flags asserts the --dir value is <socket-dir>/home and that it sits after the socket --bind and before --setenv HOME. The guarded integration test parenting-spawn-sandbox-child-roundtrips now asserts, inside the child, that (getenv "HOME") is an existing writable directory; on this machine bwrap can create a user namespace, so that ran in a real jail rather than skipping.

make compile is clean; Ran 56 tests, 56 results as expected, 0 unexpected, the same on clean main.

🤖 Generated with Claude Code

`parenting--sandbox-command-wrapper` pointed HOME at
<socket-directory>/home but nothing created that directory.  The
socket directory is bind-mounted read-write at its own path, so HOME
lay inside a writable mount, yet the `home` subdirectory did not
exist.  A --batch child never writes to HOME; a --fg-daemon child does
(savehist, recentf, the native-comp eln cache, `user-emacs-directory')
and failed on the missing directory.

Emit `--dir <home>` after the socket-directory `--bind` (so the mount
exists when the directory is created inside it) and before
`--clearenv`/`--setenv HOME`.  Correct the comments and docstrings
that called this HOME "on the tmpfs": it is a directory created per
child under the read-write socket-directory bind, removed with the
socket directory at shutdown.

Tests: `parenting-sandbox-wrapper-core-flags` now asserts the
argument list carries exactly one `--dir` whose value is
(expand-file-name "home" <socket-dir>), positioned after the
socket-directory bind and before `--setenv HOME`.
`parenting-spawn-sandbox-child-roundtrips` additionally asserts,
from inside the jail, that (getenv "HOME") is an existing, writable
directory.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@clhodapp clhodapp self-assigned this Sep 19, 2026
@clhodapp
clhodapp merged commit dba368d into main Sep 19, 2026
8 checks passed
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.

1 participant