oci: fix additional GIDs
Test suite:
```yaml
---
apiVersion: v1
kind: Pod
metadata:
name: test-no-option
annotations:
description: "Equivalent of `docker run` (no option)"
spec:
restartPolicy: Never
containers:
- name: main
image: ghcr.io/containerd/busybox:1.28
args: ['sh', '-euxc',
'[ "$(id)" = "uid=0(root) gid=0(root) groups=0(root),10(wheel)" ]']
---
apiVersion: v1
kind: Pod
metadata:
name: test-group-add-1-group-add-1234
annotations:
description: "Equivalent of `docker run --group-add 1 --group-add 1234`"
spec:
restartPolicy: Never
containers:
- name: main
image: ghcr.io/containerd/busybox:1.28
args: ['sh', '-euxc',
'[ "$(id)" = "uid=0(root) gid=0(root) groups=0(root),1(daemon),10(wheel),1234" ]']
securityContext:
supplementalGroups: [1, 1234]
---
apiVersion: v1
kind: Pod
metadata:
name: test-user-1234
annotations:
description: "Equivalent of `docker run --user 1234`"
spec:
restartPolicy: Never
containers:
- name: main
image: ghcr.io/containerd/busybox:1.28
args: ['sh', '-euxc',
'[ "$(id)" = "uid=1234 gid=0(root) groups=0(root)" ]']
securityContext:
runAsUser: 1234
---
apiVersion: v1
kind: Pod
metadata:
name: test-user-1234-1234
annotations:
description: "Equivalent of `docker run --user 1234:1234`"
spec:
restartPolicy: Never
containers:
- name: main
image: ghcr.io/containerd/busybox:1.28
args: ['sh', '-euxc',
'[ "$(id)" = "uid=1234 gid=1234 groups=1234" ]']
securityContext:
runAsUser: 1234
runAsGroup: 1234
---
apiVersion: v1
kind: Pod
metadata:
name: test-user-1234-group-add-1234
annotations:
description: "Equivalent of `docker run --user 1234 --group-add 1234`"
spec:
restartPolicy: Never
containers:
- name: main
image: ghcr.io/containerd/busybox:1.28
args: ['sh', '-euxc',
'[ "$(id)" = "uid=1234 gid=0(root) groups=0(root),1234" ]']
securityContext:
runAsUser: 1234
supplementalGroups: [1234]
```
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
@@ -121,6 +121,17 @@ func setCapabilities(s *Spec) {
|
||||
}
|
||||
}
|
||||
|
||||
// ensureAdditionalGids ensures that the primary GID is also included in the additional GID list.
|
||||
func ensureAdditionalGids(s *Spec) {
|
||||
setProcess(s)
|
||||
for _, f := range s.Process.User.AdditionalGids {
|
||||
if f == s.Process.User.GID {
|
||||
return
|
||||
}
|
||||
}
|
||||
s.Process.User.AdditionalGids = append([]uint32{s.Process.User.GID}, s.Process.User.AdditionalGids...)
|
||||
}
|
||||
|
||||
// WithDefaultSpec returns a SpecOpts that will populate the spec with default
|
||||
// values.
|
||||
//
|
||||
@@ -586,7 +597,9 @@ func WithNamespacedCgroup() SpecOpts {
|
||||
// user, uid, user:group, uid:gid, uid:group, user:gid
|
||||
func WithUser(userstr string) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) error {
|
||||
defer ensureAdditionalGids(s)
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
|
||||
// For LCOW it's a bit harder to confirm that the user actually exists on the host as a rootfs isn't
|
||||
// mounted on the host and shared into the guest, but rather the rootfs is constructed entirely in the
|
||||
@@ -679,7 +692,9 @@ func WithUser(userstr string) SpecOpts {
|
||||
// WithUIDGID allows the UID and GID for the Process to be set
|
||||
func WithUIDGID(uid, gid uint32) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
defer ensureAdditionalGids(s)
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
s.Process.User.UID = uid
|
||||
s.Process.User.GID = gid
|
||||
return nil
|
||||
@@ -692,7 +707,9 @@ func WithUIDGID(uid, gid uint32) SpecOpts {
|
||||
// additionally sets the gid to 0, and does not return an error.
|
||||
func WithUserID(uid uint32) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
|
||||
defer ensureAdditionalGids(s)
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
setUser := func(root string) error {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
return u.Uid == int(uid)
|
||||
@@ -738,7 +755,9 @@ func WithUserID(uid uint32) SpecOpts {
|
||||
// the container.
|
||||
func WithUsername(username string) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
|
||||
defer ensureAdditionalGids(s)
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
if s.Linux != nil {
|
||||
setUser := func(root string) error {
|
||||
user, err := UserFromPath(root, func(u user.User) bool {
|
||||
@@ -789,7 +808,9 @@ func WithAdditionalGIDs(userstr string) SpecOpts {
|
||||
return nil
|
||||
}
|
||||
setProcess(s)
|
||||
s.Process.User.AdditionalGids = nil
|
||||
setAdditionalGids := func(root string) error {
|
||||
defer ensureAdditionalGids(s)
|
||||
var username string
|
||||
uid, err := strconv.Atoi(userstr)
|
||||
if err == nil {
|
||||
@@ -860,6 +881,7 @@ func WithAppendAdditionalGroups(groups ...string) SpecOpts {
|
||||
}
|
||||
setProcess(s)
|
||||
setAdditionalGids := func(root string) error {
|
||||
defer ensureAdditionalGids(s)
|
||||
gpath, err := fs.RootPath(root, "/etc/group")
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -180,23 +180,23 @@ sys:x:3:root,bin,adm
|
||||
}{
|
||||
{
|
||||
user: "root",
|
||||
expected: []uint32{1, 2, 3},
|
||||
expected: []uint32{0, 1, 2, 3},
|
||||
},
|
||||
{
|
||||
user: "1000",
|
||||
expected: nil,
|
||||
expected: []uint32{0},
|
||||
},
|
||||
{
|
||||
user: "bin",
|
||||
expected: []uint32{2, 3},
|
||||
expected: []uint32{0, 2, 3},
|
||||
},
|
||||
{
|
||||
user: "bin:root",
|
||||
expected: []uint32{},
|
||||
expected: []uint32{0},
|
||||
},
|
||||
{
|
||||
user: "daemon",
|
||||
expected: []uint32{1},
|
||||
expected: []uint32{0, 1},
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
@@ -461,8 +461,9 @@ daemon:x:2:root,bin,daemon
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "no additional gids",
|
||||
groups: []string{},
|
||||
name: "no additional gids",
|
||||
groups: []string{},
|
||||
expected: []uint32{0},
|
||||
},
|
||||
{
|
||||
name: "no additional gids, append root gid",
|
||||
@@ -472,7 +473,7 @@ daemon:x:2:root,bin,daemon
|
||||
{
|
||||
name: "no additional gids, append bin and daemon gids",
|
||||
groups: []string{"bin", "daemon"},
|
||||
expected: []uint32{1, 2},
|
||||
expected: []uint32{0, 1, 2},
|
||||
},
|
||||
{
|
||||
name: "has root additional gids, append bin and daemon gids",
|
||||
@@ -483,12 +484,13 @@ daemon:x:2:root,bin,daemon
|
||||
{
|
||||
name: "append group id",
|
||||
groups: []string{"999"},
|
||||
expected: []uint32{999},
|
||||
expected: []uint32{0, 999},
|
||||
},
|
||||
{
|
||||
name: "unknown group",
|
||||
groups: []string{"unknown"},
|
||||
err: "unable to find group unknown",
|
||||
name: "unknown group",
|
||||
groups: []string{"unknown"},
|
||||
err: "unable to find group unknown",
|
||||
expected: []uint32{0},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user