diff --git a/pkgs/tools/package-management/nix/default.nix b/pkgs/tools/package-management/nix/default.nix index 13a8a74e7a41..8da4c6b494fb 100644 --- a/pkgs/tools/package-management/nix/default.nix +++ b/pkgs/tools/package-management/nix/default.nix @@ -155,17 +155,11 @@ lib.makeExtensible ( ( { nix_2_28 = commonMeson { - version = "2.28.5"; - hash = "sha256-oIfAHxO+BCtHXJXLHBnsKkGl1Pw+Uuq1PwNxl+lZ+Oc="; + version = "2.28.6"; + hash = "sha256-jg2YDTFt8CY4kMg4ha3UK5C+mQY+Zg67nwNy+CmTk5w="; self_attribute_name = "nix_2_28"; patches = patches_common ++ [ - (fetchpatch2 { - name = "nix-2.28-14764-mdbook-0.5-support.patch"; - url = "https://github.com/NixOS/nix/commit/5a64138e862fe364e751c5c286e8db8c466aaee7.patch?full_index=1"; - hash = "sha256-vFv/D08x9urtoIE9wiC7Lln4Eq3sgNBwU7TBE1iyrfI="; - }) lowdown30PatchOld - ./patches/ghsa-g3g9-5vj6-r3gj-2.28.patch ]; }; diff --git a/pkgs/tools/package-management/nix/patches/ghsa-g3g9-5vj6-r3gj-2.28.patch b/pkgs/tools/package-management/nix/patches/ghsa-g3g9-5vj6-r3gj-2.28.patch deleted file mode 100644 index ae50b007a30b..000000000000 --- a/pkgs/tools/package-management/nix/patches/ghsa-g3g9-5vj6-r3gj-2.28.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 32b09e0bfeb33434866610994d89f48da8a2bf41 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= -Date: Mon, 6 Apr 2026 16:49:13 +0200 -Subject: [PATCH] Fixes for GHSA-g3g9-5vj6-r3gj -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Squashed commit of the following: - -commit 716dba6692c42e301a1e769e5eac02a4d6e63150 -Author: Sergei Zimmerman -Date: Fri Apr 3 00:21:31 2026 +0300 - - derivation-builder: Don't use copyFile for FOD output copying, put the output in a temporary directory in the store - -commit a3215e7c5c260fab5f2cb034c4df01dfa3b284e5 -Author: Sergei Zimmerman -Date: Fri Apr 3 00:21:21 2026 +0300 - - libstore: Make temporary in-store directory not world-readable - -Signed-off-by: Jörg Thalheim ---- - src/libstore/include/nix/store/local-store.hh | 2 ++ - src/libstore/local-store.cc | 5 +-- - .../unix/build/local-derivation-goal.cc | 36 ++++++++++++++----- - 3 files changed, 33 insertions(+), 10 deletions(-) - -diff --git a/src/libstore/include/nix/store/local-store.hh b/src/libstore/include/nix/store/local-store.hh -index 5893b7d8b..c9266f6b4 100644 ---- a/src/libstore/include/nix/store/local-store.hh -+++ b/src/libstore/include/nix/store/local-store.hh -@@ -408,6 +408,8 @@ private: - friend struct PathSubstitutionGoal; - friend struct SubstitutionGoal; - friend struct DerivationGoal; -+ /* Only used for createTempDirInStore. */ -+ friend class DerivationBuilderImpl; - }; - - } // namespace nix -diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc -index 63108fab4..ab3a0d034 100644 ---- a/src/libstore/local-store.cc -+++ b/src/libstore/local-store.cc -@@ -1311,8 +1311,9 @@ std::pair LocalStore::createTempDirInStore() - do { - /* There is a slight possibility that `tmpDir' gets deleted by - the GC between createTempDir() and when we acquire a lock on it. -- We'll repeat until 'tmpDir' exists and we've locked it. */ -- tmpDirFn = createTempDir(realStoreDir, "tmp"); -+ We'll repeat until 'tmpDir' exists and we've locked it. -+ Make the directory accessible only to the current user.*/ -+ tmpDirFn = createTempDir(realStoreDir, "tmp", /*mode=*/0700); - tmpDirFd = openDirectory(tmpDirFn); - if (!tmpDirFd) { - continue; -diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc -index 88c82e063..3e4c3017d 100644 ---- a/src/libstore/unix/build/local-derivation-goal.cc -+++ b/src/libstore/unix/build/local-derivation-goal.cc -@@ -2547,6 +2547,13 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() - assert(output && scratchPath); - auto actualPath = toRealPathChroot(worker.store.printStorePath(*scratchPath)); - -+ /* An optional file descriptor of a directory used for intermediate -+ operations. */ -+ AutoCloseFD tempDirFd; -+ /* RAII cleanup of a temporary directory inside the store that is used -+ for intermediate operations. */ -+ std::optional delTempDir; -+ - auto finish = [&](StorePath finalStorePath) { - /* Store the final path */ - finalOutputs.insert_or_assign(outputName, finalStorePath); -@@ -2681,6 +2688,25 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() - return newInfo0; - }; - -+ auto moveOutputToTempDir = [&]() -> void { -+ std::filesystem::path tempDir; -+ std::tie(tempDir, tempDirFd) = getLocalStore().createTempDirInStore(); -+ delTempDir.emplace(tempDir); -+ -+ auto tmpOutput = tempDir / "x"; -+ -+ /* Serialise and create a fresh copy of the output to break -+ any stale writable file descriptors. Copy through the -+ serialisation/deserialisation. TODO: Use copyRecursive here and -+ make use of reflinking. */ -+ auto source = sinkToSource([&](Sink & nextSink) { dumpPath(actualPath, nextSink); }); -+ restorePath(tmpOutput, *source, settings.fsyncStorePaths); -+ /* This makes it slightly harder to make sense of the control flow. The rule -+ of thumb is that actualPath points to the current location of the stuff -+ that we'll end up registering. */ -+ actualPath = std::move(tmpOutput); -+ }; -+ - ValidPathInfo newInfo = std::visit( - overloaded{ - -@@ -2708,14 +2734,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() - - [&](const DerivationOutput::CAFixed & dof) { - auto & wanted = dof.ca.hash; -- -- // Replace the output by a fresh copy of itself to make sure -- // that there's no stale file descriptor pointing to it -- Path tmpOutput = actualPath + ".tmp"; -- copyFile(std::filesystem::path(actualPath), std::filesystem::path(tmpOutput), true); -- -- std::filesystem::rename(tmpOutput, actualPath); -- -+ moveOutputToTempDir(); - auto newInfo0 = newInfoFromCA( - DerivationOutput::CAFloating{ - .method = dof.ca.method, -@@ -2756,6 +2775,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() - }, - - [&](const DerivationOutput::Impure & doi) { -+ moveOutputToTempDir(); - return newInfoFromCA( - DerivationOutput::CAFloating{ - .method = doi.method,