fix(left4me-script-sandbox): self-wrap into PID 1's mount namespace
The web service runs with PrivateTmp=true, which puts it in its own mount namespace. Worker invokes the sandbox helper via sudo from there; the helper's pre-systemd-run `mount --bind --map-users=...` lands in the web service's namespace. systemd-run then spawns transient units in PID 1's namespace where the bind is invisible — the BindPaths lookup finds an empty staging dir owned by root, and the sandbox uid hits permission-denied on every write. Mirror the pattern from left4me-overlay's ExecStartPre wrapper: enter PID 1's mount namespace at the start of the helper via `nsenter --mount=/proc/1/ns/mnt`. Sentinel env var avoids exec recursion. The gameserver helper handles this at the unit level; the script helper doesn't have a unit so we self-wrap. Diagnosis: 5 failed builds all hit the same EACCES on the first `mkdir`/`tar mkdir`. Direct SSH-sudo invocations of the same helper succeeded because SSH-sudo doesn't inherit a private namespace; only the worker-invoked path is affected. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
48381089d3
commit
7a25c2453c
1 changed files with 12 additions and 0 deletions
|
|
@ -19,6 +19,18 @@
|
||||||
# not signal-able due to UID mismatch.
|
# not signal-able due to UID mismatch.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Self-wrap into PID 1's mount namespace before doing anything mount-related.
|
||||||
|
# The web app's left4me-web.service has PrivateTmp=true, which gives it a
|
||||||
|
# private mount namespace. When the worker invokes us via sudo, we inherit
|
||||||
|
# that namespace; our `mount --bind` would land there. systemd-run below
|
||||||
|
# spawns transient units in PID 1's namespace (where they don't see the
|
||||||
|
# private bind), so the sandbox would bind onto an empty staging dir and
|
||||||
|
# permission-deny on every write. The sentinel env var avoids an exec loop.
|
||||||
|
if [[ "${L4D2_SANDBOX_IN_PID1_MNT_NS:-}" != "1" ]]; then
|
||||||
|
exec env L4D2_SANDBOX_IN_PID1_MNT_NS=1 \
|
||||||
|
/usr/bin/nsenter --mount=/proc/1/ns/mnt -- "$0" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
[[ $# -eq 2 ]] || { echo "usage: $0 <overlay_id> <script>" >&2; exit 64; }
|
[[ $# -eq 2 ]] || { echo "usage: $0 <overlay_id> <script>" >&2; exit 64; }
|
||||||
|
|
||||||
OVERLAY_ID=$1
|
OVERLAY_ID=$1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue