1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Fix /proc/<pid>/oom_score_adj: invalid argument error caused by empty env name

This fix is part of the fix for issue 25099. In 25099, if an env
has a empty name, then `docker run` will throw out an error:
```
ubuntu@ubuntu:~/docker$ docker run -e =A busybox true
docker: Error response from daemon: invalid header field value "oci runtime error:
container_linux.go:247: starting container process caused \"process_linux.go:295:
setting oom score for ready process caused \\\"write /proc/83582/oom_score_adj:
invalid argument\\\"\"\n".
```

This fix validates the Env in the container spec before it is sent
to containerd/runc.

Integration tests have been created to cover the changes.

This fix is part of fix for 25099 (not complete yet, non-utf case
may require a fix in `runc`).
This fix is related to 25300.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang 2016-11-05 11:53:54 -07:00
parent e00e7e9582
commit 818d55c34b
4 changed files with 72 additions and 0 deletions

View file

@ -15,6 +15,7 @@ import (
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/truncindex" "github.com/docker/docker/pkg/truncindex"
"github.com/docker/docker/runconfig/opts"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
) )
@ -232,6 +233,13 @@ func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostCon
return nil, fmt.Errorf("invalid hostname format: %s", config.Hostname) return nil, fmt.Errorf("invalid hostname format: %s", config.Hostname)
} }
} }
// Validate if Env contains empty variable or not (e.g., ``, `=foo`)
for _, env := range config.Env {
if _, err := opts.ValidateEnv(env); err != nil {
return nil, err
}
}
} }
if hostConfig == nil { if hostConfig == nil {

View file

@ -42,3 +42,43 @@ func (s *DockerSuite) TestAPICreateWithNotExistImage(c *check.C) {
c.Assert(getErrorMessage(c, body), checker.Equals, expected) c.Assert(getErrorMessage(c, body), checker.Equals, expected)
} }
// Test for #25099
func (s *DockerSuite) TestAPICreateEmptyEnv(c *check.C) {
name := "test1"
config := map[string]interface{}{
"Image": "busybox",
"Env": []string{"", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
"Cmd": []string{"true"},
}
status, body, err := sockRequest("POST", "/containers/create?name="+name, config)
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
expected := "invalid environment variable:"
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
name = "test2"
config = map[string]interface{}{
"Image": "busybox",
"Env": []string{"=", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
"Cmd": []string{"true"},
}
status, body, err = sockRequest("POST", "/containers/create?name="+name, config)
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
expected = "invalid environment variable: ="
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
name = "test3"
config = map[string]interface{}{
"Image": "busybox",
"Env": []string{"=foo", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
"Cmd": []string{"true"},
}
status, body, err = sockRequest("POST", "/containers/create?name="+name, config)
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
expected = "invalid environment variable: =foo"
c.Assert(getErrorMessage(c, body), checker.Contains, expected)
}

View file

@ -4830,3 +4830,22 @@ func (s *DockerSuite) TestRunHypervIsolationWithCPUCountCPUSharesAndCPUPercent(c
out = inspectField(c, "test", "HostConfig.CPUPercent") out = inspectField(c, "test", "HostConfig.CPUPercent")
c.Assert(out, check.Equals, "80") c.Assert(out, check.Equals, "80")
} }
// Test for #25099
func (s *DockerSuite) TestRunEmptyEnv(c *check.C) {
testRequires(c, DaemonIsLinux)
expectedOutput := "invalid environment variable:"
out, _, err := dockerCmdWithError("run", "-e", "", "busybox", "true")
c.Assert(err, checker.NotNil)
c.Assert(out, checker.Contains, expectedOutput)
out, _, err = dockerCmdWithError("run", "-e", "=", "busybox", "true")
c.Assert(err, checker.NotNil)
c.Assert(out, checker.Contains, expectedOutput)
out, _, err = dockerCmdWithError("run", "-e", "=foo", "busybox", "true")
c.Assert(err, checker.NotNil)
c.Assert(out, checker.Contains, expectedOutput)
}

View file

@ -26,8 +26,13 @@ func ValidateAttach(val string) (string, error) {
// As on ParseEnvFile and related to #16585, environment variable names // As on ParseEnvFile and related to #16585, environment variable names
// are not validate what so ever, it's up to application inside docker // are not validate what so ever, it's up to application inside docker
// to validate them or not. // to validate them or not.
//
// The only validation here is to check if name is empty, per #25099
func ValidateEnv(val string) (string, error) { func ValidateEnv(val string) (string, error) {
arr := strings.Split(val, "=") arr := strings.Split(val, "=")
if arr[0] == "" {
return "", fmt.Errorf("invalid environment variable: %s", val)
}
if len(arr) > 1 { if len(arr) > 1 {
return val, nil return val, nil
} }