Skip to content

Commit 28e4618

Browse files
authored
Merge pull request from GHSA-hmfx-3pcx-653p
[release/1.5] oci: fix additional GIDs
2 parents 959e1cf + a62c38b commit 28e4618

File tree

5 files changed

+513
-69
lines changed

5 files changed

+513
-69
lines changed

Diff for: integration/addition_gids_test.go

+99-31
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package integration
2121

2222
import (
23+
"fmt"
2324
"io/ioutil"
2425
"os"
2526
"path/filepath"
@@ -47,8 +48,7 @@ func TestAdditionalGids(t *testing.T) {
4748
}()
4849

4950
var (
50-
testImage = GetImage(BusyBox)
51-
containerName = "test-container"
51+
testImage = GetImage(BusyBox)
5252
)
5353
t.Logf("Pull test image %q", testImage)
5454
img, err := imageService.PullImage(&runtime.ImageSpec{Image: testImage}, nil, sbConfig)
@@ -57,34 +57,102 @@ func TestAdditionalGids(t *testing.T) {
5757
assert.NoError(t, imageService.RemoveImage(&runtime.ImageSpec{Image: img}))
5858
}()
5959

60-
t.Log("Create a container to print id")
61-
cnConfig := ContainerConfig(
62-
containerName,
63-
testImage,
64-
WithCommand("id"),
65-
WithLogPath(containerName),
66-
WithSupplementalGroups([]int64{1 /*daemon*/, 1234 /*new group*/}),
67-
)
68-
cn, err := runtimeService.CreateContainer(sb, cnConfig, sbConfig)
69-
require.NoError(t, err)
60+
type testCase struct {
61+
description string
62+
opts []ContainerOpts
63+
expected string
64+
}
65+
66+
testCases := []testCase{
67+
{
68+
description: "Equivalent of `docker run` (no option)",
69+
opts: nil,
70+
expected: "groups=0(root),10(wheel)",
71+
},
72+
{
73+
description: "Equivalent of `docker run --group-add 1 --group-add 1234`",
74+
opts: []ContainerOpts{WithSupplementalGroups([]int64{1 /*daemon*/, 1234 /*new group*/})},
75+
expected: "groups=0(root),1(daemon),10(wheel),1234",
76+
},
77+
{
78+
description: "Equivalent of `docker run --user 1234`",
79+
opts: []ContainerOpts{WithRunAsUser(1234)},
80+
expected: "groups=0(root)",
81+
},
82+
{
83+
description: "Equivalent of `docker run --user 1234:1234`",
84+
opts: []ContainerOpts{WithRunAsUser(1234), WithRunAsGroup(1234)},
85+
expected: "groups=1234",
86+
},
87+
{
88+
description: "Equivalent of `docker run --user 1234 --group-add 1234`",
89+
opts: []ContainerOpts{WithRunAsUser(1234), WithSupplementalGroups([]int64{1234})},
90+
expected: "groups=0(root),1234",
91+
},
92+
{
93+
description: "Equivalent of `docker run --user daemon` (Supported by CRI, although unsupported by kube-apiserver)",
94+
opts: []ContainerOpts{WithRunAsUsername("daemon")},
95+
expected: "groups=1(daemon)",
96+
},
97+
{
98+
description: "Equivalent of `docker run --user daemon --group-add 1234` (Supported by CRI, although unsupported by kube-apiserver)",
99+
opts: []ContainerOpts{WithRunAsUsername("daemon"), WithSupplementalGroups([]int64{1234})},
100+
expected: "groups=1(daemon),1234",
101+
},
102+
}
103+
104+
for i, tc := range testCases {
105+
i, tc := i, tc
106+
tBasename := fmt.Sprintf("case-%d", i)
107+
t.Run(tBasename, func(t *testing.T) {
108+
t.Log(tc.description)
109+
t.Logf("Expected=%q", tc.expected)
110+
111+
testPodLogDir := t.TempDir()
112+
113+
t.Log("Create a sandbox with log directory")
114+
sbConfig := PodSandboxConfig("sandbox", tBasename,
115+
WithPodLogDirectory(testPodLogDir))
116+
sb, err := runtimeService.RunPodSandbox(sbConfig, *runtimeHandler)
117+
require.NoError(t, err)
118+
defer func() {
119+
assert.NoError(t, runtimeService.StopPodSandbox(sb))
120+
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
121+
}()
122+
123+
t.Log("Create a container to print id")
124+
containerName := tBasename
125+
cnConfig := ContainerConfig(
126+
containerName,
127+
testImage,
128+
append(
129+
[]ContainerOpts{
130+
WithCommand("id"),
131+
WithLogPath(containerName),
132+
}, tc.opts...)...,
133+
)
134+
cn, err := runtimeService.CreateContainer(sb, cnConfig, sbConfig)
135+
require.NoError(t, err)
136+
137+
t.Log("Start the container")
138+
require.NoError(t, runtimeService.StartContainer(cn))
139+
140+
t.Log("Wait for container to finish running")
141+
require.NoError(t, Eventually(func() (bool, error) {
142+
s, err := runtimeService.ContainerStatus(cn)
143+
if err != nil {
144+
return false, err
145+
}
146+
if s.GetState() == runtime.ContainerState_CONTAINER_EXITED {
147+
return true, nil
148+
}
149+
return false, nil
150+
}, time.Second, 30*time.Second))
70151

71-
t.Log("Start the container")
72-
require.NoError(t, runtimeService.StartContainer(cn))
73-
74-
t.Log("Wait for container to finish running")
75-
require.NoError(t, Eventually(func() (bool, error) {
76-
s, err := runtimeService.ContainerStatus(cn)
77-
if err != nil {
78-
return false, err
79-
}
80-
if s.GetState() == runtime.ContainerState_CONTAINER_EXITED {
81-
return true, nil
82-
}
83-
return false, nil
84-
}, time.Second, 30*time.Second))
85-
86-
t.Log("Search additional groups in container log")
87-
content, err := ioutil.ReadFile(filepath.Join(testPodLogDir, containerName))
88-
assert.NoError(t, err)
89-
assert.Contains(t, string(content), "groups=1(daemon),10(wheel),1234")
152+
t.Log("Search additional groups in container log")
153+
content, err := os.ReadFile(filepath.Join(testPodLogDir, containerName))
154+
assert.NoError(t, err)
155+
assert.Contains(t, string(content), tc.expected+"\n")
156+
})
157+
}
90158
}

Diff for: integration/main_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,45 @@ func WithLogPath(path string) ContainerOpts {
256256
}
257257
}
258258

259+
// WithRunAsUser sets the uid.
260+
func WithRunAsUser(uid int64) ContainerOpts {
261+
return func(c *runtime.ContainerConfig) {
262+
if c.Linux == nil {
263+
c.Linux = &runtime.LinuxContainerConfig{}
264+
}
265+
if c.Linux.SecurityContext == nil {
266+
c.Linux.SecurityContext = &runtime.LinuxContainerSecurityContext{}
267+
}
268+
c.Linux.SecurityContext.RunAsUser = &runtime.Int64Value{Value: uid}
269+
}
270+
}
271+
272+
// WithRunAsUsername sets the username.
273+
func WithRunAsUsername(username string) ContainerOpts {
274+
return func(c *runtime.ContainerConfig) {
275+
if c.Linux == nil {
276+
c.Linux = &runtime.LinuxContainerConfig{}
277+
}
278+
if c.Linux.SecurityContext == nil {
279+
c.Linux.SecurityContext = &runtime.LinuxContainerSecurityContext{}
280+
}
281+
c.Linux.SecurityContext.RunAsUsername = username
282+
}
283+
}
284+
285+
// WithRunAsGroup sets the gid.
286+
func WithRunAsGroup(gid int64) ContainerOpts {
287+
return func(c *runtime.ContainerConfig) {
288+
if c.Linux == nil {
289+
c.Linux = &runtime.LinuxContainerConfig{}
290+
}
291+
if c.Linux.SecurityContext == nil {
292+
c.Linux.SecurityContext = &runtime.LinuxContainerSecurityContext{}
293+
}
294+
c.Linux.SecurityContext.RunAsGroup = &runtime.Int64Value{Value: gid}
295+
}
296+
}
297+
259298
// WithSupplementalGroups adds supplemental groups.
260299
func WithSupplementalGroups(gids []int64) ContainerOpts {
261300
return func(c *runtime.ContainerConfig) {

0 commit comments

Comments
 (0)