containerd icon indicating copy to clipboard operation
containerd copied to clipboard

Supplemental GID missing for group with same name as user

Open burgerdev opened this issue 8 months ago • 3 comments

Description

Originally, I observed this with a mongodb container. The image user is mongodb and there is a group mongodb, but it's not the primary group of the user (nogroup is). containerd omits the mongodb group from the supplemental GID list.

Steps to reproduce the issue

  1. Create a GCP Debian Bookworm VM.
  2. Install latest k3s (v1.32.5+k3s1, comes with containerd v2.0.5-k3s1.32[^1]).
  3. Apply a specially crafted reproducer (source: https://github.com/burgerdev/weird-images/tree/74b32e2/src/gid)
    kubectl apply -f https://raw.githubusercontent.com/burgerdev/weird-images/74b32e268da916576f307f6f997ae289322f5aa6/src/gid/gid.yaml
    

[^1]: This was the simplest way for me to reproduce the bug. I know that it's a bit removed from upstream containerd main, but since I believe to have found the root cause (see last section), it may be sufficient as a demo.

Describe the results you received and expected

Observed

In the container logs, I see the UID, GID and supplemental groups:

Uid:	2	2	2	2
Gid:	1	1	1	1
Groups:	1 

Expected

The process should also have the supplemental group 2 (name).

What version of containerd are you using?

v2.0.5-k3s1.32

Any other relevant information

MongoDB setup

Image that I used when I discovered the bug: quay.io/mongodb/mongodb-community-server@sha256:8b73733842da21b6bbb6df4d7b2449229bb3135d2ec8c6880314d88205772a11

The unusual group setup comes from here, afaict:

https://github.com/mongodb/mongo/blob/cd9cc7450f3f665771a10f5c15f05bd6991c4d69/debian/mongodb-org-server.postinst#L25-L27

containerd bug

I assume it's this snippet that triggers the bug

https://github.com/containerd/containerd/blob/bcd000f443ef363b96e6dd4d67b4f6babfdef100/pkg/oci/spec_opts.go#L851-L854

The code seems to assume that a group with the same name as the user is always the primary group of the user.

It might be possible to just delete this check, given that the primary ID is always added

https://github.com/containerd/containerd/blob/bcd000f443ef363b96e6dd4d67b4f6babfdef100/pkg/oci/spec_opts.go#L833

but only if it hasn't been added already

https://github.com/containerd/containerd/blob/bcd000f443ef363b96e6dd4d67b4f6babfdef100/pkg/oci/spec_opts.go#L127-L135

Show configuration if it is related to CRI plugin.

No response

burgerdev avatar Jun 04 '25 07:06 burgerdev

Heh, I was actually looking at some of these earlier Today, in preparation of upstreaming some code that was forked in BuildKit and Moby (docker engine), but there's quite some complexity in those code-paths, and there's also multiple impleementations which seem to slightly differ (between the CRI code and non-CRI code, although for some one wraps the other); https://github.com/containerd/containerd/blob/0bf07cd5c6ec01fadbf6606c3b4af76d2359d207/internal/cri/server/container_create_linux.go#L39-L64

Out of interest, I was wondering what a docker run would currently do (but I still need to look if it's currently depending on those code-paths from containerd, or using its own implementation);

Checking /etc/passwd and /etc/group;

docker run -it --rm --user mongodb mongodb/mongodb-community-server sh -c 'cat /etc/passwd | grep mongodb'
mongodb:x:101:65534::/home/mongodb:/usr/sbin/nologin

docker run -it --rm --user mongodb mongodb/mongodb-community-server sh -c 'cat /etc/group | grep mongodb'
mongodb:x:101:mongodb

docker run -it --rm --user mongodb mongodb/mongodb-community-server sh -c 'cat /etc/group | grep 65534'
nogroup:x:65534:

default user (as defined in the image)

docker run -it --rm mongodb/mongodb-community-server id
uid=101(mongodb) gid=65534(nogroup) groups=65534(nogroup),101(mongodb)

explicitly setting the user to "mongodb" (not passing a group);

docker run -it --rm --user mongodb mongodb/mongodb-community-server id
uid=101(mongodb) gid=65534(nogroup) groups=65534(nogroup),101(mongodb)

And with your reproducer image;

docker build \
    -t test \
    -f 'https://raw.githubusercontent.com/burgerdev/weird-images/74b32e268da916576f307f6f997ae289322f5aa6/src/gid/Containerfile' \
    'https://github.com/burgerdev/weird-images.git#74b32e268da916576f307f6f997ae289322f5aa6:src/gid'

docker run -it --rm test
Uid:	2	2	2	2
Gid:	1	1	1	1
Groups:	1 2
^C

docker run -it --rm --entrypoint="" test id
uid=2(name) gid=1(daemon) groups=1(daemon),2(name)

edit: also tried with docker build to see if it's correct;

echo -e 'FROM mongodb/mongodb-community-server\nRUN id' | docker build --progress=plain --no-cache -
# ...
#6 [2/2] RUN id
#6 0.325 uid=101(mongodb) gid=65534(nogroup) groups=65534(nogroup),101(mongodb)
#6 DONE 0.4s


echo -e 'FROM mongodb/mongodb-community-server\nUSER root\nRUN id\nUSER mongodb\nRUN id' | docker build --progress=plain --no-cache -
#5 [2/3] RUN id
#5 0.232 uid=0(root) gid=0(root) groups=0(root)
#5 DONE 0.3s

#6 [3/3] RUN id
#6 0.307 uid=101(mongodb) gid=65534(nogroup) groups=65534(nogroup),101(mongodb)
#6 DONE 0.4s

thaJeztah avatar Jun 04 '25 21:06 thaJeztah

Thanks for investigating this, @thaJeztah. I also tested this with docker and can confirm your observation, but discounted it because I thought docker may be introducing some special treatment here. Now I too wonder which code path results in the correct additionalGIDs - I've only found the one with the bug and one that does not look at /etc/group.

burgerdev avatar Jun 05 '25 06:06 burgerdev

Thanks! Yes, it was also a bit "note to self" to compare the behavior; I had some "half-completed" branches to try and unify more of the implementations; especially to avoid (sometimes subtle) differences in behavior.

Big disclaimer that I'm not a kubernetes user, so it's possible that some differences were by design (https://github.com/kubernetes/enhancements/pull/3620), but I'm also aware that correct behavior for (supplemental) groups were a bit under-defined (also see https://github.com/opencontainers/image-spec/pull/1011, https://github.com/opencontainers/runtime-spec/issues/1180 for example).

thaJeztah avatar Jun 05 '25 08:06 thaJeztah