nixVersions.nix_2_28: 2.28.5 -> 2.28.6

The 2.28.6 tarball already contains the mdbook 0.5 compatibility fix
and the GHSA-g3g9-5vj6-r3gj sandbox escape fix, so drop the
now-redundant downstream backports.
This commit is contained in:
Jörg Thalheim
2026-04-07 22:33:13 +02:00
parent cc8d42cd81
commit 36341693fa
2 changed files with 2 additions and 134 deletions
@@ -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
];
};
@@ -1,126 +0,0 @@
From 32b09e0bfeb33434866610994d89f48da8a2bf41 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io>
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 <sergei@zimmerman.foo>
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 <sergei@zimmerman.foo>
Date: Fri Apr 3 00:21:21 2026 +0300
libstore: Make temporary in-store directory not world-readable
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
---
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<std::filesystem::path, AutoCloseFD> 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<AutoDelete> 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,