fix(sandbox): fall back to --map-auto when root-user mapping is restricted - #3280
fix(sandbox): fall back to --map-auto when root-user mapping is restricted#3280Einspanner123 wants to merge 3 commits into
Conversation
No behavior change. Move the inline probe out of unshare_user_namespace_works into a reusable unshare_probe helper and a cached working_unshare_mapping() that picks the first working candidate from UNSHARE_MAPPING_CANDIDATES, so the launcher and the capability probe share one code path.
…icted Plain `unshare --user --map-root-user` fails on kernels and containers that block unprivileged writes to /proc/self/uid_map (e.g. GitHub Actions, restricted AppArmor profiles). On those systems util-linux delegates to the setuid newuidmap/newgidmap helpers when --map-auto is also present. Add the combined form as a fallback candidate and build the launcher args from the probed mapping, so systems without newuidmap/newgidmap or a /etc/subuid range keep using the plain form.
d17590b to
277fdda
Compare
|
Solid fix. The fallback from --map-root-user to --map-auto is the correct approach for environments where /proc/self/uid_map is restricted (GitHub Actions, AppArmor, some Docker setups). Probing both at startup and caching the result avoids runtime surprises. One thing to verify: does the --map-auto path require |
… fallback The fallback candidate relies on the setuid newuidmap/newgidmap helpers (uidmap package) plus a subuid/subgid range for the current user. Note in the candidate docs that the startup probe rejects the candidate when those are missing, so the plain --map-root-user form is used instead.
|
Good question — yes, the Dependency: when Why this is safe: the startup probe ("Probing both at startup") runs the exact candidate command, so it covers this automatically. Verified empirically: So on systems without Documented this dependency in the candidate docs — see the new commit (9cbe6d9) in this PR. |
|
Thanks for the detailed clarification. The startup probe covering the dependency automatically is exactly what I was hoping for — no need for extra config or docs then. LGTM on the approach. |
|
Hi @code-yeongyu @Yeachan-Heo — quick heads-up on this PR (replacement for the closed #3013). Following @code-yeongyu's earlier request, the branch has been rebased onto the latest One thing needs a maintainer's help: since this is a fork PR, the |
|
The rebase looks clean and the --map-auto fallback approach is the right direction. Since this supersedes #3013, the commit history is well-structured. I think this is good to go once CI passes. |
Replaces the closed #3013 (stale, conflicts with main) with a fresh rebase onto
ultraworkers:main.Problem
unshare --user --map-root-userfails on kernels and containers that block unprivileged writes to/proc/self/uid_map(e.g. GitHub Actions, restricted AppArmor profiles, some container runtimes) with EPERM. As a result the sandbox silently disables itself even though a working mapping exists.Fix
util-linux delegates to the setuid
newuidmap/newgidmaphelpers when--map-autois also present. Probe both candidate mappings at startup and prefer the plain form:--user --map-root-user(works on most systems, no extra deps)--user --map-root-user --map-auto(fallback for restricted kernels/containers)The chosen mapping is cached and reused by both the capability probe and the launcher, so the sandbox now enables on systems where only the fallback works. The plain form stays first, so systems without
newuidmap/newgidmapor a/etc/subuidrange are unaffected.Note: the
--map-autofallback depends on the setuidnewuidmap/newgidmaphelpers (theuidmappackage on Debian/Ubuntu) and on the current user having a subuid/subgid range. The startup probe covers this dependency: when the helpers or range are missing,unshare --map-autofails and the plain form is used (verified:unshare --user --map-root-user --map-auto trueexits 127 withfailed to execute newuidmapwithout the helper).Verification
unshare --user --map-root-user truefails, combined form succeedscargo test -p runtime sandboxpasses (incl. new test guarding candidate order)cargo clippyclean for the changed file