mirror of
https://github.com/NixOS/nix.git
synced 2025-11-28 13:11:00 +01:00
Split auto UID allocation from cgroups
Cgroups are now only used for derivations that require the uid-range range feature. This allows auto UID allocation even on systems that don't have cgroups (like macOS). Also, make things work on modern systems that use cgroups v2 (where there is a single hierarchy and no "systemd" controller).
This commit is contained in:
parent
40911d7dec
commit
2fde7e0108
9 changed files with 122 additions and 96 deletions
|
|
@ -160,7 +160,7 @@ void LocalDerivationGoal::tryLocalBuild() {
|
|||
|
||||
if (useBuildUsers()) {
|
||||
if (!buildUser)
|
||||
buildUser = acquireUserLock();
|
||||
buildUser = acquireUserLock(parsedDrv->useUidRange() ? 65536 : 1);
|
||||
|
||||
if (!buildUser) {
|
||||
if (!actLock)
|
||||
|
|
@ -495,8 +495,8 @@ void LocalDerivationGoal::startBuilder()
|
|||
}
|
||||
}
|
||||
|
||||
useUidRange = parsedDrv->getRequiredSystemFeatures().count("uid-range");
|
||||
useSystemdCgroup = parsedDrv->getRequiredSystemFeatures().count("Systemd-cgroup");
|
||||
assert(!useSystemdCgroup);
|
||||
|
||||
if (useChroot) {
|
||||
|
||||
|
|
@ -576,7 +576,8 @@ void LocalDerivationGoal::startBuilder()
|
|||
|
||||
printMsg(lvlChatty, format("setting up chroot environment in '%1%'") % chrootRootDir);
|
||||
|
||||
if (mkdir(chrootRootDir.c_str(), useUidRange ? 0755 : 0750) == -1)
|
||||
// FIXME: make this 0700
|
||||
if (mkdir(chrootRootDir.c_str(), buildUser && buildUser->getUIDCount() != 1 ? 0755 : 0750) == -1)
|
||||
throw SysError("cannot create '%1%'", chrootRootDir);
|
||||
|
||||
// FIXME: only make root writable for user namespace builds.
|
||||
|
|
@ -596,8 +597,8 @@ void LocalDerivationGoal::startBuilder()
|
|||
createDirs(chrootRootDir + "/etc");
|
||||
chownToBuilder(chrootRootDir + "/etc");
|
||||
|
||||
if (useUidRange && (!buildUser || buildUser->getUIDCount() < 65536))
|
||||
throw Error("feature 'uid-range' requires '%s' to be enabled", settings.autoAllocateUids.name);
|
||||
if (parsedDrv->useUidRange() && (!buildUser || buildUser->getUIDCount() < 65536))
|
||||
throw Error("feature 'uid-range' requires the setting '%s' to be enabled", settings.autoAllocateUids.name);
|
||||
|
||||
/* Declare the build user's group so that programs get a consistent
|
||||
view of the system (e.g., "id -gn"). */
|
||||
|
|
@ -670,7 +671,7 @@ void LocalDerivationGoal::startBuilder()
|
|||
#endif
|
||||
#endif
|
||||
} else {
|
||||
if (useUidRange)
|
||||
if (parsedDrv->useUidRange())
|
||||
throw Error("feature 'uid-range' is only supported in sandboxed builds");
|
||||
if (useSystemdCgroup)
|
||||
throw Error("feature 'systemd-cgroup' is only supported in sandboxed builds");
|
||||
|
|
@ -934,12 +935,12 @@ void LocalDerivationGoal::startBuilder()
|
|||
the calling user (if build users are disabled). */
|
||||
uid_t hostUid = buildUser ? buildUser->getUID() : getuid();
|
||||
uid_t hostGid = buildUser ? buildUser->getGID() : getgid();
|
||||
uint32_t nrIds = buildUser && useUidRange ? buildUser->getUIDCount() : 1;
|
||||
uid_t nrIds = buildUser ? buildUser->getUIDCount() : 1;
|
||||
|
||||
writeFile("/proc/" + std::to_string(pid) + "/uid_map",
|
||||
fmt("%d %d %d", sandboxUid(), hostUid, nrIds));
|
||||
|
||||
if (!useUidRange)
|
||||
if (!buildUser || buildUser->getUIDCount() == 1)
|
||||
writeFile("/proc/" + std::to_string(pid) + "/setgroups", "deny");
|
||||
|
||||
writeFile("/proc/" + std::to_string(pid) + "/gid_map",
|
||||
|
|
@ -1793,7 +1794,7 @@ void LocalDerivationGoal::runChild()
|
|||
throw SysError("mounting /proc");
|
||||
|
||||
/* Mount sysfs on /sys. */
|
||||
if (useUidRange) {
|
||||
if (buildUser && buildUser->getUIDCount() != 1) {
|
||||
createDirs(chrootRootDir + "/sys");
|
||||
if (mount("none", (chrootRootDir + "/sys").c_str(), "sysfs", 0, 0) == -1)
|
||||
throw SysError("mounting /sys");
|
||||
|
|
|
|||
|
|
@ -41,9 +41,6 @@ struct LocalDerivationGoal : public DerivationGoal
|
|||
|
||||
Path chrootRootDir;
|
||||
|
||||
/* Whether to give the build more than 1 UID. */
|
||||
bool useUidRange = false;
|
||||
|
||||
/* Whether to make the 'systemd' cgroup controller available to
|
||||
the build. */
|
||||
bool useSystemdCgroup = false;
|
||||
|
|
@ -99,8 +96,8 @@ struct LocalDerivationGoal : public DerivationGoal
|
|||
result. */
|
||||
std::map<Path, ValidPathInfo> prevInfos;
|
||||
|
||||
uid_t sandboxUid() { return usingUserNamespace ? (useUidRange ? 0 : 1000) : buildUser->getUID(); }
|
||||
gid_t sandboxGid() { return usingUserNamespace ? (useUidRange ? 0 : 100) : buildUser->getGID(); }
|
||||
uid_t sandboxUid() { return usingUserNamespace ? (buildUser->getUIDCount() == 1 ? 1000 : 0) : buildUser->getUID(); }
|
||||
gid_t sandboxGid() { return usingUserNamespace ? (buildUser->getUIDCount() == 1 ? 100 : 0) : buildUser->getGID(); }
|
||||
|
||||
const static Path homeDir;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue