diff --git a/libcontainer/env.go b/libcontainer/env.go index fe1abd500..71b2f69d0 100644 --- a/libcontainer/env.go +++ b/libcontainer/env.go @@ -17,13 +17,16 @@ import ( // contains no \0 (nil) bytes; // - removes any duplicates (keeping only the last value for each key) // - sets PATH for the current process, if found in the list; -// - adds HOME to returned environment, if not found in the list. +// - adds HOME to returned environment, if not found in the list, +// or the value is empty. // // Returns the prepared environment. func prepareEnv(env []string, uid int) ([]string, error) { if env == nil { return nil, nil } + var homeIsSet bool + // Deduplication code based on dedupEnv from Go 1.22 os/exec. // Construct the output in reverse order, to preserve the @@ -40,6 +43,7 @@ func prepareEnv(env []string, uid int) ([]string, error) { return nil, errors.New("invalid environment variable: name cannot be empty") } key := kv[:i] + val := kv[i+1:] if saw[key] { // Duplicate. continue } @@ -49,17 +53,25 @@ func prepareEnv(env []string, uid int) ([]string, error) { } if key == "PATH" { // Needs to be set as it is used for binary lookup. - if err := os.Setenv("PATH", kv[i+1:]); err != nil { + if err := os.Setenv("PATH", val); err != nil { return nil, err } } + if key == "HOME" { + if val != "" { + homeIsSet = true + } else { + // Don't add empty HOME to the environment, we will override it later. + continue + } + } out = append(out, kv) } // Restore the original order. slices.Reverse(out) // If HOME is not found in env, get it from container's /etc/passwd and add. - if !saw["HOME"] { + if !homeIsSet { home, err := getUserHome(uid) if err != nil { // For backward compatibility, don't return an error, but merely log it. diff --git a/libcontainer/env_test.go b/libcontainer/env_test.go index c91747167..18dc52e88 100644 --- a/libcontainer/env_test.go +++ b/libcontainer/env_test.go @@ -37,6 +37,18 @@ func TestPrepareEnv(t *testing.T) { env: []string{"TERM=vt100", "HOME=/home/one", "HOME=/home/two", "TERM=xterm", "HOME=/home/three", "FOO=bar"}, wantEnv: []string{"TERM=xterm", "HOME=/home/three", "FOO=bar"}, }, + { + env: []string{"HOME=", "HOME=/foo"}, + wantEnv: []string{"HOME=/foo"}, + }, + { + env: []string{"HOME="}, + wantEnv: []string{home}, + }, + { + env: []string{"HOME=/foo", "HOME="}, + wantEnv: []string{home}, + }, } for _, tc := range tests {