libstore: move tmpDirInSandbox, enable-core-dumps, buildUser into capnp

since we're using tmpDirInSandbox as the working directory for the new
process we also rename it accordingly. buildUser likewise turns into a
different Credentials type because exposing user lock state seems odd.

Change-Id: Id4a1a6eb733f774c893f373b91c2a271a4b84185
This commit is contained in:
eldritch horrors
2026-02-02 18:26:57 +01:00
parent ac7a622b38
commit 0cc9d01ad0
2 changed files with 39 additions and 12 deletions
+29 -12
View File
@@ -931,6 +931,18 @@ try {
RPC_FILL(request, setBuilder, builder);
RPC_FILL(request, initArgs, args);
RPC_FILL(request, initEnvironment, envStrs);
RPC_FILL(request, setWorkingDir, tmpDirInSandbox);
request.setEnableCoreDumps(settings.enableCoreDumps);
if (buildUser) {
auto creds = request.initCredentials();
creds.setUid(buildUser->getUID());
creds.setGid(buildUser->getGID());
creds.setUidCount(buildUser->getUIDCount());
static_assert(std::is_same_v<uid_t, decltype(creds.getUid())>);
static_assert(std::is_same_v<gid_t, decltype(creds.getGid())>);
auto groups = buildUser->getSupplementaryGIDs();
creds.setSupplementaryGroups({groups.data(), groups.size()});
}
fillBuilderConfig(request);
@@ -1299,8 +1311,8 @@ void LocalDerivationGoal::runChild(build::Request::Reader request)
const bool setUser = prepareChildSetup(request);
if (sys::chdir(tmpDirInSandbox) == -1) {
throw SysError("changing into '%1%'", tmpDir);
if (sys::chdir(rpc::to<std::string>(request.getWorkingDir())) == -1) {
throw SysError("changing into '%1%'", rpc::to<std::string>(request.getWorkingDir()));
}
/* Close all other file descriptors. */
@@ -1308,7 +1320,7 @@ void LocalDerivationGoal::runChild(build::Request::Reader request)
/* Disable core dumps by default. */
struct rlimit limit = { 0, RLIM_INFINITY };
if (settings.enableCoreDumps) {
if (request.getEnableCoreDumps()) {
limit.rlim_cur = RLIM_INFINITY;
}
setrlimit(RLIMIT_CORE, &limit);
@@ -1321,22 +1333,27 @@ void LocalDerivationGoal::runChild(build::Request::Reader request)
descriptors except std*, so that's safe. Also note that
setuid() when run as root sets the real, effective and
saved UIDs. */
if (setUser && buildUser) {
if (setUser && request.hasCredentials()) {
auto creds = request.getCredentials();
/* Preserve supplementary groups of the build user, to allow
admins to specify groups such as "kvm". */
auto gids = buildUser->getSupplementaryGIDs();
if (setgroups(gids.size(), gids.data()) == -1)
std::vector<gid_t> gids;
std::copy(
creds.getSupplementaryGroups().begin(),
creds.getSupplementaryGroups().end(),
std::back_inserter(gids)
);
if (setgroups(gids.size(), gids.data()) == -1) {
throw SysError("cannot set supplementary groups of build user");
}
if (setgid(buildUser->getGID()) == -1 ||
getgid() != buildUser->getGID() ||
getegid() != buildUser->getGID())
if (setgid(creds.getGid()) == -1 || getgid() != creds.getGid() || getegid() != creds.getGid()) {
throw SysError("setgid failed");
}
if (setuid(buildUser->getUID()) == -1 ||
getuid() != buildUser->getUID() ||
geteuid() != buildUser->getUID())
if (setuid(creds.getUid()) == -1 || getuid() != creds.getUid() || geteuid() != creds.getUid()) {
throw SysError("setuid failed");
}
}
finishChildSetup(request);
+10
View File
@@ -4,7 +4,17 @@ using Cxx = import "/capnp/c++.capnp";
$Cxx.namespace("nix::build");
struct Request {
struct Credentials {
uid @0 :UInt32;
gid @1 :UInt32;
uidCount @2 :UInt32;
supplementaryGroups @3 :List(UInt32);
}
builder @0 :Data;
args @1 :List(Data);
environment @2 :List(Data);
workingDir @3 :Data;
enableCoreDumps @4 :Bool;
credentials @5 :Credentials;
}