Skip to content

proc: implement /proc/[pid]/setgroups#13200

Open
copybara-service[bot] wants to merge 1 commit into
masterfrom
test/cl916335886
Open

proc: implement /proc/[pid]/setgroups#13200
copybara-service[bot] wants to merge 1 commit into
masterfrom
test/cl916335886

Conversation

@copybara-service
Copy link
Copy Markdown

proc: implement /proc/[pid]/setgroups

Without /proc/[pid]/setgroups the canonical rootless user-namespace setup
cannot run. The expected sequence starts by writing "deny" to
/proc/self/setgroups so that an unprivileged process can then write a
non-trivial gid_map, and that file did not exist in gVisor. Tools that
take this path, like buildah or podman, fail with ENOENT on
/proc/[pid]/setgroups before they can do any work.

I followed kernel/user_namespace.c. Each UserNamespace now carries a
setgroupsAllowed bit that is initialized true and inherited from the
parent at creation. Writing "deny" succeeds while gid_map is still empty
and clears the bit, while writing "allow" succeeds only if the bit is
still set, which preserves the one-way USERNS_SETGROUPS_ALLOWED
transition. The unprivileged branch of SetGIDMap now requires the bit to
be clear so that the behavior matches new_idmap_permitted, and
setgroups(2) is gated by the conjunction of the bit and a non-empty
gid_map, mirroring userns_may_setgroups.

Tests in test/syscalls/linux/proc_pid_uid_gid_map.cc cover the file's
read and write semantics, the one-way state transition, child-namespace
inheritance, the syscall gating before and after deny, and the gid_map
interaction. They pass on both runsc and native Linux.

Closes #1235 and removes the b/27454212 TODO that has sat in user_namespace.go since the initial commit.

FUTURE_COPYBARA_INTEGRATE_REVIEW=#13147 from shayonj:setgroups-impl 43f9528

@copybara-service copybara-service Bot added the exported Issue was exported automatically label May 16, 2026
@copybara-service copybara-service Bot force-pushed the test/cl916335886 branch 2 times, most recently from a48548d to 24f14da Compare May 16, 2026 18:55
Without /proc/[pid]/setgroups the canonical rootless user-namespace setup
cannot run. The expected sequence starts by writing "deny" to
/proc/self/setgroups so that an unprivileged process can then write a
non-trivial gid_map, and that file did not exist in gVisor. Tools that
take this path, like buildah or podman, fail with ENOENT on
/proc/[pid]/setgroups before they can do any work.

I followed kernel/user_namespace.c. Each UserNamespace now carries a
setgroupsAllowed bit that is initialized true and inherited from the
parent at creation. Writing "deny" succeeds while gid_map is still empty
and clears the bit, while writing "allow" succeeds only if the bit is
still set, which preserves the one-way USERNS_SETGROUPS_ALLOWED
transition. The unprivileged branch of SetGIDMap now requires the bit to
be clear so that the behavior matches new_idmap_permitted, and
setgroups(2) is gated by the conjunction of the bit and a non-empty
gid_map, mirroring userns_may_setgroups.

Tests in test/syscalls/linux/proc_pid_uid_gid_map.cc cover the file's
read and write semantics, the one-way state transition, child-namespace
inheritance, the syscall gating before and after deny, and the gid_map
interaction. They pass on both runsc and native Linux.

Closes #1235 and removes the b/27454212 TODO that has sat in user_namespace.go since the initial commit.

FUTURE_COPYBARA_INTEGRATE_REVIEW=#13147 from shayonj:setgroups-impl 43f9528
PiperOrigin-RevId: 916335886
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

exported Issue was exported automatically

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support disabling set_groups(2) for user namespaces

1 participant