Repository navigation
unshare and a namespace clone fail with EPERM in a zone instead of killing it - #219
Merged
Merged
Conversation
…lling it, so Firefox, Chromium and bubblewrap can probe for user namespaces and start Firefox, Chromium, Electron programs and bubblewrap probe for user namespaces at start with clone(CLONE_NEWUSER) or unshare(CLONE_NEWUSER) and carry on when the answer is EPERM: the kernel's answer to an unprivileged caller, and the one Docker's and Podman's default profiles give. A kill left Firefox unable to start in a zone at all. unshare stays on the denied list, so no policy can allow it; setns is killed and clone3 gets ENOSYS as before. seccomp-trace names both calls as soft refusals and answers EPERM. The launcher, adversarial and boundary suites expect the refusal and that no namespace is made, with an unshare-newuser probe beside clone-newuser.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The zone filter killed a process that called clone(2) with any
CLONE_NEW*flag, or unshare(2). Firefox, Chromium, Electron programs and bubblewrap probe for user namespaces at start withclone(CLONE_NEWUSER)orunshare(CLONE_NEWUSER)and carry on when the answer is EPERM, so the kill left Firefox unable to start in a zone at all. EPERM is what the kernel tells an unprivileged caller, and what Docker's and Podman's default profiles answer.The filter (
seccomp.rs). clone with any bit ofCLONE_NS_MASKreturnsERRNO|EPERM; a plain clone is allowed as before. unshare joinsREFUSED_SOFTLYwith EPERM and stays inDENIED_RATIONALE, so no policy file can allow it, as with the set*id calls. setns is still killed and clone3 still gets ENOSYS; nothing else changes. One helper,soft_refusal, picks the errno or the trace notification for both the clone rule and the soft-refusal loop.seccomp-trace (
main.rs) answers a notified call throughseccomp::soft_errno: EPERM for a namespace clone, theREFUSED_SOFTLYerrno for the rest of that list, and ENOSYS for anything a zone is killed for (another architecture included). Both calls are printed withsoftand fail with EPERM, as in a zone.Probes.
seccomp-test clone-newuserexits 7 when the call fails with EPERM (it returned 0 whatever happened and relied on the kill), and a newunshare-newuserprobe does the same for unshare.What the tests assert
ERRNO|EPERM; a plain clone is allowed; setns is killed; both stay denied andwidenedrefuses them; under trace both areUSER_NOTIF. For every denied or softly refused call, a namespace clone andTIOCSTI, the trace filter notifies andsoft_errnomatches what the zone filter returns, so the tracer cannot drift from the zone.launcher.sh: the zone check runsunshare -U readlink /proc/self/ns/userand wants exit 1 with "Operation not permitted"; SIGSYS (159) fails it, and so does a printeduser:[...], a namespace made. Theclone-newuserprobe wants 7, not 5. A new check runs both calls underseccomp-traceand wantsKRYPTIK_SECCOMP_DENIED 56 clone soft,KRYPTIK_SECCOMP_DENIED 272 unshare softand two-1 1lines: a kernel may answer EPERM as well, and the names show the filter is what refuses.adversarial.sh: unshare leaves the SIGSYS loop, which keeps 12 calls with setns first, and a second loop wants 7 fromunshare-newuserandclone-newuser. Its precondition has already shown that the host lets the suite make a user namespace, so the EPERM is the filter's. Thefor ns in NEWUSER ...loop checks that isolate.rs declares kryptikd's own namespace set, not the filter, so it is unchanged.boundary-checks.sh:unshare -U /bin/truein a zone wants exit 1 and "Operation not permitted" instead of 159, and the probe list wantsclone-newuser 7,unshare-newuser 7,setns 5. Its comment no longer says the image's python lacks ctypes;build/recipes/python.shrequires it.Docs.
hardening.mdanddesign/zone-policy-files.mdsay both calls fail with EPERM and why.decisions.mdis untouched.Conflicts to expect. #194 (cleanup-kryptikd) rewords the seccomp.rs comments this edits (the ERRNO note,
REFUSED_SOFTLY, the trace comment the helper replaces) and renames the namespace-clone test. #197 (cleanup-compartment-suites) rewords the comments beside the unshare check, the filter probes and the adversarial SIGSYS loop. #208 (cleanup-docs) rewrites the same hardening.md paragraph, the "13 of these calls" line and the policy-file trace paragraph. #181 (clock-floor) and #182 (fuzz-schedule) touch main.rs elsewhere, and #178 and #184 add lines to boundary-checks.sh away from these. #214 (zone-input-checks) touches none of these files.Not built or run on the laptop: CI compiles and tests kryptikd on glibc and musl and runs the three suites unprivileged, and a Distro run takes them as root on the target kernel.