Actor rootfs `/` is mode 0700, so non-root users cannot traverse the root filesystem
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- go, linux
- Domain
- operating-systems
Research direction
Start in internal/imagecache/bundle_linux.go:61-66 and inspect how rootfs, upper, and work are created before the overlay mount at line 81. Read applyDirFixups in internal/imagecache/implicitdirs.go to determine whether the merged root is handled. Done means a standard image root remains traversable by non-root users, with a regression check for the reported 0700 root behavior.
Written by the indexing model from the issue text.
Description
Summary
Inside a gVisor actor, the root directory / is root:root 0700. A workload that drops to a non-root user cannot resolve any path at all, not even /bin/sh, because the first path component is not traversable. Docker and containerd keep the image root's mode (normally 0755). As shipped, any non-root workload fails on Substrate.
Impact
- Who hits it: every integrator whose workload runs as, or switches to, a non-root user. Agent runtimes and most hardened images do this.
- What breaks:
su,runuserand any exec as a non-root uid fail withPermission denied. The workload cannot start. - Cost: each integrator has to add a root-privileged fixup at actor start.
- Severity: High.
- Proposed priority: P1. It blocks non-root workloads out of the box. A workaround exists but needs root at startup, which depends on the uid-0 start (see Workload has no
userfield or no-new-privileges setting…).
Environment
- Substrate
d277088b(v1alpha). - GKE 1.36.x.
- gVisor sandbox class, unprivileged WorkerPool workers.
Steps to reproduce / evidence
- Create the actor (verified live). Use an ActorTemplate whose image is a Debian-based image with a non-root user (for example
useradd -u 1000 agent). Create an actor from it. - Check the root mode inside the actor, as root (verified live):
$ stat -c '%a:%U:%G %n' / 700:root:root / - Switch to the non-root user (verified live):
$ su agent -s /bin/sh -c id su: failed to execute /bin/sh: Permission denied/bin/shis itself 0755. The failure is at the traversal of/. - Show that a 0755 root is sufficient (verified live). After
chmod 755 /(as root),suandrunuserto the non-root uid both succeed. The same test also chowned the user's home directory; the exec itself (su … -c id) depends only on/being traversable. - Cause (code-read at
d277088b):internal/imagecache/bundle_linux.go:61-66creates<bundle>/rootfs,upperandworkwithos.MkdirAll(d, 0o700).- The overlay is then mounted at
rootfswith that upperdir (bundle_linux.go:81). - The merged overlay root takes its attributes from the upperdir root.
applyDirFixupsininternal/imagecache/implicitdirs.gorepairs implicit parent directories. It does not appear to cover/itself.
Expected vs actual
- Expected: the actor's
/has the image root's mode (0755 for standard base images), as under Docker, containerd and Kubernetes. - Actual:
/is 0700 and owned by root. No non-root uid can traverse it.
Workaround
At actor start, while still uid 0, an integrator can:
chmod 755 /if/is more restrictive than that.- Check that the workload user can traverse the rootfs (for example that
/bin/shresolves). - Fail closed if it cannot.
This only works because the workload starts as root.
Additional detail
- Suggested fix: create the bundle rootfs/upperdir root with 0755, or copy the image root's mode onto it after the overlay is mounted.
- Related issues (same class, image metadata lost in the actor rootfs):
- Image-layer file ownership appears as uid 0 inside the actor (
image-layer-file-ownership-lost.md). - Actor rootfs drops setuid, setgid and sticky bits from image layers (
/tmpis 0777) (actor-rootfs-drops-special-mode-bits.md).
- Image-layer file ownership appears as uid 0 inside the actor (
- Dominant language
- Go
- Stars
- 4.4k
- Forks
- 515
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 295
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from agent-substrate/substrate
-
Router dynamic xDS gRPC control plane runs plaintext on 0.0.0.0:18000Possibly taken @LiorLieberman claimed this 1 day ago. Openarea/network area/security kind/bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
agent-substrate/substrate#2276 · 1 comment · 1 assignee ·
Maintainers usually reply within 1 day
-
area/network kind/bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
agent-substrate/substrate#2245 ·
Maintainers usually reply within 1 day
-
[Bug]: e2e script flag parsing is brokenPossibly taken @ericcurtin claimed this 3 days ago. Openarea/dev-infra area/tests kind/bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
agent-substrate/substrate#2217 · 1 comment ·
Maintainers usually reply within 1 day
-
Reject trailing YAML documents in actor-template create manifestsPossibly taken @ericcurtin claimed this 5 days ago. Openarea/cli kind/bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
agent-substrate/substrate#2156 · 1 comment ·
Maintainers usually reply within 1 day
-
area/storage kind/bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
agent-substrate/substrate#2155 · 1 comment ·
Maintainers usually reply within 1 day
All issues in agent-substrate/substrate
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
-
[Chore] Remove dead AutogenV2 feature flagPossibly taken @geeknishantkyeus claimed this today. Openbug triage
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
kyverno/kyverno#17936 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100