From ca03f7379050c93a51fadb00659481180572157c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Sat, 12 Jul 2025 11:42:04 +0200 Subject: [PATCH] daemon: Tolerate pipes and sockets in failed build trees. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes . Fixes guix/guix#471. Fixes a bug introduced in ae18b3d9e6bd0c184505a094851448d08555e23e whereby interrupting ‘guix build -K hello’ would leave a build directory with root ownership due ‘secureFilePerms’ bailing out due to the presence of FIFOs in the temporary build directory. * nix/libstore/build.cc (secureFilePerms): Add ‘allowSpecialFiles’ parameter; honor it and pass it in recursive call. (DerivationGoal::deleteTmpDir): Pass true as the second argument to ‘secureFilePerms’. Reported-by: Janneke Nieuwenhuizen Reported-by: David Elsing Change-Id: I638a4ee909a2b5022f9153e1cbb832bfb2e15263 --- nix/libstore/build.cc | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index e77869fc3e..0a4de96d51 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -1318,8 +1318,9 @@ MakeError(NotDeterministic, BuildError) /* Recursively make the file permissions of a path safe for exposure to arbitrary users, but without canonicalising its permissions, timestamp, and user. Throw an exception if a file type that isn't explicitly known to be - safe is found. */ -static void secureFilePerms(Path path) + safe is found; when 'allowSpecialFiles' is true, pipes and sockets are + allowed. */ +static void secureFilePerms(Path path, bool allowSpecialFiles = false) { struct stat st; if (lstat(path.c_str(), &st)) return; @@ -1330,7 +1331,7 @@ static void secureFilePerms(Path path) case S_IFDIR: for (auto & i : readDirectory(path)) { - secureFilePerms(path + "/" + i.name); + secureFilePerms(path + "/" + i.name, allowSpecialFiles); } /* FALLTHROUGH */ @@ -1338,6 +1339,14 @@ static void secureFilePerms(Path path) chmod(path.c_str(), (st.st_mode & ~S_IFMT) & ~(S_ISUID | S_ISGID | S_IWOTH)); break; + case S_IFSOCK: + case S_IFIFO: + if (allowSpecialFiles) { + chmod(path.c_str(), (st.st_mode & ~S_IFMT) & ~(S_ISUID | S_ISGID | S_IWOTH)); + break; + } + /* FALLTHROUGH */ + default: throw Error(format("file `%1%' has an unsupported type") % path); } @@ -3401,8 +3410,9 @@ void DerivationGoal::deleteTmpDir(bool force) gid_t gid = settings.clientGid != 0 ? settings.clientGid : -1; bool reown = false; - /* First remove setuid/setgid bits. */ - secureFilePerms(tmpDir); + /* First remove setuid/setgid bits. Allow sockets and pipes + in the build directory. */ + secureFilePerms(tmpDir, true); try { _chown(tmpDir, uid, gid);