@@ -54,6 +54,8 @@ SRC_URI = "\
file://0001-cli-use-external-GO111MODULE-and-cross-compiler.patch \
file://0001-dynbinary-use-go-cross-compiler.patch;patchdir=src/import \
file://0001-check-config-make-CONFIG_MEMCG_SWAP-conditional.patch;patchdir=src/import \
+ file://0001-daemon-preserve-CDI-additional-GIDs.patch;patchdir=src/import \
+ file://0002-daemon-preserve-OCI-additionalGids-for-exec.patch;patchdir=src/import \
file://CVE-2026-41568.patch;patchdir=src/import \
file://CVE-2026-42306_p1.patch;patchdir=src/import \
file://CVE-2026-42306_p2.patch;patchdir=src/import \
new file mode 100644
@@ -0,0 +1,96 @@
+From 704210f9e6d44af1501c7564c82a98653b059b7a Mon Sep 17 00:00:00 2001
+From: Evan Lezar <elezar@nvidia.com>
+Date: Fri, 8 May 2026 00:46:21 +0200
+Subject: [PATCH] daemon: preserve CDI additional GIDs
+
+CDI injection runs from WithDevices and may append supplementary groups to process.user.additionalGids. Docker's WithUser option previously ran afterwards and replaced Process.User, dropping any CDI-provided groups.
+
+Resolve the final container user before device injection so CDI edits append to that user, and add regression coverage for a CDI v0.7 spec that injects additionalGids.
+
+Upstream-Status: Backport [https://github.com/moby/moby/pull/52579]
+
+Signed-off-by: Evan Lezar <elezar@nvidia.com>
+---
+ daemon/oci_linux.go | 3 ++-
+ daemon/oci_linux_test.go | 40 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 42 insertions(+), 1 deletion(-)
+
+diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go
+index d7a8859d6be30..668891e2672d8 100644
+--- a/daemon/oci_linux.go
++++ b/daemon/oci_linux.go
+@@ -1015,6 +1015,8 @@ func (daemon *Daemon) createSpec(ctx context.Context, daemonCfg *configStore, c
+ withCgroups(daemon, &daemonCfg.Config, c),
+ WithResources(c),
+ WithSysctls(c),
++ // Set the user before CDI device injection, which may append supplementary groups.
++ WithUser(c),
+ WithDevices(daemon, c),
+ withRlimits(daemon, &daemonCfg.Config, c),
+ WithNamespaces(daemon, c),
+@@ -1025,7 +1027,6 @@ func (daemon *Daemon) createSpec(ctx context.Context, daemonCfg *configStore, c
+ WithSelinux(c),
+ WithOOMScore(&c.HostConfig.OomScoreAdj),
+ coci.WithAnnotations(c.HostConfig.Annotations),
+- WithUser(c),
+ )
+
+ if c.NoNewPrivileges {
+diff --git a/daemon/oci_linux_test.go b/daemon/oci_linux_test.go
+index 9e2c361a83a19..fa0a442a0bc18 100644
+--- a/daemon/oci_linux_test.go
++++ b/daemon/oci_linux_test.go
+@@ -2,6 +2,7 @@ package daemon
+
+ import (
+ "context"
++ "maps"
+ "os"
+ "path/filepath"
+ "slices"
+@@ -76,6 +77,45 @@ func (i *fakeImageService) StorageDriver() string {
+ return "overlay"
+ }
+
++func TestCreateSpecPreservesCDIAdditionalGIDs(t *testing.T) {
++ cdiDir := t.TempDir()
++ err := os.WriteFile(filepath.Join(cdiDir, "test-device.yaml"), []byte(`
++cdiVersion: "0.7.0"
++kind: "example.com/device"
++devices:
++- name: foo
++ containerEdits:
++ additionalGids:
++ - 1234
++`), 0o644)
++ assert.NilError(t, err)
++
++ origDeviceDrivers := maps.Clone(deviceDrivers)
++ t.Cleanup(func() {
++ deviceDrivers = origDeviceDrivers
++ })
++ RegisterCDIDriver(cdiDir)
++
++ c := &container.Container{
++ Config: &containertypes.Config{},
++ HostConfig: &containertypes.HostConfig{
++ Resources: containertypes.Resources{
++ DeviceRequests: []containertypes.DeviceRequest{
++ {
++ Driver: "cdi",
++ DeviceIDs: []string{"example.com/device=foo"},
++ },
++ },
++ },
++ },
++ }
++ d := setupFakeDaemon(t, c)
++
++ s, err := d.createSpec(t.Context(), &configStore{}, c, nil)
++ assert.NilError(t, err)
++ assert.Assert(t, slices.Contains(s.Process.User.AdditionalGids, uint32(1234)), "CDI additional GID not present in OCI spec")
++}
++
+ // TestTmpfsDevShmNoDupMount checks that a user-specified /dev/shm tmpfs
+ // mount (as in "docker run --tmpfs /dev/shm:rw,size=NNN") does not result
+ // in "Duplicate mount point" error from the engine.
new file mode 100644
@@ -0,0 +1,61 @@
+From 6a21aad6ca4fd964672fbf54dd409650a1e05110 Mon Sep 17 00:00:00 2001
+From: Kemal Rasim Sh <kshakir@qti.qualcomm.com>
+Date: Fri, 30 Oct 2026 09:02:24 +0200
+Subject: [PATCH] daemon: preserve OCI additionalGids for exec processes
+
+docker exec rebuilds user credentials using WithUser() and
+WithAdditionalGIDs(), which causes OCI Process.User.AdditionalGids
+defined during container creation to be lost.
+
+Preserve and merge the container's original AdditionalGids into the
+exec process specification so that supplemental groups injected by CDI
+or other OCI spec modifications remain available to exec sessions.
+
+Fixes a discrepancy where the container init process receives CDI
+additionalGids but processes started through docker exec do not.
+
+Upstream-Status: Submitted [https://github.com/moby/moby/pull/54104]
+
+Signed-off-by: Kemal Rasim Sh <kshakir@qti.qualcomm.com>
+---
+ daemon/exec_linux.go | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/daemon/exec_linux.go b/daemon/exec_linux.go
+index 2d2f3d82f0999..014ab2f41c1b9 100644
+--- a/daemon/exec_linux.go
++++ b/daemon/exec_linux.go
+@@ -27,6 +27,11 @@ func getUserFromContainerd(ctx context.Context, containerdCli *containerd.Client
+ return specs.User{}, err
+ }
+
++ // Preserve OCI additional groups from container creation.
++ inheritedGids := append(
++ []uint32(nil),
++ spec.Process.User.AdditionalGids...,)
++
+ opts := []coci.SpecOpts{
+ coci.WithUser(ec.User),
+ coci.WithAdditionalGIDs(ec.User),
+@@ -38,6 +43,21 @@ func getUserFromContainerd(ctx context.Context, containerdCli *containerd.Client
+ }
+ }
+
++ // Merge inherited OCI groups.
++ existing := map[uint32]struct{}{}
++
++ for _, gid := range spec.Process.User.AdditionalGids {
++ existing[gid] = struct{}{}
++ }
++
++ for _, gid := range inheritedGids {
++ if _, ok := existing[gid]; !ok {
++ spec.Process.User.AdditionalGids = append(
++ spec.Process.User.AdditionalGids,
++ gid,)
++ }
++ }
++
+ return spec.Process.User, nil
+ }
+