From 3108ae62269aff1ee7ff20a7ff0b4d67cb44fcce Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Wed, 29 Jul 2020 12:43:43 +1000 Subject: [PATCH] oci: correctly use user.GetExecUser interface A nil interface in Go is not the same as a nil pointer that satisfies the interface. libcontainer/user has special handling for missing /etc/{passwd,group} files but this is all based on nil interface checks, which were broken by Docker's usage of the API. When combined with some recent changes in runc that made read errors actually be returned to the caller, this results in spurrious -EINVAL errors when we should detect the situation as "there is no passwd file". Signed-off-by: Aleksa Sarai --- daemon/oci_linux.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 44ac97d1d3..47970593d3 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -176,7 +176,14 @@ func readUserFile(c *container.Container, p string) (io.ReadCloser, error) { if err != nil { return nil, err } - return os.Open(fp) + fh, err := os.Open(fp) + if err != nil { + // This is needed because a nil *os.File is different to a nil + // io.ReadCloser and this causes GetExecUser to not detect that the + // container file is missing. + return nil, err + } + return fh, nil } func getUser(c *container.Container, username string) (uint32, uint32, []uint32, error) {