You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A host file that is group-readable to a group the invoking user belongs to cannot be read inside the
sandbox, and --ro-binding it explicitly does not help. The file lists as nobody:nogroup, which
reads as a failed mount or changed ownership, so the obvious next moves — re-check the mount, re-check
the host permissions, reboot — all investigate the wrong thing.
Concretely: a service credential at /etc/foo/credentials.yaml, mode 0640, owner root:foo, with
the user a member of foo. Readable outside, EACCES inside.
Root cause
The user namespace maps exactly one uid and one gid, each of length 1 — the invoking user's.
Every other host id, including gid foo, is unmapped.
stat() has no in-namespace number for an unmapped owner, so it reports /proc/sys/kernel/overflowuid and overflowgid — both 65534, which resolve by name to nobody and nogroup. The display is purely cosmetic, but it is indistinguishable from a real
ownership problem.
/proc/self/setgroups is deny, so supplementary groups cannot be acquired in the namespace. id -G returns only the mapped gid and the overflow gid, so the user's real membership of foo
is unusable for permission checks.
--ro on the file changes where the inode is visible, not the ids it carries, and the access
check uses the real ids. So an explicit bind looks like it should fix this and cannot.
/etc/group is visible and getent group foo correctly lists the user as a member. Everything
therefore looks correctly configured from inside the sandbox, which is what makes the
misdiagnosis stick.
but for group membership rather than root-owned files. There the failure was a loud error naming the
file; here it is a bare EACCES behind an owner display that points elsewhere.
Evidence
/etc/foo/credentials.yaml, mode 0640, owner root:foo, user in group foo:
Condition
ls -l shows
read
outside sandbox
root foo
ok
in sandbox, no extra mount
nobody nogroup
EACCES
in sandbox, --ro /etc/foo/credentials.yaml
nobody nogroup
EACCES
The owner display is identical in both failing cases and gives no hint that the cause is the gid map
rather than the mount.
Not verified, and stated as prediction rather than evidence: mode 0644 on the host file, or a copy
owned by the invoking uid, should both read fine — the first via the other bits, the second via the
one mapped uid. That follows from the permission model above but was not run before the sandbox in
question was gone.
Fix directions
Tightest first:
Warn when a path given to --ro/--rw is not readable with the sandboxed credentials. Cheap,
no privilege needed, and it turns a silent EACCES plus a misleading owner into a pointer at the
actual cause. This alone would have been sufficient here.
Document that group-based access does not survive the namespace: only the invoking uid and the other bits work. Worth stating next to --ro/--rw, since binding a path is exactly the moment
the assumption gets made.
An --allow-groups flag mapping the invoking user's supplementary gids into the namespace, to fit
the existing --allow-* taxonomy. Note this needs setgroups not to be deny and a wider gid_map, which may not be reachable unprivileged — worth confirming before promising it.
Summary
A host file that is group-readable to a group the invoking user belongs to cannot be read inside the
sandbox, and
--ro-binding it explicitly does not help. The file lists asnobody:nogroup, whichreads as a failed mount or changed ownership, so the obvious next moves — re-check the mount, re-check
the host permissions, reboot — all investigate the wrong thing.
Concretely: a service credential at
/etc/foo/credentials.yaml, mode0640, ownerroot:foo, withthe user a member of
foo. Readable outside,EACCESinside.Root cause
The user namespace maps exactly one uid and one gid, each of length 1 — the invoking user's.
Every other host id, including gid
foo, is unmapped.stat()has no in-namespace number for an unmapped owner, so it reports/proc/sys/kernel/overflowuidandoverflowgid— both65534, which resolve by name tonobodyandnogroup. The display is purely cosmetic, but it is indistinguishable from a realownership problem.
/proc/self/setgroupsisdeny, so supplementary groups cannot be acquired in the namespace.id -Greturns only the mapped gid and the overflow gid, so the user's real membership offoois unusable for permission checks.
--roon the file changes where the inode is visible, not the ids it carries, and the accesscheck uses the real ids. So an explicit bind looks like it should fix this and cannot.
/etc/groupis visible andgetent group foocorrectly lists the user as a member. Everythingtherefore looks correctly configured from inside the sandbox, which is what makes the
misdiagnosis stick.
Same unmapped-id mechanism as
but for group membership rather than root-owned files. There the failure was a loud error naming the
file; here it is a bare
EACCESbehind an owner display that points elsewhere.Evidence
/etc/foo/credentials.yaml, mode0640, ownerroot:foo, user in groupfoo:ls -lshowsroot foonobody nogroupEACCES--ro /etc/foo/credentials.yamlnobody nogroupEACCESThe owner display is identical in both failing cases and gives no hint that the cause is the gid map
rather than the mount.
Not verified, and stated as prediction rather than evidence: mode
0644on the host file, or a copyowned by the invoking uid, should both read fine — the first via the
otherbits, the second via theone mapped uid. That follows from the permission model above but was not run before the sandbox in
question was gone.
Fix directions
Tightest first:
--ro/--rwis not readable with the sandboxed credentials. Cheap,no privilege needed, and it turns a silent
EACCESplus a misleading owner into a pointer at theactual cause. This alone would have been sufficient here.
otherbits work. Worth stating next to--ro/--rw, since binding a path is exactly the momentthe assumption gets made.
--allow-groupsflag mapping the invoking user's supplementary gids into the namespace, to fitthe existing
--allow-*taxonomy. Note this needssetgroupsnot to bedenyand a widergid_map, which may not be reachable unprivileged — worth confirming before promising it.option in ssh fails in sandbox: root-owned /etc/ssh/ssh_config rejected under unmapped-uid userns #6.