mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
cherry-pick https://gerrit.lix.systems/c/lix/+/2100
Cherry-pick https://gerrit.lix.systems/c/lix/+/2100 This change fixes a potential concurrency failure when accessing random which is not thread safe. Co-authored-by: Lily Ballard <lily@ballards.net>
This commit is contained in:
parent
e22142e11a
commit
6aed9d877c
7 changed files with 35 additions and 37 deletions
|
@ -1,22 +1,14 @@
|
|||
#include "nix/store/build/derivation-builder.hh"
|
||||
#include "nix/store/local-store.hh"
|
||||
#include "nix/util/processes.hh"
|
||||
#include "nix/store/indirect-root-store.hh"
|
||||
#include "nix/store/build/hook-instance.hh"
|
||||
#include "nix/store/build/worker.hh"
|
||||
#include "nix/store/builtins.hh"
|
||||
#include "nix/store/builtins/buildenv.hh"
|
||||
#include "nix/store/path-references.hh"
|
||||
#include "nix/util/finally.hh"
|
||||
#include "nix/util/util.hh"
|
||||
#include "nix/util/archive.hh"
|
||||
#include "nix/util/git.hh"
|
||||
#include "nix/util/compression.hh"
|
||||
#include "nix/store/daemon.hh"
|
||||
#include "nix/util/topo-sort.hh"
|
||||
#include "nix/util/callback.hh"
|
||||
#include "nix/util/json-utils.hh"
|
||||
#include "nix/util/current-process.hh"
|
||||
#include "nix/store/build/child.hh"
|
||||
#include "nix/util/unix-domain-socket.hh"
|
||||
#include "nix/store/posix-fs-canonicalise.hh"
|
||||
|
@ -671,23 +663,33 @@ static void replaceValidPath(const Path & storePath, const Path & tmpPath)
|
|||
tmpPath (the replacement), so we have to move it out of the
|
||||
way first. We'd better not be interrupted here, because if
|
||||
we're repairing (say) Glibc, we end up with a broken system. */
|
||||
Path oldPath = fmt("%1%.old-%2%-%3%", storePath, getpid(), rand());
|
||||
if (pathExists(storePath))
|
||||
Path oldPath;
|
||||
|
||||
if (pathExists(storePath)) {
|
||||
// why do we loop here?
|
||||
// although makeTempPath should be unique, we can't
|
||||
// guarantee that.
|
||||
do {
|
||||
oldPath = makeTempPath(storePath, ".old");
|
||||
// store paths are often directories so we can't just unlink() it
|
||||
// let's make sure the path doesn't exist before we try to use it
|
||||
} while (pathExists(oldPath));
|
||||
movePath(storePath, oldPath);
|
||||
|
||||
}
|
||||
try {
|
||||
movePath(tmpPath, storePath);
|
||||
} catch (...) {
|
||||
try {
|
||||
// attempt to recover
|
||||
movePath(oldPath, storePath);
|
||||
if (!oldPath.empty())
|
||||
movePath(oldPath, storePath);
|
||||
} catch (...) {
|
||||
ignoreExceptionExceptInterrupt();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
deletePath(oldPath);
|
||||
if (!oldPath.empty())
|
||||
deletePath(oldPath);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue