mirror of
https://github.com/NixOS/nix
synced 2025-07-02 13:31:48 +02:00
* Fix a huge gaping hole in nix-env w.r.t. the garbage collector.
Nix-env failed to call addPermRoot(), which is necessary to safely add a new root. So if nix-env started after and finished before the garbage collector, the user environment (plus all other new stuff) it built might be garbage collected, leading to a dangling symlink chain in ~/.nix-profile... * Be more explicit if we block on the GC lock ("waiting for the big garbage collector lock..."). * Don't loop trying to create a new generation. It's not necessary anymore since profiles are locked nowadays.
This commit is contained in:
parent
f00bc4c94c
commit
5c38c863bd
3 changed files with 26 additions and 22 deletions
|
@ -44,7 +44,10 @@ static int openGCLock(LockType lockType)
|
|||
if (fdGCLock == -1)
|
||||
throw SysError(format("opening global GC lock `%1%'") % fnGCLock);
|
||||
|
||||
lockFile(fdGCLock, lockType, true);
|
||||
if (!lockFile(fdGCLock, lockType, false)) {
|
||||
printMsg(lvlError, format("waiting for the big garbage collector lock..."));
|
||||
lockFile(fdGCLock, lockType, true);
|
||||
}
|
||||
|
||||
/* !!! Restrict read permission on the GC root. Otherwise any
|
||||
process that can open the file for reading can DoS the
|
||||
|
@ -74,7 +77,7 @@ void createSymlink(const Path & link, const Path & target, bool careful)
|
|||
|
||||
|
||||
Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
|
||||
bool indirect)
|
||||
bool indirect, bool allowOutsideRootsDir)
|
||||
{
|
||||
Path storePath(canonPath(_storePath));
|
||||
Path gcRoot(canonPath(_gcRoot));
|
||||
|
@ -97,14 +100,16 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
|
|||
}
|
||||
|
||||
else {
|
||||
Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str());
|
||||
if (!allowOutsideRootsDir) {
|
||||
Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str());
|
||||
|
||||
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
|
||||
throw Error(format(
|
||||
"path `%1%' is not a valid garbage collector root; "
|
||||
"it's not in the directory `%2%'")
|
||||
% gcRoot % rootsDir);
|
||||
|
||||
if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/")
|
||||
throw Error(format(
|
||||
"path `%1%' is not a valid garbage collector root; "
|
||||
"it's not in the directory `%2%'")
|
||||
% gcRoot % rootsDir);
|
||||
}
|
||||
|
||||
createSymlink(gcRoot, storePath, false);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue