diff options
Diffstat (limited to 'nix/libstore/build.cc')
-rw-r--r-- | nix/libstore/build.cc | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 461fcbc584..e2adee118b 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -1382,6 +1382,22 @@ void DerivationGoal::buildDone() % drvPath % statusToString(status)); } + if (fixedOutput) { + /* Replace the output, if it exists, by a fresh copy of itself to + make sure that there's no stale file descriptor pointing to it + (CVE-2024-27297). */ + foreach (DerivationOutputs::iterator, i, drv.outputs) { + if (pathExists(i->second.path)) { + Path pivot = i->second.path + ".tmp"; + copyFileRecursively(i->second.path, pivot, true); + int err = rename(pivot.c_str(), i->second.path.c_str()); + if (err != 0) + throw SysError(format("renaming `%1%' to `%2%'") + % pivot % i->second.path); + } + } + } + /* Compute the FS closure of the outputs and register them as being valid. */ registerOutputs(); |