From 9aed117395f6fd6c4d24a81a6b66994e75311f5e Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Wed, 1 Jul 2015 14:56:34 +0200 Subject: Preserve supplementary groups of build users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following patch is an attempt to address this bug (see ) by preserving the supplementary groups of build users in the build environment. In practice, I would expect that supplementary groups would contain only one or two groups: the build users group, and possibly the “kvm” group. [Changed &at(0) to data() and removed tabs - Eelco] --- src/libstore/build.cc | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 21bf7167e523..00b38dd98d74 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -446,6 +446,7 @@ private: string user; uid_t uid; gid_t gid; + std::vector supplementaryGIDs; public: UserLock(); @@ -459,6 +460,7 @@ public: string getUser() { return user; } uid_t getUID() { return uid; } uid_t getGID() { return gid; } + std::vector getSupplementaryGIDs() { return supplementaryGIDs; } bool enabled() { return uid != 0; } @@ -538,6 +540,17 @@ void UserLock::acquire() throw Error(format("the Nix user should not be a member of ‘%1%’") % settings.buildUsersGroup); + /* Get the list of supplementary groups of this build user. This + is usually either empty or contains a group such as "kvm". */ + supplementaryGIDs.resize(10); + int ngroups = supplementaryGIDs.size(); + int err = getgrouplist(pw->pw_name, pw->pw_gid, + supplementaryGIDs.data(), &ngroups); + if (err == -1) + throw Error(format("failed to get list of supplementary groups for ‘%1’") % pw->pw_name); + + supplementaryGIDs.resize(ngroups); + return; } } @@ -2304,8 +2317,11 @@ void DerivationGoal::runChild() setuid() when run as root sets the real, effective and saved UIDs. */ if (buildUser.enabled()) { - if (setgroups(0, 0) == -1) - throw SysError("cannot clear the set of supplementary groups"); + /* Preserve supplementary groups of the build user, to allow + admins to specify groups such as "kvm". */ + if (setgroups(buildUser.getSupplementaryGIDs().size(), + buildUser.getSupplementaryGIDs().data()) == -1) + throw SysError("cannot set supplementary groups of build user"); if (setgid(buildUser.getGID()) == -1 || getgid() != buildUser.getGID() || -- cgit 1.4.1