Skip to content

Commit 9cdc70a

Browse files
authored
Merge pull request moby#3651 from AkihiroSuda/fix-additional-gids
Ensures that the primary GID is also included in the additional GIDs
2 parents 39964a6 + a0ef27c commit 9cdc70a

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

executor/oci/user.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func parseUID(str string) (uint32, error) {
9191
// once the PR in containerd is merged we should remove this function.
9292
func WithUIDGID(uid, gid uint32, sgids []uint32) containerdoci.SpecOpts {
9393
return func(_ context.Context, _ containerdoci.Client, _ *containers.Container, s *containerdoci.Spec) error {
94+
defer ensureAdditionalGids(s)
9495
setProcess(s)
9596
s.Process.User.UID = uid
9697
s.Process.User.GID = gid
@@ -106,3 +107,15 @@ func setProcess(s *containerdoci.Spec) {
106107
s.Process = &specs.Process{}
107108
}
108109
}
110+
111+
// ensureAdditionalGids ensures that the primary GID is also included in the additional GID list.
112+
// From https://github.com/containerd/containerd/blob/v1.7.0-beta.4/oci/spec_opts.go#L124-L133
113+
func ensureAdditionalGids(s *containerdoci.Spec) {
114+
setProcess(s)
115+
for _, f := range s.Process.User.AdditionalGids {
116+
if f == s.Process.User.GID {
117+
return
118+
}
119+
}
120+
s.Process.User.AdditionalGids = append([]uint32{s.Process.User.GID}, s.Process.User.AdditionalGids...)
121+
}

frontend/dockerfile/dockerfile_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ var allTests = integration.TestFuncs(
7171
testExportedHistory,
7272
testExposeExpansion,
7373
testUser,
74+
testUserAdditionalGids,
7475
testCacheReleased,
7576
testDockerignore,
7677
testDockerignoreInvalid,
@@ -3005,6 +3006,43 @@ USER nobody
30053006
require.Equal(t, "nobody", ociimg.Config.User)
30063007
}
30073008

3009+
// testUserAdditionalGids ensures that that the primary GID is also included in the additional GID list.
3010+
// CVE-2023-25173: https://github.com/advisories/GHSA-hmfx-3pcx-653p
3011+
func testUserAdditionalGids(t *testing.T, sb integration.Sandbox) {
3012+
f := getFrontend(t, sb)
3013+
3014+
dockerfile := []byte(`
3015+
# Mimics the tests in https://github.com/containerd/containerd/commit/3eda46af12b1deedab3d0802adb2e81cb3521950
3016+
FROM busybox
3017+
SHELL ["/bin/sh", "-euxc"]
3018+
RUN [ "$(id)" = "uid=0(root) gid=0(root) groups=0(root),10(wheel)" ]
3019+
USER 1234
3020+
RUN [ "$(id)" = "uid=1234 gid=0(root) groups=0(root)" ]
3021+
USER 1234:1234
3022+
RUN [ "$(id)" = "uid=1234 gid=1234 groups=1234" ]
3023+
USER daemon
3024+
RUN [ "$(id)" = "uid=1(daemon) gid=1(daemon) groups=1(daemon)" ]
3025+
`)
3026+
3027+
dir, err := integration.Tmpdir(
3028+
t,
3029+
fstest.CreateFile("Dockerfile", dockerfile, 0600),
3030+
)
3031+
require.NoError(t, err)
3032+
3033+
c, err := client.New(sb.Context(), sb.Address())
3034+
require.NoError(t, err)
3035+
defer c.Close()
3036+
3037+
_, err = f.Solve(sb.Context(), c, client.SolveOpt{
3038+
LocalDirs: map[string]string{
3039+
dockerui.DefaultLocalNameDockerfile: dir,
3040+
dockerui.DefaultLocalNameContext: dir,
3041+
},
3042+
}, nil)
3043+
require.NoError(t, err)
3044+
}
3045+
30083046
func testCopyChown(t *testing.T, sb integration.Sandbox) {
30093047
f := getFrontend(t, sb)
30103048

0 commit comments

Comments
 (0)