mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
libct: Override HOME if its set to the empty string
Before commit06f1e0765("libct: speedup process.Env handling") we were overriding HOME if it was set to "" too[1]. But now we only override it if it wasn't set at all. This patch restores the old behavior of overriding it if it was set to an empty value. Docker relies on this behaviour since ages[2]. [1]: https://github.com/opencontainers/runc/blob/1c508045727231e7342e258ab30add1478c1f981/libcontainer/init_linux.go#L544-L549 [2]: https://github.com/moby/moby/blob/843e51459f14ebc964d349eba1013dc8a3e9d52e/integration-cli/docker_cli_run_test.go#L822-L843 Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com> (cherry picked from commit09501d96d2)
This commit is contained in:
+15
-3
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user