You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(spurd): drop privilege inside unshare wrapper, not before exec (#128) (#130)
When spurd ran as root and a non-root user submitted a job, two
is_root()-guarded branches in `launch_job` interacted incorrectly:
1. `use_namespaces` built `unshare --pid --mount --fork bash wrapper.sh`
2. `cmd.uid(uid)` + `cmd.gid(gid)` were applied via `pre_exec`
Because pre_exec runs between fork and exec, the child dropped to the
unprivileged uid *before* exec'ing unshare. The unshare(2) syscall then
failed with EPERM (CAP_SYS_ADMIN required for CLONE_NEWNS|CLONE_NEWPID),
producing the user-visible:
unshare: unshare failed: Operation not permitted
A second, hidden bug on the same path: even if unshare had succeeded,
the wrapper's `mount -t proc proc /proc` and friends would silently
no-op (`2>/dev/null || true`) for the unprivileged user, so namespace
isolation has been ineffective whenever uid > 0.
Fix:
- Move the privilege drop *inside* the wrapper script, after unshare
creates the namespaces and after the mounts run, using
`setpriv --reuid=$U --regid=$G --init-groups -- /bin/bash $SCRIPT`.
- Skip the cmd.uid()/cmd.gid() pre_exec hooks when use_namespaces is
true, since the wrapper now handles the drop.
- `setpriv --init-groups` calls initgroups() based on --reuid, so
video/render supplementary groups (needed for /dev/dri and /dev/kfd)
are still set for the user payload.
Refactor the wrapper construction into `build_namespace_wrapper`, a
pure function that returns the bash script. Adds three unit tests:
- uid > 0 → wrapper contains setpriv with --reuid/--regid/--init-groups,
setpriv runs after the proc mount, and there is no bare `exec /bin/bash`
slip-through.
- uid == 0 → wrapper exec's bash directly, no setpriv.
- gpu_devices → wrapper emits renderD copy lines only for allocated
device IDs.
setpriv ships with util-linux on every Linux distro, so no new runtime
dependency.
Closes#128
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments