diff --git a/pkg/kubelet/rkt/fake_rkt_interface_test.go b/pkg/kubelet/rkt/fake_rkt_interface_test.go index 65cd726e98a..6de54564edc 100644 --- a/pkg/kubelet/rkt/fake_rkt_interface_test.go +++ b/pkg/kubelet/rkt/fake_rkt_interface_test.go @@ -175,6 +175,10 @@ func (f *fakeRuntimeHelper) GetPodDir(podUID types.UID) string { return "/poddir/" + string(podUID) } +func (f *fakeRuntimeHelper) GetExtraSupplementalGroupsForPod(pod *api.Pod) []int64 { + return nil +} + type fakeRktCli struct { sync.Mutex cmds []string diff --git a/pkg/kubelet/rkt/rkt.go b/pkg/kubelet/rkt/rkt.go index 2cfbe2e0d80..279c1ba8ff5 100644 --- a/pkg/kubelet/rkt/rkt.go +++ b/pkg/kubelet/rkt/rkt.go @@ -510,9 +510,11 @@ func verifyNonRoot(app *appctypes.App, ctx *api.SecurityContext) error { return nil } -func setSupplementaryGIDs(app *appctypes.App, podCtx *api.PodSecurityContext) { - if podCtx != nil { +func setSupplementalGIDs(app *appctypes.App, podCtx *api.PodSecurityContext, supplementalGids []int64) { + if podCtx != nil || len(supplementalGids) != 0 { app.SupplementaryGIDs = app.SupplementaryGIDs[:0] + } + if podCtx != nil { for _, v := range podCtx.SupplementalGroups { app.SupplementaryGIDs = append(app.SupplementaryGIDs, int(v)) } @@ -520,10 +522,13 @@ func setSupplementaryGIDs(app *appctypes.App, podCtx *api.PodSecurityContext) { app.SupplementaryGIDs = append(app.SupplementaryGIDs, int(*podCtx.FSGroup)) } } + for _, v := range supplementalGids { + app.SupplementaryGIDs = append(app.SupplementaryGIDs, int(v)) + } } // setApp merges the container spec with the image's manifest. -func setApp(imgManifest *appcschema.ImageManifest, c *api.Container, opts *kubecontainer.RunContainerOptions, ctx *api.SecurityContext, podCtx *api.PodSecurityContext) error { +func setApp(imgManifest *appcschema.ImageManifest, c *api.Container, opts *kubecontainer.RunContainerOptions, ctx *api.SecurityContext, podCtx *api.PodSecurityContext, supplementalGids []int64) error { app := imgManifest.App // Set up Exec. @@ -564,7 +569,7 @@ func setApp(imgManifest *appcschema.ImageManifest, c *api.Container, opts *kubec if ctx != nil && ctx.RunAsUser != nil { app.User = strconv.Itoa(int(*ctx.RunAsUser)) } - setSupplementaryGIDs(app, podCtx) + setSupplementalGIDs(app, podCtx, supplementalGids) // If 'User' or 'Group' are still empty at this point, // then apply the root UID and GID. @@ -806,8 +811,9 @@ func (r *Runtime) newAppcRuntimeApp(pod *api.Pod, podIP string, c api.Container, }) } + supplementalGids := r.runtimeHelper.GetExtraSupplementalGroupsForPod(pod) ctx := securitycontext.DetermineEffectiveSecurityContext(pod, &c) - if err := setApp(imgManifest, &c, opts, ctx, pod.Spec.SecurityContext); err != nil { + if err := setApp(imgManifest, &c, opts, ctx, pod.Spec.SecurityContext, supplementalGids); err != nil { return err } diff --git a/pkg/kubelet/rkt/rkt_test.go b/pkg/kubelet/rkt/rkt_test.go index e665a86da88..bab2eb431dc 100644 --- a/pkg/kubelet/rkt/rkt_test.go +++ b/pkg/kubelet/rkt/rkt_test.go @@ -940,21 +940,23 @@ func TestSetApp(t *testing.T) { fsgid := int64(3) tests := []struct { - container *api.Container - opts *kubecontainer.RunContainerOptions - ctx *api.SecurityContext - podCtx *api.PodSecurityContext - expect *appctypes.App - err error + container *api.Container + opts *kubecontainer.RunContainerOptions + ctx *api.SecurityContext + podCtx *api.PodSecurityContext + supplementalGids []int64 + expect *appctypes.App + err error }{ // Nothing should change, but the "User" and "Group" should be filled. { - container: &api.Container{}, - opts: &kubecontainer.RunContainerOptions{}, - ctx: nil, - podCtx: nil, - expect: baseAppWithRootUserGroup(t), - err: nil, + container: &api.Container{}, + opts: &kubecontainer.RunContainerOptions{}, + ctx: nil, + podCtx: nil, + supplementalGids: nil, + expect: baseAppWithRootUserGroup(t), + err: nil, }, // error verifying non-root. @@ -965,9 +967,10 @@ func TestSetApp(t *testing.T) { RunAsNonRoot: &runAsNonRootTrue, RunAsUser: &rootUser, }, - podCtx: nil, - expect: nil, - err: fmt.Errorf("container has no runAsUser and image will run as root"), + podCtx: nil, + supplementalGids: nil, + expect: nil, + err: fmt.Errorf("container has no runAsUser and image will run as root"), }, // app's args should be changed. @@ -975,9 +978,10 @@ func TestSetApp(t *testing.T) { container: &api.Container{ Args: []string{"foo"}, }, - opts: &kubecontainer.RunContainerOptions{}, - ctx: nil, - podCtx: nil, + opts: &kubecontainer.RunContainerOptions{}, + ctx: nil, + podCtx: nil, + supplementalGids: nil, expect: &appctypes.App{ Exec: appctypes.Exec{"/bin/foo", "foo"}, User: "0", @@ -1036,11 +1040,12 @@ func TestSetApp(t *testing.T) { SupplementalGroups: []int64{1, 2}, FSGroup: &fsgid, }, + supplementalGids: []int64{4}, expect: &appctypes.App{ Exec: appctypes.Exec{"/bin/bar", "foo"}, User: "42", Group: "0", - SupplementaryGIDs: []int{1, 2, 3}, + SupplementaryGIDs: []int{1, 2, 3, 4}, WorkingDirectory: tmpDir, Environment: []appctypes.EnvironmentVariable{ {"env-foo", "bar"}, @@ -1099,11 +1104,12 @@ func TestSetApp(t *testing.T) { SupplementalGroups: []int64{1, 2}, FSGroup: &fsgid, }, + supplementalGids: []int64{4}, expect: &appctypes.App{ Exec: appctypes.Exec{"/bin/hello", "foo", "hello", "world", "bar"}, User: "42", Group: "0", - SupplementaryGIDs: []int{1, 2, 3}, + SupplementaryGIDs: []int{1, 2, 3, 4}, WorkingDirectory: tmpDir, Environment: []appctypes.EnvironmentVariable{ {"env-foo", "foo"}, @@ -1128,7 +1134,7 @@ func TestSetApp(t *testing.T) { for i, tt := range tests { testCaseHint := fmt.Sprintf("test case #%d", i) img := baseImageManifest(t) - err := setApp(img, tt.container, tt.opts, tt.ctx, tt.podCtx) + err := setApp(img, tt.container, tt.opts, tt.ctx, tt.podCtx, tt.supplementalGids) if err == nil && tt.err != nil || err != nil && tt.err == nil { t.Errorf("%s: expect %v, saw %v", testCaseHint, tt.err, err) }