1
0
Fork 0
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:
Eelco Dolstra 2006-09-14 22:30:33 +00:00
parent f00bc4c94c
commit 5c38c863bd
3 changed files with 26 additions and 22 deletions

View file

@ -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);
}