run: fail fast on unusable sandbox bind paths (+ empty-src bind_try skip) #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "run/bind-dest-validation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Engine-side hardening that came out of the batch-3/4 packaging work: fail fast on sandbox bind paths that cannot work at exec time.
The problem: the staged rootfs (composefs render over FUSE, or the compose overlay) is read-only, and bwrap creates bind destinations by mkdir inside it — dying LATE with the cryptic
Can't mkdir <dst>: Read-only file system(tmux hit this in the pkgs batch-3 gate).--diris no escape: same mkdir, same EROFS (verified against bwrap 0.11.2). The repo's own conventions (tmux/nvimRUN mkdir -p, distroless/dirs/COPY) exist precisely because of this, but nothing told you that was the fix.The change:
validate_bind_pathsruns before bwrap on both the direct and compose-inner paths and turns each case into an early error that names the bind and the fix. Destination existence is judged against the SANDBOX VIEW, not the bare rootfs — host-overlaid dirs (/run /var /etc /home /mnt /media /opt /srv) stat host-side; /tmp /dev /proc are engine-mounted writable pseudo-fs; everything else stats the rootfs.Bonus fix (real latent bug): bwrap does NOT treat an empty bind_try source as "missing" — it falls into the dst mkdir and EROFS. An unset
$VARin an entrypoint expands to exactly that empty string, so pkgs#14's openssh-clients agent-socket design (bind_try $XDG_RUNTIME_DIR) was broken on any host with no runtime dir, despite passing CI (which sets the var).push_bindnow skips empty-source try binds with a warning, making that design actually degrade as documented; required binds with empty/missing sources error loudly via the validator.Deliberately rejected: auto-creating mountpoints engine-side. The FUSE server is the pinned upstream composefs-fuse serving an immutable EROFS image — creation would mean forking it or prerendering per-run images. Hard error + actionable message instead (maintainer call, 2026-09-24; happy to revisit if we ever want a writable-root layer).
9 new unit tests (116 total green), clippy --all-targets clean, release build green. Third commit is drive-by newer-clippy fallout in sources/home (empty format literal, useless vec! in tests) so the bar stays green on rust:bookworm's toolchain.