Resolve HOME to the target user's home directory instead of /root

ResolvedUser now carries home, looked up from the image's own
/etc/passwd entry for the final resolved uid (falling back to /root
for uid 0 or / otherwise when there's no matching row). bwrap's HOME
now uses this whenever a user override applies (--user/--group or an
image-declared default user); the plain /root default is kept only
when no override applies at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
This commit is contained in:
2026-08-22 06:47:16 +00:00
parent 545762d6de
commit 355675b43f
4 changed files with 24 additions and 9 deletions
+1 -3
View File
@@ -227,11 +227,9 @@ std::vector<std::string> build_bwrap_args(const std::string& root,
"--setenv",
"PATH",
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"--setenv",
"HOME",
"/root",
};
args.insert(args.end(), filesystem_args.begin(), filesystem_args.end());
args.insert(args.end(), {"--setenv", "HOME", user ? user->home : "/root"});
for (const auto& volume : volumes) {
args.insert(args.end(), {"--bind", volume.host_directory, volume.container_path});
+1
View File
@@ -45,6 +45,7 @@ std::optional<std::vector<std::string>> wrap_for_root_namespace(const std::strin
struct ResolvedUser {
int uid;
int gid;
std::string home; // from the image's /etc/passwd entry for uid, or a sane fallback
};
// Assembles the full bwrap argv (program name included) to run `command` with
+11 -1
View File
@@ -119,5 +119,15 @@ std::optional<ResolvedUser> resolve_user_and_group(const std::string& user,
}
}
return ResolvedUser{uid, gid};
// Looked up by the final resolved uid (field 2), independent of whether `user`
// was given as a name or a number, so it matches whichever /etc/passwd row
// actually owns that uid. No matching row -> fall back to "/root" for uid 0
// (matches useradd-less images' own convention for root) or "/" otherwise.
std::string home = uid == 0 ? "/root" : "/";
auto home_entry = lookup_entry(passwd_file, std::to_string(uid), 2);
if (home_entry && home_entry->size() > 5 && !(*home_entry)[5].empty()) {
home = (*home_entry)[5];
}
return ResolvedUser{uid, gid, home};
}