| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
All contributors have signed the DCO ✍️ ✅ |
Sorry, something went wrong.
|
I have read the DCO document and I hereby sign the DCO. |
Sorry, something went wrong.
|
recheck |
Sorry, something went wrong.
|
Few points of note:
|
Sorry, something went wrong.
Sorry, something went wrong.
|
The new OCSF degraded-mode alert may not fire. The parent-side probe returns early if CAP_SETPCAP is present in the effective set, but the commit message says Podman can grant CAP_SETPCAP while AppArmor still makes bounding::clear() fail with EPERM. Then we skip the parent DetectionFinding, and only hit the warn! inside pre_exec, which is exactly the context this patch says cannot reliably emit structured logs. Could we make the readiness probe test the actual bounding-set clear behavior ? |
Sorry, something went wrong.
|
@waynesun09 look to me. Just fix the format issue and we're good to merge |
Sorry, something went wrong.
|
@alangou it's updated, please check, thanks |
Sorry, something went wrong.
|
@alangou the new ci clippy failure on backticked AppArmor is fixed, sorry I missed that in the local test |
Sorry, something went wrong.
| toolchain: "1.95.0" | ||
| cache: false | ||
|
|
||
| - name: Run supervisor capability tests without CAP_SETPCAP |
There was a problem hiding this comment.
This test does not align with how we would ideally be testing this feature. We should add an e2e test suite that uses rootless podman, and not just run the unit tests as a regular user.
Sorry, something went wrong.
There was a problem hiding this comment.
Ok, I'm on checking the current e2e test which is with nested container, with the out layer started with --privilege and it might have the AppArmor disabled and could not cover the bug, I'm still testing on it, will let you know the findings.
If we could add the e2e test, do you want me to keep current drop privilege test or just keep it?
Sorry, something went wrong.
There was a problem hiding this comment.
I started #2119 to move the rootless tests out of the container, but I have not yet been able to reproduce the failure you're seeing.
Feel free to comment on the PR if you something obvious sticks out.
@alangou don't take my comments as blocking. If this fixes the regression, we can merge and then add better testing ... Although being able to reproduce the behaviour would have been a win.
Sorry, something went wrong.
There was a problem hiding this comment.
This is triggered by the supervisor image version pinning bug (#2068). The Podman driver defaults supervisor_image to :latest, so an older gateway (pre-#2001, SETPCAP in cap_drop) pulls a newer supervisor (v0.0.73 with bounding::clear()). The gateway's container spec never grants CAP_SETPCAP, but the supervisor now needs it — prctl(PR_CAPBST_DROP) returns EPERM and the supervisor crashes.
I verified locally via podman inspect on a gateway-created container: SETPCAP was in CapDrop, confirming the pre-#2001 container spec.
With a matched gateway+supervisor both post-#2001 (SETPCAP in cap_add), the prctl succeeds because drop_capability_bounding_set() runs before setuid() while CapEff is still full. I need to verify that locally first — will update here once confirmed.
To reproduce: use a pre-#2001 gateway binary with the latest supervisor image (the :latest default makes this happen naturally until #2068 is fixed).
Either way the fix is still valid as defensive code: the supervisor shouldn't crash when CAP_SETPCAP is absent regardless of the reason (version skew, custom container specs, non-podman runtimes).
Sorry, something went wrong.
There was a problem hiding this comment.
Confirmed locally: matched v0.0.73 gateway + supervisor does not crash.
$ openshell status Version: 0.0.73 $ openshell sandbox create --no-keep -- echo "ok" Created sandbox: lawful-soldierfish ok ✓ Deleted sandbox lawful-soldierfish $ openshell sandbox create --name verify-caps -- bash -c "cat /proc/self/status | grep -i cap; id" CapBnd: 0000000000000000 uid=998(sandbox) gid=998(sandbox)
Bounding set cleared successfully — drop_capability_bounding_set() runs before setuid() while CapEff still has CAP_SETPCAP, so prctl(PR_CAPBSET_DROP) succeeds.
The crash only reproduces under version skew: pre-#2001 gateway (SETPCAP in cap_drop) + post-#2001 supervisor. The :latest pinning bug (#2068) creates this naturally when the registry publishes a new supervisor ahead of a gateway upgrade.
The fix remains valid as defensive hardening — the supervisor shouldn't crash when CAP_SETPCAP is absent regardless of the cause.
Sorry, something went wrong.
There was a problem hiding this comment.
Reproduced locally with v0.0.72 gateway + v0.0.73 supervisor:
$ /tmp/openshell-072/openshell status
Version: 0.0.72
$ /tmp/openshell-072/openshell sandbox create --no-keep -- echo "ok"
Error: sandbox is not ready
Container exited with code 1
$ podman inspect openshell-sandbox-repro-crash --format '{{json .HostConfig.CapDrop}}'
["CAP_DAC_OVERRIDE","CAP_FSETID","CAP_KILL","CAP_NET_BIND_SERVICE","CAP_SETFCAP","CAP_SETPCAP","CAP_SYS_CHROOT"]
v0.0.72 gateway has CAP_SETPCAP in cap_drop. v0.0.73 gateway removed it (via #2001). The version skew is the trigger.
Sorry, something went wrong.
|
Rebased on main (includes #2119). Dropped the old rootless-caps CI job initially thinking #2119's e2e covered it, then re-added after analysis. Why e2e-podman-rootless (#2119) doesn't cover this fix: The e2e builds the gateway from the same checkout (e2e_build_gateway_binaries → cargo build -p openshell-server) and uses a supervisor image tagged with the same commit SHA (inputs.image-tag). Gateway and supervisor are always matched — the version skew that triggers the EPERM path never occurs. Pinning a v0.0.72 gateway in e2e isn't good either, coupling a regression test to a specific old release is fragile. Why the unit test job works: The rootless-caps job runs cargo test -p openshell-supervisor-process --lib -- capability_bounding drop_privileges as an unprivileged testuser on bare ubuntu-24.04. That user has no CAP_SETPCAP in CapEff, so prctl(PR_CAPBSET_DROP) returns EPERM with a non-empty bounding set — directly exercising validate_capability_bounding_set_clear() through drop_privileges(). No version pinning needed, stable across future versions. |
Sorry, something went wrong.
|
I am struggling with this change because it degrades the security boundary and I prefer the fail-closed behavior that exists today. I'd be interested in what @drew, @TaylorMutch, and/or @cgwalters have to say about it. |
Sorry, something went wrong.
|
Maybe there should be a config option that allows the degraded behavior 🤔 |
Sorry, something went wrong.
|
Since this is caused by a version mismatch between the gateway and the supervisor, I don't think we should change the handling of the bounding set at this stage. What we should do is:
|
Sorry, something went wrong.
I think we should avoid degrading any boundary and always prefer to fail closed. If there is a capability that is unavailable, then we should find a way to explicitly configure a topology (#2048) to support that configuration. |
Sorry, something went wrong.
…unavailable When the supervisor lacks CAP_SETPCAP in its effective set (for example, a container runtime that does not grant it), the child's prctl(PR_CAPBSET_DROP) returns EPERM during privilege drop. The clear runs inside pre_exec, which cannot emit structured logs, so the failure surfaced only as an opaque child exit with code 1. Keep the bounding-set clear fail-closed and make the failure diagnosable: - Probe PR_CAPBSET_DROP availability in the parent before fork() with a non-destructive bounding::drop() on a capability that is already absent from the bounding set. When the probe detects EPERM with a non-empty bounding set, emit an OCSF DetectionFinding alert and refuse the spawn with an actionable error. - Extend the child-side EPERM error in validate_capability_bounding_set_clear() with the CAP_SETPCAP diagnosis and remediation hint as a backstop for environments the parent probe cannot predict. Related to NVIDIA#2069 Signed-off-by: Wayne Sun <gsun@redhat.com>
|
@maxamillion @elezar @drew Thanks for the feedback — I've reworked the PR to keep the bounding-set clear fail-closed. The EPERM-tolerance branch, degraded-mode docs, and the rootless-caps CI job are all dropped. What remains is diagnosability: the clear runs inside pre_exec, which can't emit structured logs, so a blocked clear previously surfaced only as an opaque exit code 1. The parent now probes PR_CAPBSET_DROP availability before fork() and refuses the spawn with an actionable error plus a High-severity OCSF DetectionFinding when CAP_SETPCAP is unavailable. The child-side EPERM error carries the same diagnosis as a backstop. Supporting genuinely capability-limited runtimes as an explicit opt-in seems like a better fit for the topology work in #2048. Verified in rust:1.95 containers, including a --cap-drop SETPCAP run that exercises the refusal path end-to-end; details in the updated description. |
Sorry, something went wrong.
|
This pull request has had no activity for 14 days and is now marked stale. It may be closed in 7 days if there is no further activity. |
Sorry, something went wrong.
|
Closing as stale. |
Sorry, something went wrong.
The probe was added with the original rootless Podman CI lane in #2119 while investigating #2075. The reported failure was later traced to mismatched gateway and sandbox versions rather than rootless Podman capability-set handling. Since #2981 removed the direct rootless Podman job, this probe no longer has a caller and does not represent active coverage. Signed-off-by: Evan Lezar <elezar@nvidia.com>
The probe was added with the original rootless Podman CI lane in #2119 while investigating #2075. The reported failure was later traced to mismatched gateway and sandbox versions rather than rootless Podman capability-set handling. Since #2981 removed the direct rootless Podman job, this probe no longer has a caller and does not represent active coverage. Signed-off-by: Evan Lezar <elezar@nvidia.com>
The probe was added with the original rootless Podman CI lane in #2119 while investigating #2075. The reported failure was later traced to mismatched gateway and sandbox versions rather than rootless Podman capability-set handling. Since #2981 removed the direct rootless Podman job, this probe no longer has a caller and does not represent active coverage. Signed-off-by: Evan Lezar <elezar@nvidia.com>
| Back | FazBrowse Home | New Git URL |
Summary
When the supervisor lacks CAP_SETPCAP in its effective set (for example, a container runtime that does not grant it), the child's prctl(PR_CAPBSET_DROP) returns EPERM during privilege drop. The clear runs inside pre_exec, which cannot emit structured logs, so the failure surfaced only as an opaque child exit with code 1.
Following the review discussion, this PR keeps the bounding-set clear fail-closed — no tolerance path, no degraded mode — and instead makes the failure diagnosable:
The version-skew trigger that originally surfaced this (older gateway pulling a newer :latest supervisor image) was fixed separately by #2070, which closed #2068. This PR addresses the remaining gap from #2069: a supervisor that cannot clear the bounding set should fail fast with a clear diagnosis rather than an undiagnosable crash.
Related Issue
Related to #2069
Changes
Compared to the previous revision of this PR: the EPERM-tolerance branch, the degraded-mode documentation, and the rootless-caps CI job are all dropped per review feedback.
Testing
Checklist