From ff12d1c1a1bb0dcea5a9ac6b8a5036d7e5dc11ca Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 28 Nov 2022 20:49:17 +0100 Subject: [PATCH] Check that auto-allocated UIDs don't clash with existing accounts --- src/libstore/lock.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libstore/lock.cc b/src/libstore/lock.cc index 7459d837d..2858137d6 100644 --- a/src/libstore/lock.cc +++ b/src/libstore/lock.cc @@ -127,13 +127,10 @@ struct AutoUserLock : UserLock { settings.requireExperimentalFeature(Xp::AutoAllocateUids); assert(settings.startId > 0); - assert(settings.startId % maxIdsPerBuild == 0); assert(settings.uidCount % maxIdsPerBuild == 0); assert((uint64_t) settings.startId + (uint64_t) settings.uidCount <= std::numeric_limits::max()); assert(nrIds <= maxIdsPerBuild); - // FIXME: check whether the id range overlaps any known users - createDirs(settings.nixStateDir + "/userpool2"); size_t nrSlots = settings.uidCount / maxIdsPerBuild; @@ -150,11 +147,18 @@ struct AutoUserLock : UserLock throw SysError("opening user lock '%s'", fnUserLock); if (lockFile(fd.get(), ltWrite, false)) { + + auto firstUid = settings.startId + i * maxIdsPerBuild; + + auto pw = getpwuid(firstUid); + if (pw) + throw Error("auto-allocated UID %d clashes with existing user account '%s'", firstUid, pw->pw_name); + auto lock = std::make_unique(); lock->fdUserLock = std::move(fd); - lock->firstUid = settings.startId + i * maxIdsPerBuild; + lock->firstUid = firstUid; if (useChroot) - lock->firstGid = lock->firstUid; + lock->firstGid = firstUid; else { struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); if (!gr)