From 3bf9fdde4ce12321659f085d3c1a9cfb86bb702a Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 26 Jun 2025 21:04:34 +0200 Subject: [PATCH] cmd/create, cmd/run, cmd/utils: Unbreak overriding the HOME variable The POSIX shell implementation used to read and respect the HOME environment variable. It broke when the Go implementation started using user.Current() [1], because it uses getpwuid_r(3), which only uses the GNU Name Service Switch's (or NSS') password database and ignores HOME. This created a strange situation where the toolbox(1) binary ignored the HOME environment variable, while the profile.d/toolbox.sh shell start-up snippet and Podman read and respected it. Restoring the HOME environment variable will enable users to create Toolbx containers with different home directories from the host for increased isolation, and to isolate the host's HOME from the system tests. Fallout from e8d7f25e831725d0bafbbd3171b9a5262d2d1113 [1] https://pkg.go.dev/os/user#Current https://github.com/containers/toolbox/issues/1044 https://github.com/containers/toolbox/issues/1564 --- src/cmd/create.go | 11 ++++++----- src/cmd/run.go | 2 +- src/cmd/utils.go | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/cmd/create.go b/src/cmd/create.go index 494cd21..531721b 100644 --- a/src/cmd/create.go +++ b/src/cmd/create.go @@ -1,5 +1,5 @@ /* - * Copyright © 2019 – 2024 Red Hat Inc. + * Copyright © 2019 – 2025 Red Hat Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -300,12 +300,13 @@ func createContainer(container, image, release, authFile string, showCommandToEn dbusSystemSocketMountArg := dbusSystemSocket + ":" + dbusSystemSocket - homeDirEvaled, err := filepath.EvalSymlinks(currentUser.HomeDir) + currentUserHomeDir := getCurrentUserHomeDir() + homeDirEvaled, err := filepath.EvalSymlinks(currentUserHomeDir) if err != nil { - return fmt.Errorf("failed to canonicalize %s", currentUser.HomeDir) + return fmt.Errorf("failed to canonicalize %s", currentUserHomeDir) } - logrus.Debugf("%s canonicalized to %s", currentUser.HomeDir, homeDirEvaled) + logrus.Debugf("%s canonicalized to %s", currentUserHomeDir, homeDirEvaled) homeDirMountArg := homeDirEvaled + ":" + homeDirEvaled + ":rslave" var avahiSocketMount []string @@ -412,7 +413,7 @@ func createContainer(container, image, release, authFile string, showCommandToEn "toolbox", "--log-level", "debug", "init-container", "--gid", currentUser.Gid, - "--home", currentUser.HomeDir, + "--home", currentUserHomeDir, "--shell", userShell, "--uid", currentUser.Uid, "--user", currentUser.Username, diff --git a/src/cmd/run.go b/src/cmd/run.go index 7094c3a..389ea16 100644 --- a/src/cmd/run.go +++ b/src/cmd/run.go @@ -448,7 +448,7 @@ func runCommandWithFallbacks(container string, workDir = runFallbackWorkDirs[runFallbackWorkDirsIndex] if workDir == "" { - workDir = currentUser.HomeDir + workDir = getCurrentUserHomeDir() } fmt.Fprintf(os.Stderr, "Using %s instead.\n", workDir) diff --git a/src/cmd/utils.go b/src/cmd/utils.go index 999b596..e35fb3d 100644 --- a/src/cmd/utils.go +++ b/src/cmd/utils.go @@ -341,6 +341,22 @@ func getCDIFileForNvidia(targetUser *user.User) (string, error) { return cdiFile, nil } +func getCurrentUserHomeDir() string { + if currentUser == nil { + panic("current user unknown") + } + + userHomeDir, err := os.UserHomeDir() + if err == nil { + return userHomeDir + } + + logrus.Debugf("Getting the current user's home directory: failed to use os.UserHomeDir(): %s", err) + logrus.Debug("Using user.Current() instead") + + return currentUser.HomeDir +} + func getUsageForCommonCommands() string { var builder strings.Builder builder.WriteString("create Create a new Toolbx container\n")