Skip to content

docker exec: fail early on exec create if specified user doesn't exist #49868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 9, 2025

Conversation

thaJeztah
Copy link
Member

@thaJeztah thaJeztah commented Apr 25, 2025

Before this patch, and error would be produced when starting the exec, but the CLI would wait for the exec to complete, timing out after 10 seconds (default). With this change, an error is returned immediately when creating the exec.

Note that "technically" this check may have some TOCTOU issues, because '/etc/passwd' and '/etc/groups' may be mutated by the container in between creating the exec and starting it.

This is very likely a corner-case, but something we can consider changing in future (either allow creating an invalid exec, and checking before starting, or checking both before create and before start).

With this patch:

printf 'FROM alpine\nRUN rm -f /etc/group' | docker build -t nogroup -
ID=$(docker run -dit nogroup)

time docker exec -u 0:root $ID echo hello
Error response from daemon: unable to find group root: no matching entries in group file

real	0m0.014s
user	0m0.010s
sys	0m0.003s

# numericc uid/gid (should not require lookup);
time docker exec -u 0:0 $ID echo hello
hello

real	0m0.059s
user	0m0.007s
sys	0m0.008s

# no user specified (should not require lookup);
time docker exec $ID echo hello
hello

real	0m0.057s
user	0m0.013s
sys	0m0.008s

docker rm -fv $ID

# container that does have a valid /etc/groups

ID=$(docker run -dit alpine)
time docker exec -u 0:root $ID echo hello
hello

real	0m0.063s
user	0m0.010s
sys	0m0.009s

# non-existing user or group
time docker exec -u 0:blabla $ID echo hello
Error response from daemon: unable to find group blabla: no matching entries in group file

real	0m0.013s
user	0m0.004s
sys	0m0.009s

docker rm -fv $ID

- What I did

- How I did it

- How to verify it

- Human readable description for the release notes

Fix `docker exec` waiting for 10 seconds if a non-existing user or group was specified.

- A picture of a cute animal (not mandatory but encouraged)

Before this patch, and error would be produced when starting the exec,
but the CLI would wait for the exec to complete, timing out after 10
seconds (default). With this change, an error is returned immediately
when creating the exec.

Note that "technically" this check may have some TOCTOU issues, because
'/etc/passwd' and '/etc/groups' may be mutated by the container in between
creating the exec and starting it.

This is very likely a corner-case, but something we can consider changing
in future (either allow creating an invalid exec, and checking before
starting, or checking both before create and before start).

With this patch:

    printf 'FROM alpine\nRUN rm -f /etc/group' | docker build -t nogroup -
    ID=$(docker run -dit nogroup)

    time docker exec -u 0:root $ID echo hello
    Error response from daemon: unable to find group root: no matching entries in group file

    real	0m0.014s
    user	0m0.010s
    sys	0m0.003s

    # numericc uid/gid (should not require lookup);
    time docker exec -u 0:0 $ID echo hello
    hello

    real	0m0.059s
    user	0m0.007s
    sys	0m0.008s

    # no user specified (should not require lookup);
    time docker exec $ID echo hello
    hello

    real	0m0.057s
    user	0m0.013s
    sys	0m0.008s

    docker rm -fv $ID

    # container that does have a valid /etc/groups

    ID=$(docker run -dit alpine)
    time docker exec -u 0:root $ID echo hello
    hello

    real	0m0.063s
    user	0m0.010s
    sys	0m0.009s

    # non-existing user or group
    time docker exec -u 0:blabla $ID echo hello
    Error response from daemon: unable to find group blabla: no matching entries in group file

    real	0m0.013s
    user	0m0.004s
    sys	0m0.009s

    docker rm -fv $ID

Signed-off-by: Sebastiaan van Stijn <[email protected]>
@thaJeztah thaJeztah force-pushed the exec_validate_user branch from a4c1169 to b54a038 Compare April 25, 2025 13:24
@thaJeztah thaJeztah self-assigned this Apr 26, 2025
Copy link
Contributor

@vvoland vvoland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines +285 to +290
ctrOpts := []func(*container.TestContainerConfig){
container.WithTty(true),
container.WithUser("1:1"),
}
withoutEtcGroups := container.WithImage(build.Do(ctx, t, apiClient, fakecontext.New(t, "", fakecontext.WithDockerfile("FROM busybox\nRUN rm /etc/group"))))
withoutEtcPasswd := container.WithImage(build.Do(ctx, t, apiClient, fakecontext.New(t, "", fakecontext.WithDockerfile("FROM busybox\nRUN rm /etc/passwd"))))
Copy link
Member Author

@thaJeztah thaJeztah Apr 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should point out that I had some fun with this part; if I tried to make these tests run without building an image (so running a container with sh -c 'rm /etc/passwd && top' as command), the test didn't fail as expected. I tried adding a sync in between to see if it was possibly that changes weren't written to disk, but that didn't work either. So ... something odd.

Trying to run the same scenario manually didn't reproduce that issue.

cid=$(docker run -dit --name foo busybox sh -c 'rm /etc/passwd && top') \
 && docker exec -it -u root:root $cid echo hello

# Error response from daemon: unable to find user root: no matching entries in passwd file

So either it's something in how the tests runs, or there's some actual race somewhere. I decided not to continue looking into that, because failing to detect the problem would still cause the actual exec to fail (the new check is just an extra check), but perhaps something to try to find what's happening.

@thaJeztah thaJeztah requested a review from dmcgowan April 28, 2025 13:51
@thaJeztah
Copy link
Member Author

@dmcgowan ptal ❤️

@thaJeztah thaJeztah merged commit 9b19172 into moby:master May 9, 2025
141 checks passed
@thaJeztah thaJeztah deleted the exec_validate_user branch May 9, 2025 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Slow exec error when no /etc/group
3 participants