diff mbox series

docker-moby: preserve gids during docker exec

Message ID 20261111172826.1584415-1-kshakir@las-colo41-d19-20.qualcomm.com
State New
Headers show
Series docker-moby: preserve gids during docker exec | expand

Commit Message

Kemal Rasim Sh Nov. 11, 2026, 5:28 p.m. UTC
From: Kemal Rasim Sh <kshakir@qti.qualcomm.com>

Processes started with docker exec do not inherit all
supplemental groups assigned to the container when it was
created.

When OCI additionalGids are injected through CDI or other
OCI runtime modifications, the container init process
receives the groups correctly. However, docker exec rebuilds
user credentials and drops the original additionalGids from
the OCI process specification.

As a result, exec'd processes may lose access to devices and
resources granted through supplemental group membership,
leading to inconsistent behavior within the same container.

Preserve and merge the original OCI additionalGids into the
exec process specification so that groups assigned during
container creation remain available to docker exec
processes.

Before:

  docker exec <container> cat /proc/self/status | grep Groups
  Groups: 15 44 1000

After:

  docker exec <container> cat /proc/self/status | grep Groups
  Groups: 15 44 981 987 992 993 999 1000

Signed-off-by: Kemal Rasim Sh <kshakir@qti.qualcomm.com>
---
 recipes-containers/docker/docker-moby_git.bb  |  1 +
 ...preserve-OCI-additionalGids-for-exec.patch | 61 +++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 recipes-containers/docker/files/0002-daemon-preserve-OCI-additionalGids-for-exec.patch

Comments

Khem Raj Nov. 11, 2026, 7:53 p.m. UTC | #1
Wrong ML, please send it to meta-virtualization@lists.yoctoproject.org

On Wed, Nov 11, 2026 at 10:22 AM Kemal Rasim Sh via openembedded-devel
<kshakir=las-colo41-d19-20.qualcomm.com@lists.openembedded.org> wrote:

> From: Kemal Rasim Sh <kshakir@qti.qualcomm.com>
>
> Processes started with docker exec do not inherit all
> supplemental groups assigned to the container when it was
> created.
>
> When OCI additionalGids are injected through CDI or other
> OCI runtime modifications, the container init process
> receives the groups correctly. However, docker exec rebuilds
> user credentials and drops the original additionalGids from
> the OCI process specification.
>
> As a result, exec'd processes may lose access to devices and
> resources granted through supplemental group membership,
> leading to inconsistent behavior within the same container.
>
> Preserve and merge the original OCI additionalGids into the
> exec process specification so that groups assigned during
> container creation remain available to docker exec
> processes.
>
> Before:
>
>   docker exec <container> cat /proc/self/status | grep Groups
>   Groups: 15 44 1000
>
> After:
>
>   docker exec <container> cat /proc/self/status | grep Groups
>   Groups: 15 44 981 987 992 993 999 1000
>
> Signed-off-by: Kemal Rasim Sh <kshakir@qti.qualcomm.com>
> ---
>  recipes-containers/docker/docker-moby_git.bb  |  1 +
>  ...preserve-OCI-additionalGids-for-exec.patch | 61 +++++++++++++++++++
>  2 files changed, 62 insertions(+)
>  create mode 100644
> recipes-containers/docker/files/0002-daemon-preserve-OCI-additionalGids-for-exec.patch
>
> diff --git a/recipes-containers/docker/docker-moby_git.bb
> b/recipes-containers/docker/docker-moby_git.bb
> index 271f006e..eafe7a35 100644
> --- a/recipes-containers/docker/docker-moby_git.bb
> +++ b/recipes-containers/docker/docker-moby_git.bb
> @@ -54,6 +54,7 @@ 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://0002-daemon-preserve-OCI-additionalGids-for-exec.patch;patchdir=src/import
> \
>         "
>
>  DOCKER_COMMIT = "${SRCREV_moby}"
> diff --git
> a/recipes-containers/docker/files/0002-daemon-preserve-OCI-additionalGids-for-exec.patch
> b/recipes-containers/docker/files/0002-daemon-preserve-OCI-additionalGids-for-exec.patch
> new file mode 100644
> index 00000000..8c5c5102
> --- /dev/null
> +++
> b/recipes-containers/docker/files/0002-daemon-preserve-OCI-additionalGids-for-exec.patch
> @@ -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
> + }
> +
> --
> 2.43.0
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#132134):
> https://lists.openembedded.org/g/openembedded-devel/message/132134
> Mute This Topic: https://lists.openembedded.org/mt/122216875/1997914
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [
> raj.khem@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
>
diff mbox series

Patch

diff --git a/recipes-containers/docker/docker-moby_git.bb b/recipes-containers/docker/docker-moby_git.bb
index 271f006e..eafe7a35 100644
--- a/recipes-containers/docker/docker-moby_git.bb
+++ b/recipes-containers/docker/docker-moby_git.bb
@@ -54,6 +54,7 @@  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://0002-daemon-preserve-OCI-additionalGids-for-exec.patch;patchdir=src/import \
 	"
 
 DOCKER_COMMIT = "${SRCREV_moby}"
diff --git a/recipes-containers/docker/files/0002-daemon-preserve-OCI-additionalGids-for-exec.patch b/recipes-containers/docker/files/0002-daemon-preserve-OCI-additionalGids-for-exec.patch
new file mode 100644
index 00000000..8c5c5102
--- /dev/null
+++ b/recipes-containers/docker/files/0002-daemon-preserve-OCI-additionalGids-for-exec.patch
@@ -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
+ }
+