From 92eb418a5923690ec0785a1d874bcc5a11be1ff1 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Wed, 26 Mar 2025 01:05:34 +0100 Subject: [PATCH] libstore: chown to builder variant for file descriptors We use it immediately for the build temporary directory. Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947 Signed-off-by: Raito Bezarius --- lix/libstore/build/local-derivation-goal.cc | 9 ++++++++- lix/libstore/build/local-derivation-goal.hh | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lix/libstore/build/local-derivation-goal.cc b/lix/libstore/build/local-derivation-goal.cc index 1f8a87eff..f7512c234 100644 --- a/lix/libstore/build/local-derivation-goal.cc +++ b/lix/libstore/build/local-derivation-goal.cc @@ -495,7 +495,7 @@ kj::Promise> LocalDerivationGoal::startBuilder() if (!tmpDirFd) throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir); - chownToBuilder(tmpDir); + chownToBuilder(tmpDirFd); for (auto & [outputName, status] : initialOutputs) { /* Set scratch path we'll actually use during the build. @@ -1371,6 +1371,13 @@ void LocalDerivationGoal::chownToBuilder(const Path & path) throw SysError("cannot change ownership of '%1%'", path); } +void LocalDerivationGoal::chownToBuilder(const AutoCloseFD & fd) +{ + if (!buildUser) return; + if (fchown(fd.get(), buildUser->getUID(), buildUser->getGID()) == -1) + throw SysError("cannot change ownership of file '%1%'", fd.guessOrInventPath()); +} + void LocalDerivationGoal::runChild() { diff --git a/lix/libstore/build/local-derivation-goal.hh b/lix/libstore/build/local-derivation-goal.hh index 67677a111..6ba8c281a 100644 --- a/lix/libstore/build/local-derivation-goal.hh +++ b/lix/libstore/build/local-derivation-goal.hh @@ -251,10 +251,18 @@ struct LocalDerivationGoal : public DerivationGoal void addDependency(const StorePath & path); /** - * Make a file owned by the builder. + * Make a file owned by the builder addressed by its path. + * + * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor. + * It's only safe to call in a child of a directory only visible to the owner. */ void chownToBuilder(const Path & path); + /** + * Make a file owned by the builder addressed by its file descriptor. + */ + void chownToBuilder(const AutoCloseFD & fd); + int getChildStatus() override; /**