Skip to content

Commit

Permalink
Merge pull request #9261 from flokli/backport-3564
Browse files Browse the repository at this point in the history
[2.3-maintenance] Wait for build users when none are available
  • Loading branch information
Ericson2314 authored Nov 2, 2023
2 parents 791af78 + 12935e5 commit f769904
Showing 1 changed file with 36 additions and 26 deletions.
62 changes: 36 additions & 26 deletions src/libstore/build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -524,17 +524,24 @@ class UserLock
uid_t getGID() { assert(gid); return gid; }
std::vector<gid_t> getSupplementaryGIDs() { return supplementaryGIDs; }

bool findFreeUser();

bool enabled() { return uid != 0; }

};


Sync<PathSet> UserLock::lockedPaths_;


UserLock::UserLock()
{
assert(settings.buildUsersGroup != "");
createDirs(settings.nixStateDir + "/userpool");
/* Mark that user is not enabled by default */
uid = 0;
}

bool UserLock::findFreeUser() {

/* Get the members of the build-users-group. */
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
Expand Down Expand Up @@ -564,7 +571,6 @@ UserLock::UserLock()
throw Error(format("the user '%1%' in the group '%2%' does not exist")
% i % settings.buildUsersGroup);

createDirs(settings.nixStateDir + "/userpool");

fnUserLock = (format("%1%/userpool/%2%") % settings.nixStateDir % pw->pw_uid).str();

Expand Down Expand Up @@ -605,28 +611,24 @@ UserLock::UserLock()
supplementaryGIDs.resize(ngroups);
#endif

return;
return true;
}

} catch (...) {
lockedPaths_.lock()->erase(fnUserLock);
return false;
}
}

throw Error(format("all build users are currently in use; "
"consider creating additional users and adding them to the '%1%' group")
% settings.buildUsersGroup);
return false;
}


UserLock::~UserLock()
{
auto lockedPaths(lockedPaths_.lock());
assert(lockedPaths->count(fnUserLock));
lockedPaths->erase(fnUserLock);
}


void UserLock::kill()
{
killUser(uid);
Expand Down Expand Up @@ -1415,6 +1417,30 @@ void DerivationGoal::tryToBuild()
{
trace("trying to build");

/* If `build-users-group' is not empty, then we have to build as
one of the members of that group. */
if (settings.buildUsersGroup != "" && getuid() == 0) {
#if defined(__linux__) || defined(__APPLE__)
if (!buildUser) buildUser = std::make_unique<UserLock>();

if (!buildUser->enabled()) {
if (!buildUser->findFreeUser()) {
debug("waiting for build users");
worker.waitForAWhile(shared_from_this());
return;
}

/* Make sure that no other processes are executing under this
uid. */
buildUser->kill();
}
#else
/* Don't know how to block the creation of setuid/setgid
binaries on this platform. */
throw Error("build users are not supported on this platform for security reasons");
#endif
}

/* Obtain locks on all output paths. The locks are automatically
released when we exit this function or Nix crashes. If we
can't acquire the lock, then continue; hopefully some other
Expand Down Expand Up @@ -1931,22 +1957,6 @@ void DerivationGoal::startBuilder()
#endif
}

/* If `build-users-group' is not empty, then we have to build as
one of the members of that group. */
if (settings.buildUsersGroup != "" && getuid() == 0) {
#if defined(__linux__) || defined(__APPLE__)
buildUser = std::make_unique<UserLock>();

/* Make sure that no other processes are executing under this
uid. */
buildUser->kill();
#else
/* Don't know how to block the creation of setuid/setgid
binaries on this platform. */
throw Error("build users are not supported on this platform for security reasons");
#endif
}

/* Create a temporary directory where the build will take
place. */
auto drvName = storePathToName(drvPath);
Expand Down Expand Up @@ -4465,7 +4475,7 @@ void Worker::waitForInput()
if (!waitingForAWhile.empty()) {
useTimeout = true;
if (lastWokenUp == steady_time_point::min())
printError("waiting for locks or build slots...");
printError("waiting for locks, build slots or build users...");
if (lastWokenUp == steady_time_point::min() || lastWokenUp > before) lastWokenUp = before;
timeout.tv_sec = std::max(1L,
(long) std::chrono::duration_cast<std::chrono::seconds>(
Expand Down

0 comments on commit f769904

Please sign in to comment.