From 7fceee3ce381fd7b8b0a88f89d178a7fb7eb2769 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Wed, 26 Mar 2025 01:04:59 +0100 Subject: [PATCH] libstore: open build directory as a dirfd as well We now keep around a proper AutoCloseFD around the temporary directory which we plan to use for openat operations and avoiding the build directory being swapped out while we are doing something else. Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a Signed-off-by: Raito Bezarius --- lix/libstore/build/local-derivation-goal.cc | 13 ++++++++++++- lix/libstore/build/local-derivation-goal.hh | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lix/libstore/build/local-derivation-goal.cc b/lix/libstore/build/local-derivation-goal.cc index 625f33cba..1f8a87eff 100644 --- a/lix/libstore/build/local-derivation-goal.cc +++ b/lix/libstore/build/local-derivation-goal.cc @@ -482,7 +482,18 @@ kj::Promise> LocalDerivationGoal::startBuilder() /* Create a temporary directory where the build will take place. */ - tmpDir = createTempDir(settings.buildDir.get().value_or(""), "nix-build-" + std::string(drvPath.name()), false, false, 0700); + tmpDir = createTempDir( + settings.buildDir.get().value_or(""), + "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)}; + if (!tmpDirFd) + throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir); chownToBuilder(tmpDir); diff --git a/lix/libstore/build/local-derivation-goal.hh b/lix/libstore/build/local-derivation-goal.hh index 96f0c41a0..67677a111 100644 --- a/lix/libstore/build/local-derivation-goal.hh +++ b/lix/libstore/build/local-derivation-goal.hh @@ -31,6 +31,11 @@ struct LocalDerivationGoal : public DerivationGoal */ Path tmpDir; + /** + * The temporary directory file descriptor + */ + AutoCloseFD tmpDirFd; + /** * The path of the temporary directory in the sandbox. */