Verify $HOME is owned by current user in getHome(), if it exists.

Useful because a default `sudo` on darwin doesn't clear `$HOME`, so things like `sudo nix-channel --list`
will surprisingly return the USER'S channels, rather than `root`'s.

Other counterintuitive outcomes can be seen in this PR description:
  https://github.com/NixOS/nix/pull/6622
This commit is contained in:
Dave Nicponski 2022-06-15 16:38:56 -04:00
parent 9f58df4c91
commit ca2be509b9

View file

@ -574,6 +574,20 @@ Path getHome()
static Path homeDir = []() static Path homeDir = []()
{ {
auto homeDir = getEnv("HOME"); auto homeDir = getEnv("HOME");
if (homeDir) {
// Only use $HOME if doesn't exist or is owned by the current user.
struct stat st;
int result = stat(homeDir->c_str(), &st);
if (result != 0) {
if (errno != ENOENT) {
warn("Couldn't stat $HOME ('%s') for reason other than not existing ('%d'), falling back to the one defined in the 'passwd' file", *homeDir, errno);
homeDir.reset();
}
} else if (st.st_uid != geteuid()) {
warn("$HOME ('%s') is not owned by you, falling back to the one defined in the 'passwd' file", *homeDir);
homeDir.reset();
}
}
if (!homeDir) { if (!homeDir) {
std::vector<char> buf(16384); std::vector<char> buf(16384);
struct passwd pwbuf; struct passwd pwbuf;