fix(sandbox): undo tmpfs overlay when setns fails during SPIFFE mount namespace setup#2184
Conversation
|
/ok to test bec39d9 |
bec39d9 to
4d0c97a
Compare
lbelyaev
left a comment
There was a problem hiding this comment.
Thanks for tracking down the setns/EPERM case — the umount2(MNT_DETACH) in the error path (R348–R354) is a real fix and stands on its own.
Two concerns, both flagged inline, and both about the same thing: the PR pairs that fix with changes that let a sandbox keep serving traffic after a core safety property has failed. R242–R246 continues without workload identity when mount-namespace setup fails; R236–R241 symlinks around the ancestor-integrity check. For a runtime whose value is that these properties hold, degrading past either silently is a worse failure than not starting.
Would it be possible to land the umount2 fix on its own — the focused version in #2012 looked like it did exactly that — and treat the fail-open behaviours as a separate discussion? Happy to help however's useful; we're running this fail-closed downstream and would rather converge on an upstream shape than carry a patch.
| eprintln!( | ||
| "WARN: supervisor identity mount namespace setup failed ({err}), continuing without isolation" | ||
| ); | ||
| let _ = SUPERVISOR_IDENTITY_MOUNT_NS.set(None); |
There was a problem hiding this comment.
this catches setup failure, logs a warning, sets the namespace to None, and continues "without isolation." — on the same path that carries the SVID the whole identity model depends on. For a governance control plane an agent that silently runs without workload identity is worse than one that fails to start. The umount2 fix in the same PR is correct and separable; the fail-open wiring is not.
| if let Ok(exe_proc) = std::env::current_exe() { | ||
| if exe_proc != *exe_argv0 && !exe_proc.exists() && exe_argv0.exists() { | ||
| if let Some(parent) = exe_proc.parent() { | ||
| let _ = std::fs::create_dir_all(parent); | ||
| } | ||
| let _ = std::os::unix::fs::symlink(exe_argv0, &exe_proc); | ||
| } |
There was a problem hiding this comment.
This symlink works around the ancestor-integrity check rather than satisfying it. That check stats /proc/self/exe on every proxied request and denies traffic when the path is absent — it's a runtime integrity guarantee on the request path, not a startup nicety. Creating a symlink so the check passes means a proxied request no longer verifies the running binary is the one that was launched. The errors are dropped (let _ =), so a partial failure leaves the check silently satisfied rather than failing closed. The stale /proc/self/exe is a genuine side effect of the mount-namespace change, but the fix should restore honest resolution — not make an integrity check pass unconditionally.
… namespace setup On OpenShift and other container runtimes that do not grant CAP_SYS_ADMIN, setns(CLONE_NEWNS) fails with EPERM after create_supervisor_identity_mount_namespace has already mounted an empty tmpfs over the SPIFFE workload API socket directory. PID 1 remains stuck in the new mount namespace where the tmpfs hides the socket, making it invisible to all processes. Fix: when setns() fails, call umount2(MNT_DETACH) to remove the tmpfs overlay before returning the error, so the SPIFFE socket stays accessible even without namespace isolation. Signed-off-by: Adel Zaalouk <azaalouk@redhat.com>
4d0c97a to
44d7a88
Compare
|
@lbelyaev thanks for the careful review — you're right on both counts. I've restructured the PR to land only the umount2 fix:
The diff is now a single change in |
Summary
setns(CLONE_NEWNS)fails withEPERM(common on OpenShift and hardened K8s withoutCAP_SYS_ADMIN),create_supervisor_identity_mount_namespaceleaves an empty tmpfs mounted over the SPIFFE workload API socket directory. Since PID 1 is stuck in the new mount namespace, the socket becomes invisible to all processes in the container, even though the CSI volume is healthy.umount2(MNT_DETACH)in thesetns()error path to remove the tmpfs overlay before returning, keeping the SPIFFE socket accessible.Related Issue
N/A (discovered during SPIFFE + token grant integration testing on OpenShift)
Changes
crates/openshell-supervisor-process/src/process.rs:create_supervisor_identity_mount_namespace: onsetns()failure,umount2(target, MNT_DETACH)before returning errorTesting
/spiffe-workload-api/spire-agent.sockis visible inside sandbox containercargo test --workspace)Checklist
cargo fmtcleancargo clippyclean