From c87a9b855e12fafbafcd2af37fd53374cf965ce8 Mon Sep 17 00:00:00 2001 From: Reepca Russelstein Date: Fri, 5 Sep 2025 01:59:12 -0500 Subject: daemon: Restore post-canonicalization permissions after moving. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At this point the value of 'st.st_mode' is from before canonicalization, so restoring to that will undo the permissions aspect of the canonicalization for a top-level directory store item. Fixes #1104, introduced in ae18b3d9e6 (https://codeberg.org/guix/guix/commit/ae18b3d9e6bd0c184505a094851448d08555e23e). * nix/libstore/build.cc (DerivationGoal::registerOutputs): update 'st' with post-canonicalization permissions before making actualPath temporarily-writable. * tests/store.scm ("build outputs aren't writable"): new test. Change-Id: I5e5eaa79fa6b7f81e1d12fd285883c762a22ce5a Signed-off-by: Ludovic Courtès --- nix/libstore/build.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'nix') diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 0a4de96d51d..a48214a9c0a 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -3139,10 +3139,14 @@ void DerivationGoal::registerOutputs() replaceValidPath(path, actualPath); else if (buildMode != bmCheck) { - if (S_ISDIR(st.st_mode)) + if (S_ISDIR(st.st_mode)) { + if (lstat(actualPath.c_str(), &st) == -1) + throw SysError(format("getting canonicalized permissions of directory `%1%'") % actualPath); /* Change mode on the directory to allow for rename(2). */ - chmod(actualPath.c_str(), st.st_mode | 0700); + if (chmod(actualPath.c_str(), st.st_mode | 0700) == -1) + throw SysError(format("making `%1%' writable for move from chroot to store") % actualPath); + } if (rename(actualPath.c_str(), path.c_str()) == -1) throw SysError(format("moving build output `%1%' from the chroot to the store") % path); if (S_ISDIR(st.st_mode) && chmod(path.c_str(), st.st_mode) == -1) -- cgit v1.3