mirror of
https://github.com/NixOS/nix
synced 2025-07-08 15:13:55 +02:00
When moving paths out of sandbox, ensure we have write permission.
If we're a single-user installation of Nix, then we won't have root
superpowers to just ignore the permission bits. This means that we'll
need permission on the directory (if it's a directory) that we're moving
in order to move it with rename, because it must update the ".."
directory entry.
Fixes #4295.
This is already working in master, thanks to
e913a2989f
(and followup cleanups).
This commit is contained in:
parent
6456941993
commit
2239953894
1 changed files with 22 additions and 3 deletions
|
@ -3193,6 +3193,26 @@ PathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv, con
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Move/rename path 'src' to 'dst'. Temporarily make 'src' writable if
|
||||||
|
it's a directory and we're not root (to be able to update the
|
||||||
|
directory's parent link ".."). */
|
||||||
|
static void movePath(const Path & src, const Path & dst)
|
||||||
|
{
|
||||||
|
auto st = lstat(src);
|
||||||
|
|
||||||
|
bool changePerm = (geteuid() && S_ISDIR(st.st_mode) && !(st.st_mode & S_IWUSR));
|
||||||
|
|
||||||
|
if (changePerm)
|
||||||
|
chmod_(src, st.st_mode | S_IWUSR);
|
||||||
|
|
||||||
|
if (rename(src.c_str(), dst.c_str()))
|
||||||
|
throw SysError("renaming '%1%' to '%2%'", src, dst);
|
||||||
|
|
||||||
|
if (changePerm)
|
||||||
|
chmod_(dst, st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DerivationGoal::registerOutputs()
|
void DerivationGoal::registerOutputs()
|
||||||
{
|
{
|
||||||
/* When using a build hook, the build hook can register the output
|
/* When using a build hook, the build hook can register the output
|
||||||
|
@ -3233,9 +3253,8 @@ void DerivationGoal::registerOutputs()
|
||||||
/* Move output paths from the chroot to the Nix store. */
|
/* Move output paths from the chroot to the Nix store. */
|
||||||
if (buildMode == bmRepair)
|
if (buildMode == bmRepair)
|
||||||
replaceValidPath(path, actualPath);
|
replaceValidPath(path, actualPath);
|
||||||
else
|
else if (buildMode != bmCheck)
|
||||||
if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1)
|
movePath(actualPath, worker.store.toRealPath(path));
|
||||||
throw SysError(format("moving build output '%1%' from the sandbox to the Nix store") % path);
|
|
||||||
}
|
}
|
||||||
if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path);
|
if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue