diff --git a/flake.lock b/flake.lock index d83cf0b..1ea5788 100644 --- a/flake.lock +++ b/flake.lock @@ -96,11 +96,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1750854959, - "narHash": "sha256-aL8Nu/gDUwMZpCsf1Crx+tT24yE+Fa8n0+hVjFKOpQQ=", + "lastModified": 1751243689, + "narHash": "sha256-yWwH1pb06X9r9qmJCqLrsUpT+1lI+CEAD30MpaJ7FVU=", "owner": "chaotic-cx", "repo": "nyx", - "rev": "c417f3d4efc3042682c54631c975d554481a3bdb", + "rev": "b9f4e747234d73a7e9c45ba0c30cbb46311dbdf3", "type": "github" }, "original": { @@ -163,11 +163,11 @@ ] }, "locked": { - "lastModified": 1750680230, - "narHash": "sha256-kD88T/NqmcgfOBFAwphN30ccaUdj6K6+LG0XdM2w2LA=", + "lastModified": 1750903843, + "narHash": "sha256-Ng9+f0H5/dW+mq/XOKvB9uwvGbsuiiO6HrPdAcVglCs=", "owner": "nix-community", "repo": "disko", - "rev": "8fd2d6c75009ac75f9a6fb18c33a239806778d01", + "rev": "83c4da299c1d7d300f8c6fd3a72ac46cb0d59aae", "type": "github" }, "original": { @@ -393,11 +393,11 @@ "rust-overlay": "rust-overlay_2" }, "locked": { - "lastModified": 1750857684, - "narHash": "sha256-pbF4oz+HZE/rXsm9YOOA9aV/QnwTvc0zHDTpkaHpYK4=", + "lastModified": 1751148058, + "narHash": "sha256-8Zvw/xGpWtOXtz7l1ZDIHsX/TSnc34p38CEnYANwzRk=", "owner": "helix-editor", "repo": "helix", - "rev": "c3c4895179d4bc5a00e22fdf129d41c1af96226a", + "rev": "f75d71844f27a13b313603af42c58a5c6d6b608e", "type": "github" }, "original": { @@ -415,11 +415,11 @@ ] }, "locked": { - "lastModified": 1750730235, - "narHash": "sha256-rZErlxiV7ssvI8t7sPrKU+fRigNc2KvoKZG3gtUtK50=", + "lastModified": 1751238753, + "narHash": "sha256-hJUPWfz/h+QgXKaKovPwFAdNBnALsvVMggAPgBB+Qvw=", "owner": "nix-community", "repo": "home-manager", - "rev": "d07e9cceb4994ed64a22b9b36f8b76923e87ac38", + "rev": "cab8104e9236fab1eb9a702165454ffed353c20f", "type": "github" }, "original": { @@ -435,11 +435,11 @@ ] }, "locked": { - "lastModified": 1750798083, - "narHash": "sha256-DTCCcp6WCFaYXWKFRA6fiI2zlvOLCf5Vwx8+/0R8Wc4=", + "lastModified": 1751239699, + "narHash": "sha256-zA1uUdAq3c26fHm26xMWMuF5COhI18EzaH7az/P2OWM=", "owner": "nix-community", "repo": "home-manager", - "rev": "ff31a4677c1a8ae506aa7e003a3dba08cb203f82", + "rev": "f6deff178cc4d6049d30785dbfc831e6c6e3a219", "type": "github" }, "original": { @@ -473,11 +473,11 @@ "lix": { "flake": false, "locked": { - "lastModified": 1750762203, - "narHash": "sha256-LmQhjQ7c+AOkwhvR9GFgJOy8oHW35MoQRELtrwyVnPw=", - "rev": "38b358ce27203f972faa2973cf44ba80c758f46e", + "lastModified": 1751235704, + "narHash": "sha256-J4ycLoXHPsoBoQtEXFCelL4xlq5pT8U9tNWNKm43+YI=", + "rev": "1d7368585eebaa2c4bdbcb88fe600cfb2239b2c6", "type": "tarball", - "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/38b358ce27203f972faa2973cf44ba80c758f46e.tar.gz?rev=38b358ce27203f972faa2973cf44ba80c758f46e" + "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/1d7368585eebaa2c4bdbcb88fe600cfb2239b2c6.tar.gz?rev=1d7368585eebaa2c4bdbcb88fe600cfb2239b2c6" }, "original": { "type": "tarball", @@ -496,16 +496,16 @@ ] }, "locked": { - "lastModified": 1750776670, - "narHash": "sha256-EfA5K5EZAnspmraJrXQlziffVpaT+QDBiE6yKmuaNNQ=", - "ref": "release-2.93", - "rev": "c3c78a32273e89d28367d8605a4c880f0b6607e3", - "revCount": 146, + "lastModified": 1751240025, + "narHash": "sha256-SXUAlxpjPRkArRMHy5+Hdi+PiC+ND9yzzIjiaHmTvQU=", + "ref": "2.93.2-1", + "rev": "8b1094356f4723d6e89d3f8a95b333ee16d9ab02", + "revCount": 147, "type": "git", "url": "https://git.lix.systems/lix-project/nixos-module" }, "original": { - "ref": "release-2.93", + "ref": "2.93.2-1", "type": "git", "url": "https://git.lix.systems/lix-project/nixos-module" } @@ -522,11 +522,11 @@ "xwayland-satellite-unstable": "xwayland-satellite-unstable" }, "locked": { - "lastModified": 1750847367, - "narHash": "sha256-BQzKA0b7B73PRwgQLEs37w1YhLdCm49GB2RhR0Xjt0Y=", + "lastModified": 1751232679, + "narHash": "sha256-ljpyZxr5cHjJEXItXCoJVXJ+fiHTW1Ft0fPgEY72K5A=", "owner": "sodiboo", "repo": "niri-flake", - "rev": "bde02c6f392a7bfd487352a537183ebf2da7f53b", + "rev": "d9b7ff985e454c1b3d2af1c5d09e799ecd38902d", "type": "github" }, "original": { @@ -599,11 +599,11 @@ "rust-overlay": "rust-overlay_3" }, "locked": { - "lastModified": 1750849699, - "narHash": "sha256-MzTjtv7AcRwJRoU9shc+B3tW4Rr/HkdI+st3ThKVo+w=", + "lastModified": 1751195306, + "narHash": "sha256-rcrO38Qo9gDDWkEF8ZePf1mPw+MM42DgiK66eDH8i+U=", "owner": "lilyinstarlight", "repo": "nixos-cosmic", - "rev": "cfc96e2a5e57cbe1831c4b44f63cd66eb7743e42", + "rev": "0968e4f05337f6f2043b394b452ae0d38a4d5923", "type": "github" }, "original": { @@ -630,11 +630,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1750741721, - "narHash": "sha256-Z0djmTa1YmnGMfE9jEe05oO4zggjDmxOGKwt844bUhE=", + "lastModified": 1751011381, + "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4b1164c3215f018c4442463a27689d973cffd750", + "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", "type": "github" }, "original": { @@ -661,11 +661,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1750622754, - "narHash": "sha256-kMhs+YzV4vPGfuTpD3mwzibWUE6jotw5Al2wczI0Pv8=", + "lastModified": 1750969886, + "narHash": "sha256-zW/OFnotiz/ndPFdebpo3X0CrbVNf22n4DjN2vxlb58=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c7ab75210cb8cb16ddd8f290755d9558edde7ee1", + "rev": "a676066377a2fe7457369dd37c31fd2263b662f4", "type": "github" }, "original": { @@ -677,11 +677,11 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1750646418, - "narHash": "sha256-4UAN+W0Lp4xnUiHYXUXAPX18t+bn6c4Btry2RqM9JHY=", + "lastModified": 1750877742, + "narHash": "sha256-OrCy70x59VaBHxPZnm6A1wvQSdJvTz4i8Ngx40UeApI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1f426f65ac4e6bf808923eb6f8b8c2bfba3d18c5", + "rev": "f25c1bd2a6b33a4b1aa7aff56a94e0daab3773f0", "type": "github" }, "original": { @@ -693,11 +693,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1750741721, - "narHash": "sha256-Z0djmTa1YmnGMfE9jEe05oO4zggjDmxOGKwt844bUhE=", + "lastModified": 1751011381, + "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4b1164c3215f018c4442463a27689d973cffd750", + "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", "type": "github" }, "original": { @@ -709,11 +709,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1750741721, - "narHash": "sha256-Z0djmTa1YmnGMfE9jEe05oO4zggjDmxOGKwt844bUhE=", + "lastModified": 1751011381, + "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4b1164c3215f018c4442463a27689d973cffd750", + "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", "type": "github" }, "original": { @@ -768,11 +768,11 @@ "nur-rycee": { "flake": false, "locked": { - "lastModified": 1750824237, - "narHash": "sha256-jrJs7RMjB2P/V4y0n8qtN6EU5vId9W+6/le2XcRPg+4=", + "lastModified": 1751169806, + "narHash": "sha256-bq+FVbQZ61yhQP0Bb2bgBtu1Bidn4iaJfMCDqNkEQmQ=", "owner": "rycee", "repo": "nur-expressions", - "rev": "6d3d0527e3e273e9aaef9f5c433ef8046245fbb2", + "rev": "0dc3533f67cde2f338b5dd8c8b382c95c3287785", "type": "gitlab" }, "original": { @@ -812,11 +812,11 @@ ] }, "locked": { - "lastModified": 1750732748, - "narHash": "sha256-HR2b3RHsPeJm+Fb+1ui8nXibgniVj7hBNvUbXEyz0DU=", + "lastModified": 1751165203, + "narHash": "sha256-3QhlpAk2yn+ExwvRLtaixWsVW1q3OX3KXXe0l8VMLl4=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "4b4494b2ba7e8a8041b2e28320b2ee02c115c75f", + "rev": "90f547b90e73d3c6025e66c5b742d6db51c418c3", "type": "github" }, "original": { @@ -854,11 +854,11 @@ ] }, "locked": { - "lastModified": 1750819193, - "narHash": "sha256-XvkupGPZqD54HuKhN/2WhbKjAHeTl1UEnWspzUzRFfA=", + "lastModified": 1751165203, + "narHash": "sha256-3QhlpAk2yn+ExwvRLtaixWsVW1q3OX3KXXe0l8VMLl4=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "1ba3b9c59b68a4b00156827ad46393127b51b808", + "rev": "90f547b90e73d3c6025e66c5b742d6db51c418c3", "type": "github" }, "original": { @@ -915,11 +915,11 @@ "tinted-zed": "tinted-zed" }, "locked": { - "lastModified": 1750862951, - "narHash": "sha256-oUhnj0mzeSAX3IFaWn6LKLbmuFeNd7ulIAkxf0Jc07A=", + "lastModified": 1751145558, + "narHash": "sha256-OPlbpH64jzIspYqvJB96tnN9V9HBlAxROS5ijQwtN70=", "owner": "nix-community", "repo": "stylix", - "rev": "37b8c5f68086f36a109074c3fedebbbf8c20ecda", + "rev": "3a09d3f5cb940fa4142a2f3415b508a8be92b721", "type": "github" }, "original": { @@ -1066,11 +1066,11 @@ "nixpkgs": "nixpkgs_4" }, "locked": { - "lastModified": 1749194973, - "narHash": "sha256-eEy8cuS0mZ2j/r/FE0/LYBSBcIs/MKOIVakwHVuqTfk=", + "lastModified": 1750931469, + "narHash": "sha256-0IEdQB1nS+uViQw4k3VGUXntjkDp7aAlqcxdewb/hAc=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "a05be418a1af1198ca0f63facb13c985db4cb3c5", + "rev": "ac8e6f32e11e9c7f153823abc3ab007f2a65d3e1", "type": "github" }, "original": { @@ -1099,11 +1099,11 @@ "xwayland-satellite-unstable": { "flake": false, "locked": { - "lastModified": 1750821680, - "narHash": "sha256-Bu5unTxnqok2RoU5P394Gh0vRaoyI/5xlOOJDF6akrc=", + "lastModified": 1751228685, + "narHash": "sha256-MENtauGBhJ+kDeFaawvWGXaFG3Il6qQzjaP0RmtfM0k=", "owner": "Supreeeme", "repo": "xwayland-satellite", - "rev": "2e7c318ac2bbf699b6ab92ef91e661e16415dfac", + "rev": "557ebeb616e03d5e4a8049862bbbd1f02c6f020b", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index f99dc15..00b162e 100644 --- a/flake.nix +++ b/flake.nix @@ -39,7 +39,7 @@ # nixpkgs.follows = "nixos-cosmic/nixpkgs"; lix-module = { - url = "git+https://git.lix.systems/lix-project/nixos-module?ref=release-2.93"; + url = "git+https://git.lix.systems/lix-project/nixos-module?ref=2.93.2-1"; inputs = { nixpkgs.follows = "nixpkgs"; flake-utils.follows = "flake-utils"; diff --git a/overlays/modifications/default.nix b/overlays/modifications/default.nix index a555650..2f18ea8 100644 --- a/overlays/modifications/default.nix +++ b/overlays/modifications/default.nix @@ -11,8 +11,6 @@ in # ./QQ.nix ./helix.nix ./cliphist.nix - - ./fix-lix ] |> map (file: import file args) |> (overlays: (lib.composeManyExtensions overlays) final prev) diff --git a/overlays/modifications/fix-lix/default.nix b/overlays/modifications/fix-lix/default.nix deleted file mode 100644 index c1aa41c..0000000 --- a/overlays/modifications/fix-lix/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{...}: _final: prev: { - lix = prev.lix.overrideAttrs { - patches = [./fix-cve-2025-52992.diff]; - }; -} diff --git a/overlays/modifications/fix-lix/fix-cve-2025-52992.diff b/overlays/modifications/fix-lix/fix-cve-2025-52992.diff deleted file mode 100644 index a9d1b71..0000000 --- a/overlays/modifications/fix-lix/fix-cve-2025-52992.diff +++ /dev/null @@ -1,267 +0,0 @@ -diff --git a/doc/manual/rl-next/correct-cleanup-redirected-stores.md b/doc/manual/rl-next/correct-cleanup-redirected-stores.md -new file mode 100644 -index 000000000..a5d4a55a8 ---- /dev/null -+++ b/doc/manual/rl-next/correct-cleanup-redirected-stores.md -@@ -0,0 +1,18 @@ -+--- -+synopsis: "Correct cleanup in redirected stores" -+issues: [] -+cls: [3493] -+category: "Fixes" -+credits: ["horrors"] -+--- -+ -+Following CVE-2025-52992, the Lix team implemented automatic cleanup of -+*scratch outputs*, store paths written but not yet registered (e.g. -+`/nix/store/...`). -+ -+In setups using redirected stores, cleanup was mistakenly applied to the -+logical store path (always under `/nix/store`) rather than the actual physical -+location on disk. -+ -+This could result in accidental deletion from the system -+store instead of the intended redirected store. -diff --git a/doc/manual/rl-next/infallible-build-dirs.md b/doc/manual/rl-next/infallible-build-dirs.md -new file mode 100644 -index 000000000..563d4fcde ---- /dev/null -+++ b/doc/manual/rl-next/infallible-build-dirs.md -@@ -0,0 +1,25 @@ -+--- -+synopsis: "Fallback to safe temp dir when build-dir is unwritable" -+issues: [fj#876] -+cls: [3501] -+category: "Fixes" -+credits: ["raito", "horrors"] -+--- -+ -+Non-daemon builds started failing with a permission error after introducing the `build-dir` option: -+ -+``` -+$ nix build --store ~/scratch nixpkgs#hello --rebuild -+error: creating directory '/nix/var/nix/builds/nix-build-hello-2.12.2.drv-0': Permission denied -+``` -+ -+This happens because: -+ -+1. These builds are not run via the daemon, which owns `/nix/var/nix/builds`. -+2. The user lacks permissions for that path. -+ -+We considered making `build-dir` a store-level option and defaulting it to `/nix/var/nix/builds` for chroot stores, but opted instead for a fallback: if the default fails, Nix now creates a safe build directory under `/tmp`. -+ -+To avoid CVE-2025-52991, the fallback uses an extra path component between `/tmp` and the build dir. -+ -+**Note**: this fallback clutters `/tmp` with build directories that are not cleaned up. To prevent this, explicitly set `build-dir` to a path managed by Lix, even for local workloads. -diff --git a/doc/manual/rl-next/valid-outputs-deletion.md b/doc/manual/rl-next/valid-outputs-deletion.md -new file mode 100644 -index 000000000..f56112f41 ---- /dev/null -+++ b/doc/manual/rl-next/valid-outputs-deletion.md -@@ -0,0 +1,22 @@ -+--- -+synopsis: "Do not delete valid outputs after build" -+issues: [fj#883] -+cls: [3494] -+category: "Fixes" -+credits: ["horrors"] -+--- -+ -+In response to CVE-2025-52992, the Lix team introduced automatic deletion of -+*scratch outputs*, store paths written but not yet registered (e.g. in -+`/nix/store`). -+ -+However, the control flow distinguishing scratch outputs from valid ones is -+complex. A logic error caused valid outputs, especially those obtained via -+closure copies (e.g. remote builds), to be deleted post-build. -+ -+This led to breakage in Lix and could potentially render entire systems -+unusable by removing critical libraries. -+ -+We are sorry for the severity of this bug and are taking steps to prevent its -+recurrence. If your system is affected, please reach out on our support -+channels for recovery assistance. -diff --git a/lix/libstore/build/local-derivation-goal.cc b/lix/libstore/build/local-derivation-goal.cc -index c866a3b66..247943e5c 100644 ---- a/lix/libstore/build/local-derivation-goal.cc -+++ b/lix/libstore/build/local-derivation-goal.cc -@@ -487,17 +487,47 @@ try { - }); - } - -- createDirs(settings.buildDir.get()); -- -- /* Create a temporary directory where the build will take -- place. */ -- tmpDir = createTempDir( -- settings.buildDir.get(), -- "nix-build-" + std::string(drvPath.name()), -- false, -- false, -- 0700 -- ); -+ try { -+ auto buildDir = worker.buildDirOverride.value_or(settings.buildDir.get()); -+ -+ createDirs(buildDir); -+ -+ /* Create a temporary directory where the build will take -+ place. */ -+ tmpDir = -+ createTempDir(buildDir, "nix-build-" + std::string(drvPath.name()), false, false, 0700); -+ } catch (SysError & e) { -+ /* -+ * Fallback to the global tmpdir and create a safe space there -+ * only if it's a permission error. -+ */ -+ if (e.errNo != EACCES) { -+ throw; -+ } -+ -+ auto globalTmp = defaultTempDir(); -+ createDirs(globalTmp); -+#if __APPLE__ -+ /* macOS filesystem namespacing does not exist, to avoid breaking builds, we need to weaken -+ * the mode bits on the top-level directory. This avoids issues like -+ * https://github.com/NixOS/nix/pull/11031. */ -+ constexpr int toplevelDirMode = 0755; -+#else -+ constexpr int toplevelDirMode = 0700; -+#endif -+ auto nixBuildsTmp = -+ createTempDir(globalTmp, fmt("nix-builds-%s", geteuid()), false, false, toplevelDirMode); -+ warn( -+ "Failed to use the system-wide build directory '%s', falling back to a temporary " -+ "directory inside '%s'", -+ settings.buildDir.get(), -+ nixBuildsTmp -+ ); -+ worker.buildDirOverride = nixBuildsTmp; -+ tmpDir = createTempDir( -+ nixBuildsTmp, "nix-build-" + std::string(drvPath.name()), false, false, 0700 -+ ); -+ } - /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to - * POSIX semantics.*/ - tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)}; -@@ -538,7 +568,9 @@ try { - /* Schedule this scratch output path for automatic deletion - * if we do not cancel it, e.g. when registering the outputs. - */ -- scratchOutputsCleaner.insert_or_assign(outputName, worker.store.printStorePath(scratchPath)); -+ scratchOutputsCleaner.emplace( -+ outputName, worker.store.toRealPath(worker.store.printStorePath(scratchPath)) -+ ); - - /* Substitute output placeholders with the scratch output paths. - We'll use during the build. */ -@@ -1739,6 +1771,11 @@ try { - before this for loop. */ - if (*scratchPath != finalStorePath) - outputRewrites[std::string { scratchPath->hashPart() }] = std::string { finalStorePath.hashPart() }; -+ /* Cancel automatic deletion of that output if it was a scratch output that we just -+ * registered. */ -+ if (auto cleaner = scratchOutputsCleaner.extract(outputName)) { -+ cleaner.mapped().cancel(); -+ } - }; - - auto orifu = get(outputReferencesIfUnregistered, outputName); -@@ -2063,10 +2100,6 @@ try { - the next iteration */ - if (newInfo.ca) { - TRY_AWAIT(localStore.registerValidPaths({{newInfo.path, newInfo}})); -- /* Cancel automatic deletion of that output if it was a scratch output. */ -- if (auto cleaner = scratchOutputsCleaner.extract(outputName)) { -- cleaner.mapped().cancel(); -- } - } - - infos.emplace(outputName, std::move(newInfo)); -@@ -2107,13 +2140,6 @@ try { - infos2.insert_or_assign(newInfo.path, newInfo); - } - TRY_AWAIT(localStore.registerValidPaths(infos2)); -- -- /* Cancel automatic deletion of that output if it was a scratch output that we just registered. */ -- for (auto & [outputName, _ ] : infos) { -- if (auto cleaner = scratchOutputsCleaner.extract(outputName)) { -- cleaner.mapped().cancel(); -- } -- } - } - - /* In case of a fixed-output derivation hash mismatch, throw an -diff --git a/lix/libstore/build/worker.hh b/lix/libstore/build/worker.hh -index 7fc3d1fe9..d9dc36e34 100644 ---- a/lix/libstore/build/worker.hh -+++ b/lix/libstore/build/worker.hh -@@ -195,6 +195,7 @@ public: - Store & store; - Store & evalStore; - AsyncSemaphore substitutions, localBuilds; -+ std::optional buildDirOverride; - - private: - kj::TaskSet children; -diff --git a/tests/functional/build.sh b/tests/functional/build.sh -index 58fba83aa..fc83f61f3 100644 ---- a/tests/functional/build.sh -+++ b/tests/functional/build.sh -@@ -174,3 +174,8 @@ test "$(<<<"$out" grep -E '^error:' | wc -l)" = 3 - <<<"$out" grepQuiet -E "error: 2 dependencies of derivation '.*-x4\\.drv' failed to build" - <<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x3\\.drv'" - <<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x2\\.drv'" -+ -+# Ensure when if the system build dir is inaccessible, we can still build things -+BUILD_DIR=$(mktemp -d) -+chmod 0000 "$BUILD_DIR" -+nix --build-dir "$BUILD_DIR" build -E 'with import ./config.nix; mkDerivation { name = "test"; buildCommand = "echo rawr > $out"; }' --impure --no-link -diff --git a/tests/functional/linux-sandbox.sh b/tests/functional/linux-sandbox.sh -index 82f363a09..526605e5f 100644 ---- a/tests/functional/linux-sandbox.sh -+++ b/tests/functional/linux-sandbox.sh -@@ -81,3 +81,10 @@ testCert present fixed-output "$certsymlink" - - # Symlinks should be added in the sandbox directly and not followed - nix-sandbox-build symlink-derivation.nix -+ -+# Regression fj#883: derivations outputs disappearing after rebuild -+# build the derivation for both its outputs and delete one of them. -+# simulates substitution or copying only one output from a builder. -+nix-store --delete $(nix-sandbox-build --no-out-link ./regression-fj883.nix -A base.lib) -+# build a derivation depending on previous one. this should succeed -+nix-sandbox-build --no-out-link ./regression-fj883.nix -A downstream -diff --git a/tests/functional/regression-fj883.nix b/tests/functional/regression-fj883.nix -new file mode 100644 -index 000000000..2317145b7 ---- /dev/null -+++ b/tests/functional/regression-fj883.nix -@@ -0,0 +1,15 @@ -+with import ./config.nix; -+ -+rec { -+ base = mkDerivation { -+ name = "base"; -+ outputs = [ "out" "lib" ]; -+ buildCommand = "echo > $out; echo > $lib"; -+ }; -+ -+ downstream = mkDerivation { -+ name = "downstream"; -+ deps = [ base.out base.lib ]; -+ buildCommand = "echo $deps > $out"; -+ }; -+} -diff --git a/version.json b/version.json -index 22b83defe..a39a6e7e2 100644 ---- a/version.json -+++ b/version.json -@@ -1,5 +1,5 @@ - { -- "version": "2.93.1", -- "official_release": true, -+ "version": "2.93.2", -+ "official_release": false, - "release_name": "Bici Bici" - }