Commit Graph

6 Commits

Author SHA1 Message Date
ceamac 095ae8397a Drop --unshare-net from bwrap args, no network setup yet
Without any network setup (slirp4netns or similar), unsharing the
network namespace just leaves the sandbox with no network at all,
which isn't useful yet. build_bwrap_args() now skips --unshare-net
when assembling the real bwrap invocation; re-add once network
isolation is implemented.

detect_bwrap_unshare_args() itself is unchanged and still probes/
reports net namespace kernel support (e.g. via -t/--test), since
that's capability detection, not policy -- same pattern as the
--new-session removal.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 06:17:20 +00:00
ceamac b1a2d924e8 Don't request --unshare-user for bwrap when running as root
Root already has full privilege without a new user namespace. Creating
one anyway (bwrap's default single-mapping uid/gid setup, no
--uid/--gid/subuid ranges) forces the kernel's unprivileged-userns
setgroups() restriction: every supplementary group outside that one
mapping collapses to the overflow gid (65534/"nobody"), and
setgroups() calls inside the sandbox then fail.

Reported by the user running -r images/gitea.tar as root: `id` showed
groups=0(root),65534(nobody) repeated once per real supplementary
group, and `su git` failed with "can't set groups: Operation not
permitted". detect_bwrap_unshare_args() now skips --unshare-user (and
stops combining the other probes with CLONE_NEWUSER) whenever
geteuid() == 0 -- confirmed fixed by the user on a root-capable
machine. The non-root path is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 05:34:41 +00:00
ceamac 529a96c89c Combine namespace probes with CLONE_NEWUSER
As a regular (non-root) user, most namespace types can only be
unshared together with a fresh user namespace, not in isolation --
the user namespace is what supplies the needed capabilities. Probing
each type on its own under-reported support: on this dev machine only
--unshare-user came back as supported, when in fact ipc/pid/net/uts/
cgroup were all usable once combined with it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 09:07:29 +00:00
ceamac 4478e94b65 Drop --new-session from bwrap args, breaks foreground tty
It detaches the sandboxed process from the controlling terminal, so
an interactive /bin/sh fails with "can't access tty; job control
turned off." Re-add it once background/daemonized runs land, where
detaching from the terminal is actually the point.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 07:52:49 +00:00
ceamac c0bef0d989 Add -r/--run and -c/--cleanup, fix nsenter under root
-r/--run mounts an image, runs a command under bwrap in the
foreground (default /bin/sh, overridable via -- <command> [args...]),
then unmounts and cleans up when it exits. -c/--cleanup deletes a
layer and its ancestor chain from local storage (containers-storage
delete-layer, walking parents via `layer --json`), since -u only ever
unmounted.

bwrap needs to see the merged mount from inside the private namespace
containers-storage mount creates when running rootless; run_bwrap()
locates the live fuse-overlayfs process and runs bwrap via nsenter
into its namespaces. When running as root no such namespace exists
(containers-storage doesn't need to reexec for privilege), so nsenter
fails with EINVAL; detect geteuid() == 0 and skip it automatically
there. -n/--no-nsenter forces it off manually for any other case.

process.cpp gains run_process_foreground() (inherited stdio, for the
interactive bwrap run) and the relocated find_in_path(), now shared
with bwrap.cpp's nsenter lookup.

Also: meson test only ran -m, leaking a layer on every run; it now
runs tests/run_test.py, which drives mount -> umount -> cleanup and
fails if any step does.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 07:44:24 +00:00
ceamac 839551a648 Add kernel namespace detection for bwrap integration
Add detect_bwrap_unshare_args(), which probes the running kernel for
which namespace types (user, ipc, pid, net, uts, cgroup) can actually
be unshared and returns the matching bwrap --unshare-xxx flags. Each
probe forks a throwaway child to call unshare() so the calling
process's own namespaces are never touched. Needed because the target
device (Android, stock kernel) only supports a subset of namespace
types, so bwrap must be invoked with just the flags it can honor.

Temporarily wired into -t/--test so it can be exercised on-device
ahead of the real bwrap invocation; will be removed once that lands.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 05:56:31 +00:00