diff --git a/flake.lock b/flake.lock index 1ea5788..d83cf0b 100644 --- a/flake.lock +++ b/flake.lock @@ -96,11 +96,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1751243689, - "narHash": "sha256-yWwH1pb06X9r9qmJCqLrsUpT+1lI+CEAD30MpaJ7FVU=", + "lastModified": 1750854959, + "narHash": "sha256-aL8Nu/gDUwMZpCsf1Crx+tT24yE+Fa8n0+hVjFKOpQQ=", "owner": "chaotic-cx", "repo": "nyx", - "rev": "b9f4e747234d73a7e9c45ba0c30cbb46311dbdf3", + "rev": "c417f3d4efc3042682c54631c975d554481a3bdb", "type": "github" }, "original": { @@ -163,11 +163,11 @@ ] }, "locked": { - "lastModified": 1750903843, - "narHash": "sha256-Ng9+f0H5/dW+mq/XOKvB9uwvGbsuiiO6HrPdAcVglCs=", + "lastModified": 1750680230, + "narHash": "sha256-kD88T/NqmcgfOBFAwphN30ccaUdj6K6+LG0XdM2w2LA=", "owner": "nix-community", "repo": "disko", - "rev": "83c4da299c1d7d300f8c6fd3a72ac46cb0d59aae", + "rev": "8fd2d6c75009ac75f9a6fb18c33a239806778d01", "type": "github" }, "original": { @@ -393,11 +393,11 @@ "rust-overlay": "rust-overlay_2" }, "locked": { - "lastModified": 1751148058, - "narHash": "sha256-8Zvw/xGpWtOXtz7l1ZDIHsX/TSnc34p38CEnYANwzRk=", + "lastModified": 1750857684, + "narHash": "sha256-pbF4oz+HZE/rXsm9YOOA9aV/QnwTvc0zHDTpkaHpYK4=", "owner": "helix-editor", "repo": "helix", - "rev": "f75d71844f27a13b313603af42c58a5c6d6b608e", + "rev": "c3c4895179d4bc5a00e22fdf129d41c1af96226a", "type": "github" }, "original": { @@ -415,11 +415,11 @@ ] }, "locked": { - "lastModified": 1751238753, - "narHash": "sha256-hJUPWfz/h+QgXKaKovPwFAdNBnALsvVMggAPgBB+Qvw=", + "lastModified": 1750730235, + "narHash": "sha256-rZErlxiV7ssvI8t7sPrKU+fRigNc2KvoKZG3gtUtK50=", "owner": "nix-community", "repo": "home-manager", - "rev": "cab8104e9236fab1eb9a702165454ffed353c20f", + "rev": "d07e9cceb4994ed64a22b9b36f8b76923e87ac38", "type": "github" }, "original": { @@ -435,11 +435,11 @@ ] }, "locked": { - "lastModified": 1751239699, - "narHash": "sha256-zA1uUdAq3c26fHm26xMWMuF5COhI18EzaH7az/P2OWM=", + "lastModified": 1750798083, + "narHash": "sha256-DTCCcp6WCFaYXWKFRA6fiI2zlvOLCf5Vwx8+/0R8Wc4=", "owner": "nix-community", "repo": "home-manager", - "rev": "f6deff178cc4d6049d30785dbfc831e6c6e3a219", + "rev": "ff31a4677c1a8ae506aa7e003a3dba08cb203f82", "type": "github" }, "original": { @@ -473,11 +473,11 @@ "lix": { "flake": false, "locked": { - "lastModified": 1751235704, - "narHash": "sha256-J4ycLoXHPsoBoQtEXFCelL4xlq5pT8U9tNWNKm43+YI=", - "rev": "1d7368585eebaa2c4bdbcb88fe600cfb2239b2c6", + "lastModified": 1750762203, + "narHash": "sha256-LmQhjQ7c+AOkwhvR9GFgJOy8oHW35MoQRELtrwyVnPw=", + "rev": "38b358ce27203f972faa2973cf44ba80c758f46e", "type": "tarball", - "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/1d7368585eebaa2c4bdbcb88fe600cfb2239b2c6.tar.gz?rev=1d7368585eebaa2c4bdbcb88fe600cfb2239b2c6" + "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/38b358ce27203f972faa2973cf44ba80c758f46e.tar.gz?rev=38b358ce27203f972faa2973cf44ba80c758f46e" }, "original": { "type": "tarball", @@ -496,16 +496,16 @@ ] }, "locked": { - "lastModified": 1751240025, - "narHash": "sha256-SXUAlxpjPRkArRMHy5+Hdi+PiC+ND9yzzIjiaHmTvQU=", - "ref": "2.93.2-1", - "rev": "8b1094356f4723d6e89d3f8a95b333ee16d9ab02", - "revCount": 147, + "lastModified": 1750776670, + "narHash": "sha256-EfA5K5EZAnspmraJrXQlziffVpaT+QDBiE6yKmuaNNQ=", + "ref": "release-2.93", + "rev": "c3c78a32273e89d28367d8605a4c880f0b6607e3", + "revCount": 146, "type": "git", "url": "https://git.lix.systems/lix-project/nixos-module" }, "original": { - "ref": "2.93.2-1", + "ref": "release-2.93", "type": "git", "url": "https://git.lix.systems/lix-project/nixos-module" } @@ -522,11 +522,11 @@ "xwayland-satellite-unstable": "xwayland-satellite-unstable" }, "locked": { - "lastModified": 1751232679, - "narHash": "sha256-ljpyZxr5cHjJEXItXCoJVXJ+fiHTW1Ft0fPgEY72K5A=", + "lastModified": 1750847367, + "narHash": "sha256-BQzKA0b7B73PRwgQLEs37w1YhLdCm49GB2RhR0Xjt0Y=", "owner": "sodiboo", "repo": "niri-flake", - "rev": "d9b7ff985e454c1b3d2af1c5d09e799ecd38902d", + "rev": "bde02c6f392a7bfd487352a537183ebf2da7f53b", "type": "github" }, "original": { @@ -599,11 +599,11 @@ "rust-overlay": "rust-overlay_3" }, "locked": { - "lastModified": 1751195306, - "narHash": "sha256-rcrO38Qo9gDDWkEF8ZePf1mPw+MM42DgiK66eDH8i+U=", + "lastModified": 1750849699, + "narHash": "sha256-MzTjtv7AcRwJRoU9shc+B3tW4Rr/HkdI+st3ThKVo+w=", "owner": "lilyinstarlight", "repo": "nixos-cosmic", - "rev": "0968e4f05337f6f2043b394b452ae0d38a4d5923", + "rev": "cfc96e2a5e57cbe1831c4b44f63cd66eb7743e42", "type": "github" }, "original": { @@ -630,11 +630,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1751011381, - "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", + "lastModified": 1750741721, + "narHash": "sha256-Z0djmTa1YmnGMfE9jEe05oO4zggjDmxOGKwt844bUhE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", + "rev": "4b1164c3215f018c4442463a27689d973cffd750", "type": "github" }, "original": { @@ -661,11 +661,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1750969886, - "narHash": "sha256-zW/OFnotiz/ndPFdebpo3X0CrbVNf22n4DjN2vxlb58=", + "lastModified": 1750622754, + "narHash": "sha256-kMhs+YzV4vPGfuTpD3mwzibWUE6jotw5Al2wczI0Pv8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a676066377a2fe7457369dd37c31fd2263b662f4", + "rev": "c7ab75210cb8cb16ddd8f290755d9558edde7ee1", "type": "github" }, "original": { @@ -677,11 +677,11 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1750877742, - "narHash": "sha256-OrCy70x59VaBHxPZnm6A1wvQSdJvTz4i8Ngx40UeApI=", + "lastModified": 1750646418, + "narHash": "sha256-4UAN+W0Lp4xnUiHYXUXAPX18t+bn6c4Btry2RqM9JHY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f25c1bd2a6b33a4b1aa7aff56a94e0daab3773f0", + "rev": "1f426f65ac4e6bf808923eb6f8b8c2bfba3d18c5", "type": "github" }, "original": { @@ -693,11 +693,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1751011381, - "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", + "lastModified": 1750741721, + "narHash": "sha256-Z0djmTa1YmnGMfE9jEe05oO4zggjDmxOGKwt844bUhE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", + "rev": "4b1164c3215f018c4442463a27689d973cffd750", "type": "github" }, "original": { @@ -709,11 +709,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1751011381, - "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", + "lastModified": 1750741721, + "narHash": "sha256-Z0djmTa1YmnGMfE9jEe05oO4zggjDmxOGKwt844bUhE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", + "rev": "4b1164c3215f018c4442463a27689d973cffd750", "type": "github" }, "original": { @@ -768,11 +768,11 @@ "nur-rycee": { "flake": false, "locked": { - "lastModified": 1751169806, - "narHash": "sha256-bq+FVbQZ61yhQP0Bb2bgBtu1Bidn4iaJfMCDqNkEQmQ=", + "lastModified": 1750824237, + "narHash": "sha256-jrJs7RMjB2P/V4y0n8qtN6EU5vId9W+6/le2XcRPg+4=", "owner": "rycee", "repo": "nur-expressions", - "rev": "0dc3533f67cde2f338b5dd8c8b382c95c3287785", + "rev": "6d3d0527e3e273e9aaef9f5c433ef8046245fbb2", "type": "gitlab" }, "original": { @@ -812,11 +812,11 @@ ] }, "locked": { - "lastModified": 1751165203, - "narHash": "sha256-3QhlpAk2yn+ExwvRLtaixWsVW1q3OX3KXXe0l8VMLl4=", + "lastModified": 1750732748, + "narHash": "sha256-HR2b3RHsPeJm+Fb+1ui8nXibgniVj7hBNvUbXEyz0DU=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "90f547b90e73d3c6025e66c5b742d6db51c418c3", + "rev": "4b4494b2ba7e8a8041b2e28320b2ee02c115c75f", "type": "github" }, "original": { @@ -854,11 +854,11 @@ ] }, "locked": { - "lastModified": 1751165203, - "narHash": "sha256-3QhlpAk2yn+ExwvRLtaixWsVW1q3OX3KXXe0l8VMLl4=", + "lastModified": 1750819193, + "narHash": "sha256-XvkupGPZqD54HuKhN/2WhbKjAHeTl1UEnWspzUzRFfA=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "90f547b90e73d3c6025e66c5b742d6db51c418c3", + "rev": "1ba3b9c59b68a4b00156827ad46393127b51b808", "type": "github" }, "original": { @@ -915,11 +915,11 @@ "tinted-zed": "tinted-zed" }, "locked": { - "lastModified": 1751145558, - "narHash": "sha256-OPlbpH64jzIspYqvJB96tnN9V9HBlAxROS5ijQwtN70=", + "lastModified": 1750862951, + "narHash": "sha256-oUhnj0mzeSAX3IFaWn6LKLbmuFeNd7ulIAkxf0Jc07A=", "owner": "nix-community", "repo": "stylix", - "rev": "3a09d3f5cb940fa4142a2f3415b508a8be92b721", + "rev": "37b8c5f68086f36a109074c3fedebbbf8c20ecda", "type": "github" }, "original": { @@ -1066,11 +1066,11 @@ "nixpkgs": "nixpkgs_4" }, "locked": { - "lastModified": 1750931469, - "narHash": "sha256-0IEdQB1nS+uViQw4k3VGUXntjkDp7aAlqcxdewb/hAc=", + "lastModified": 1749194973, + "narHash": "sha256-eEy8cuS0mZ2j/r/FE0/LYBSBcIs/MKOIVakwHVuqTfk=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "ac8e6f32e11e9c7f153823abc3ab007f2a65d3e1", + "rev": "a05be418a1af1198ca0f63facb13c985db4cb3c5", "type": "github" }, "original": { @@ -1099,11 +1099,11 @@ "xwayland-satellite-unstable": { "flake": false, "locked": { - "lastModified": 1751228685, - "narHash": "sha256-MENtauGBhJ+kDeFaawvWGXaFG3Il6qQzjaP0RmtfM0k=", + "lastModified": 1750821680, + "narHash": "sha256-Bu5unTxnqok2RoU5P394Gh0vRaoyI/5xlOOJDF6akrc=", "owner": "Supreeeme", "repo": "xwayland-satellite", - "rev": "557ebeb616e03d5e4a8049862bbbd1f02c6f020b", + "rev": "2e7c318ac2bbf699b6ab92ef91e661e16415dfac", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 00b162e..f99dc15 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=2.93.2-1"; + url = "git+https://git.lix.systems/lix-project/nixos-module?ref=release-2.93"; inputs = { nixpkgs.follows = "nixpkgs"; flake-utils.follows = "flake-utils"; diff --git a/home/modules/programs/alacritty/alacritty.toml b/home/modules/programs/alacritty/alacritty.toml index 4db938e..be05835 100644 --- a/home/modules/programs/alacritty/alacritty.toml +++ b/home/modules/programs/alacritty/alacritty.toml @@ -25,3 +25,4 @@ osc52 = "CopyPaste" [mouse] hide_when_typing = true + diff --git a/nixos/modules/gui/niri.nix b/nixos/modules/gui/niri.nix index e47747b..54e71e8 100644 --- a/nixos/modules/gui/niri.nix +++ b/nixos/modules/gui/niri.nix @@ -35,9 +35,6 @@ in { mime = { enable = true; defaultApplications = { - "application/pdf" = [ - "org.gnome.Evince.desktop" - ]; "inode/directory" = [ "com.system76.CosmicFiles.desktop" ]; diff --git a/overlays/modifications/default.nix b/overlays/modifications/default.nix index 2f18ea8..a555650 100644 --- a/overlays/modifications/default.nix +++ b/overlays/modifications/default.nix @@ -11,6 +11,8 @@ 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 new file mode 100644 index 0000000..c1aa41c --- /dev/null +++ b/overlays/modifications/fix-lix/default.nix @@ -0,0 +1,5 @@ +{...}: _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 new file mode 100644 index 0000000..a9d1b71 --- /dev/null +++ b/overlays/modifications/fix-lix/fix-cve-2025-52992.diff @@ -0,0 +1,267 @@ +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" + }