Skip to content

fix(privilege): keep the root group when dropping to an unprivileged workload#17

Draft
jansav wants to merge 1 commit into
mainfrom
fix/privilege-keep-root-group
Draft

fix(privilege): keep the root group when dropping to an unprivileged workload#17
jansav wants to merge 1 commit into
mainfrom
fix/privilege-keep-root-group

Conversation

@jansav

@jansav jansav commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Both privilege-drop paths cleared all supplementary groups before setgid/setuid (setgroups(&[])), so a workload dropped to an arbitrary non-root uid had no group-0 membership.

Images built for the "run as an arbitrary non-root uid that belongs to the root group (gid 0)" model (bitnami, OpenShift) own their writable dirs root:0 with group-write and expect the process to be in group 0. Without it they can't write — e.g. bitnami/wordpress as uid 1001:

mkdir: cannot create directory '/opt/bitnami/apache/conf/bitnami/certs': Permission denied
drwxrwxr-x  0/0  /opt/bitnami/apache/conf/bitnami     # root:0, group-writable

Change

Keep the root group (gid 0) as the dropped workload's sole supplementary group: setgroups(&[Gid::from_raw(ROOT_GID)]) in both drop paths — privilege::apply (piped) and pty::spawn_pty (PTY) — sharing a ROOT_GID const so the two can't drift. The supervisor's own supplementary groups are still dropped (only gid 0 is kept), preserving fail-closed behavior otherwise.

Note for reviewers

There are two independent drop paths and interactive (-i -t) runs use the PTY path — easy to fix one and miss the other. Verified both end-to-end:

lns run --sandbox-uid 1001 --sandbox-user 1001 alpine -- id
# uid=1001(1001) gid=1001(1001) groups=0(root)

Tests: 447 pass, clippy clean.

Downstream

Consumed by lens-sandbox (lns) via the pinned lens-sandbox-core rev; a follow-up there bumps the rev once this lands. Surfaced while validating a real multi-tier OCI workload (bitnami/wordpress).

Closes #15.

…workload

Both privilege-drop paths cleared all supplementary groups before
setgid/setuid (setgroups(&[])), so a workload dropped to an arbitrary
non-root uid had no group-0 membership. Images built for the "run as an
arbitrary non-root uid that belongs to the root group" model (bitnami,
OpenShift) own their writable dirs root:0 with group-write and expect the
process to be in group 0 — so they fail to write (e.g. bitnami's
/opt/bitnami tree: mkdir .../bitnami/certs -> Permission denied).

Keep the root group (gid 0) as the dropped workload's sole supplementary
group in both the piped path (privilege::apply) and the PTY path
(pty::spawn_pty), sharing a ROOT_GID const so the two can't drift.
@jansav jansav marked this pull request as draft June 8, 2026 04:59
@jansav jansav requested a review from jakolehm June 8, 2026 06:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Privilege drop clears supplementary groups; arbitrary-uid-in-root-group images (bitnami/OpenShift) can't write group-0 dirs

1 participant