Repository navigation
podman stub: snug's own binary replaces the /bin/sh script (#691) - #695
Merged
Merged
Conversation
Issue #691. /snug/bin/podman was a KindData /bin/sh dispatcher, so it needed a shell inside and baked the shim's host path into a heredoc. Now it is a KindSymlink to /snug/lib/snug/wrapper, staged with the wrapper bind, and internal/wrapper/podman.go is the dispatcher. Main runs the stub when argv[0]'s basename is podman AND os.Executable() is WrapperGuest: bwrap's execvp and a shell pass the bare word, and the image check keeps a host snug installed as podman the CLI. The stub execs the first of docker, then podman-remote (policy.PodmanStubClients) on PATH, skipping /snug/bin and relative entries. docker keeps the subcommand allowlist and podman-only refusals; podman-remote gets argv verbatim, the proxy filtering it. Connection-shaping flags refused on both. Neither found: 125 naming both. The shim path is no longer in any message. --dry-run COMMANDS block and JSON containers.podman_stub* name the client this sandbox's PATH reaches (Policy.PodmanStubClient), or that it reaches neither. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…client Red team, issue #691: a profile putting a payload-writable directory on PATH, even after /usr/bin, lets the payload drop a docker the stub execs, while --dry-run named the client on disk now. PodmanStubClient now also returns the first such directory searched before the answer (IsShadowSlot), and the COMMANDS block and JSON containers.podman_stub_writable say so. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…on flags F1 (sev:low): --dry-run named a client the payload could replace when the client PATH itself was writable though its directory was not — a host link under a ro bind pointing into /tmp, or a file granted rw in a ro directory. PodmanStubClient now asks IsShadowSlot of each searched client path too. F2 (sev:low): podman -H=tcp://... ps reached docker, while --dry-run says connection-selecting flags are refused. Each client's own global spellings (docker -H --host -c --context --config; podman-remote -r -c --identity) are now refused before the subcommand, not after, where -c is --cpu-shares. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Section 3 claimed podman-remote is refused at the libpod create and pull routes; libpodcreate.go examines both, and the stub now execs podman-remote. Section 8's client order, flag lists, dispatch rule and --dry-run fields restated comments in internal/wrapper/podman.go and podmanstub.go; they are now pointers. Section 9's docker cp concern duplicated section 4. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Closes #691.
/snug/bin/podmanwas KindData/bin/shdispatcher: needed shell inside, baked shim host path into heredoc. NowKindSymlink->/snug/lib/snug/wrapper, wrapper bind staged with it. Dispatcher in Go:internal/wrapper/podman.go.Dispatch
Main: stub whenfilepath.Base(argv[0]) == "podman"ANDos.Executable() == WrapperGuest. bwrap execvp / shell PATH lookup pass barepodman; image check keeps host snug installed aspodmanthe CLI (TestHostSnugNamedPodmanIsTheCLI).docker, thenpodman-remote(policy.PodmanStubClients) on PATH, every dir for docker before any for podman-remote. Skips/snug/binand relative entries.--remote --url --connection --root --runroot --runtimeanywhere; before subcommand also docker-H --host -c --context --config, podman-remote-r -c --identity(after subcommand-cis--cpu-shares).--dry-run
link /snug/bin/podman -> /snug/lib/snug/wrapper+ wrapper bind.This sandbox: docker, at /usr/bin/docker./NEITHER;BUT <dir> is on PATH and WRITABLE from insidewhen PATH dir or client path searched first is a shadow slot.containers.podman_stub,podman_stub_client,podman_stub_client_path,podman_stub_writable(Policy.PodmanStubClient).Golden diff
internal/policy/testdata/podman-socket.bwrap.txt:--perms 0755 --ro-bind-data 14 /snug/bin/podman->--symlink /snug/lib/snug/wrapper /snug/bin/podman+--ro-bind-fd 18 /snug/lib/snug/wrapper(+/snug/lib/snugdirs, fd renumber).Red team (2 rounds, no escape)
docker-> fixed,TestPodmanStubClientNamesAWritablePATHDirectory./tmp, rw file in ro dir -> fixed,TestPodmanStubClientNamesAWritableClientPath.podman -H=tcp://10.0.0.1:2375 psreached docker while dry-run says connection flags refused -> fixed,TestRefusedFlag./snug/bin, hidden__verbs inside (all refuse; no userns,fork/exec /proc/self/exe: operation not permitted), wrapper ro/nosuid, env onlyCONTAINER_HOST/DOCKER_HOST, no fd leak.-trimpathseparate change).Tests
make gategreen.make integration: sandbox suite 61 engine tests (floor 46), all pass exceptTestOfflineHasOnlyLoopback,TestDoctorRunsCleanOnAHostThatCanRunSnug— host hasip_greloaded,fb_tunnels_only_for_init_net=0, every netns getsgre0 gretap0 erspan0(unshare -Urn ip -br linkshows same outside snug). Host state, not this change.integration-signalsgreen.make verify: 5 passed, 4 skipped, 0 failed.TestPodmanStubForwardsToDockerInsideTheSandbox,TestPodmanStubRefusesInsideTheSandbox,TestHostSnugNamedPodmanIsTheCLI.@sysexposes real/usr/bin/docker, which always wins inside.🤖 Generated with Claude Code