mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
docker exec: fail early on exec create if specified user doesn't exist
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 <github@gone.nl>
This commit is contained in:
@@ -98,6 +98,22 @@ func (daemon *Daemon) ContainerExecCreate(name string, options *containertypes.E
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if user := options.User; user != "" {
|
||||
// Lookup the user inside the container before starting the exec to
|
||||
// allow for an early exit.
|
||||
//
|
||||
// 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).
|
||||
if _, err := getUser(cntr, user); err != nil {
|
||||
return "", errdefs.InvalidParameter(err)
|
||||
}
|
||||
}
|
||||
|
||||
keys := []byte{}
|
||||
if options.DetachKeys != "" {
|
||||
|
||||
Reference in New Issue
Block a user