From patchwork Fri Jan 24 17:24:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 37687 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 9F46F27BBEA; Fri, 24 Jan 2025 17:26:48 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE, SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id C116C27BBE2 for ; Fri, 24 Jan 2025 17:26:47 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tbNRX-0005gc-K0; Fri, 24 Jan 2025 12:26:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNRV-0005fe-Fc for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:05 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tbNRV-000880-5v; Fri, 24 Jan 2025 12:26:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:References:In-Reply-To:Date:From:To:Subject; bh=xpCSNZlKD/xC2GsfHtr1wqnKQLVLgRRMGCIqgMVlQ94=; b=odpIA2Pj0JQiOvSN6CSBRg5io3ENszFYerAulwELKA6Ue+eS3CCdjx5RvvZ2yezjmdVYZJ0aBn8D6/nOGAq4mozYmTyuYxMGHpUIvNEG+W+IQkU3K+W1z0naeiAvctk/zWjPW+z4Yz75xmQp8NXdt3/dbCv9+ta3cfnV6CBE8zyNYCLIOtBpaHvz+dqV0fLJO07mo2kG1SovjC4rWohuUECXAgFk9ZW1ydx+PS9KheYqKW/wDgpx6KQYqAsN2YDl7mYn/fVkJaYJVVOtvdUGBBnD+PA09ECZhsFgHA9pLc6cOaFQgsi19tGSVQuQWzd6uw+V2fxZRqdaJmUTcfsHRg==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tbNRS-0003VS-Bx; Fri, 24 Jan 2025 12:26:02 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#75810] [PATCH 1/6] daemon: Allow running as non-root with unprivileged user namespaces. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix@cbaines.net, dev@jpoiret.xyz, ludo@gnu.org, othacehe@gnu.org, zimon.toutoune@gmail.com, me@tobias.gr, guix-patches@gnu.org Resent-Date: Fri, 24 Jan 2025 17:26:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75810 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75810@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= , Christopher Baines , Josselin Poiret , Ludovic =?utf-8?q?Court=C3=A8s?= , Mathieu Othacehe , Simon Tournier , Tobias Geerinckx-Rice X-Debbugs-Original-Xcc: Christopher Baines , Josselin Poiret , Ludovic =?utf-8?q?Court=C3=A8s?= , Mathieu Othacehe , Simon Tournier , Tobias Geerinckx-Rice Received: via spool by 75810-submit@debbugs.gnu.org id=B75810.173773952013360 (code B ref 75810); Fri, 24 Jan 2025 17:26:02 +0000 Received: (at 75810) by debbugs.gnu.org; 24 Jan 2025 17:25:20 +0000 Received: from localhost ([127.0.0.1]:46890 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tbNQk-0003Sl-7c for submit@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39734) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tbNQh-0003N4-Ab for 75810@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:16 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNQc-00082X-0O; Fri, 24 Jan 2025 12:25:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:In-Reply-To:Date:Subject:To: From; bh=xpCSNZlKD/xC2GsfHtr1wqnKQLVLgRRMGCIqgMVlQ94=; b=QBQPaD4IAa/nSt+g28pj jh5L6YWqgV/CvdgjR+5jgXgV4uZTPZX0U2j7ZtZ5TREl0bwCo+g1xRkGJXb9lSR9o+cKFeFifmWRz 9J/ZZZ58Yd4Y35oVCyuyzSrlvYe4QqIEsf8aB5Rk/3RiOx6aIHd98Aw0FN4GzVz64Z8+HI0adWkeD mGIO7H4a9M095pamkOHgr6LhaAbMZJ6EiS+b+fuELhroa+QAeoozF0KcdwBNfZYztFWKYe42epvQ+ +tn8TFNzuCbPEZ5p7UsD0GMoEZ2UWYq1iZ0Dn9z45sR++NKd+0it6MljZ4KZ0Qzre2xvx5hPyMzWY t5y7kS7+4HDZag==; From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Fri, 24 Jan 2025 18:24:51 +0100 Message-ID: <41862c6aa51aa70c69a348635eb03a5ca8069695.1737738362.git.ludo@gnu.org> X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches From: Ludovic Courtès * nix/libstore/build.cc (guestUID, guestGID): New variables. (initializeUserNamespace): New function. (DerivationGoal::startBuilder): Call ‘chown’ only when ‘buildUser.enabled()’ is true. Pass CLONE_NEWUSER to ‘clone’ when ‘buildUser.enabled()’ is false or not running as root. Retry ‘clone’ without CLONE_NEWUSER upon EPERM. (DerivationGoal::registerOutputs): Make ‘actualPath’ writable before ‘rename’. (DerivationGoal::deleteTmpDir): Catch ‘SysError’ around ‘_chown’ call. * nix/libstore/local-store.cc (LocalStore::createUser): Do nothing if ‘dirs’ already exists. Warn instead of failing when failing to chown ‘dir’. * guix/substitutes.scm (%narinfo-cache-directory): Check for ‘_NIX_OPTIONS’ rather than getuid() == 0 to determine the cache location. Change-Id: I38fbe01f80fb45a99cd8a391e55a39a54d64fcb7 --- guix/substitutes.scm | 4 +- nix/libstore/build.cc | 123 +++++++++++++++++++++++++++++------- nix/libstore/local-store.cc | 22 +++++-- 3 files changed, 118 insertions(+), 31 deletions(-) diff --git a/guix/substitutes.scm b/guix/substitutes.scm index e31b394020..2761a3dafb 100644 --- a/guix/substitutes.scm +++ b/guix/substitutes.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013-2021, 2023-2024 Ludovic Courtès +;;; Copyright © 2013-2021, 2023-2025 Ludovic Courtès ;;; Copyright © 2014 Nikita Karetnikov ;;; Copyright © 2018 Kyle Meyer ;;; Copyright © 2020 Christopher Baines @@ -76,7 +76,7 @@ (define %narinfo-cache-directory ;; time, 'guix substitute' is called by guix-daemon as root and stores its ;; cached data in /var/guix/…. However, when invoked from 'guix challenge' ;; as a user, it stores its cache in ~/.cache. - (if (zero? (getuid)) + (if (getenv "_NIX_OPTIONS") ;invoked by guix-daemon (or (and=> (getenv "XDG_CACHE_HOME") (cut string-append <> "/guix/substitute")) (string-append %state-directory "/substitute/cache")) diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index edd01bab34..727472c77f 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -1622,6 +1622,25 @@ int childEntry(void * arg) } +/* UID and GID of the build user inside its own user namespace. */ +static const uid_t guestUID = 30001; +static const gid_t guestGID = 30000; + +/* Initialize the user namespace of CHILD. */ +static void initializeUserNamespace(pid_t child) +{ + auto hostUID = getuid(); + auto hostGID = getgid(); + + writeFile("/proc/" + std::to_string(child) + "/uid_map", + (format("%d %d 1") % guestUID % hostUID).str()); + + writeFile("/proc/" + std::to_string(child) + "/setgroups", "deny"); + + writeFile("/proc/" + std::to_string(child) + "/gid_map", + (format("%d %d 1") % guestGID % hostGID).str()); +} + void DerivationGoal::startBuilder() { auto f = format( @@ -1685,7 +1704,7 @@ void DerivationGoal::startBuilder() then an attacker could create in it a hardlink to a root-owned file such as /etc/shadow. If 'keepFailed' is true, the daemon would then chown that hardlink to the user, giving them write access to - that file. */ + that file. See CVE-2021-27851. */ tmpDir += "/top"; if (mkdir(tmpDir.c_str(), 0700) == 1) throw SysError("creating top-level build directory"); @@ -1802,7 +1821,7 @@ void DerivationGoal::startBuilder() if (mkdir(chrootRootDir.c_str(), 0750) == -1) throw SysError(format("cannot create ‘%1%’") % chrootRootDir); - if (chown(chrootRootDir.c_str(), 0, buildUser.getGID()) == -1) + if (buildUser.enabled() && chown(chrootRootDir.c_str(), 0, buildUser.getGID()) == -1) throw SysError(format("cannot change ownership of ‘%1%’") % chrootRootDir); /* Create a writable /tmp in the chroot. Many builders need @@ -1821,8 +1840,8 @@ void DerivationGoal::startBuilder() (format( "nixbld:x:%1%:%2%:Nix build user:/:/noshell\n" "nobody:x:65534:65534:Nobody:/:/noshell\n") - % (buildUser.enabled() ? buildUser.getUID() : getuid()) - % (buildUser.enabled() ? buildUser.getGID() : getgid())).str()); + % (buildUser.enabled() ? buildUser.getUID() : guestUID) + % (buildUser.enabled() ? buildUser.getGID() : guestGID)).str()); /* Declare the build user's group so that programs get a consistent view of the system (e.g., "id -gn"). */ @@ -1859,7 +1878,7 @@ void DerivationGoal::startBuilder() createDirs(chrootStoreDir); chmod_(chrootStoreDir, 01775); - if (chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1) + if (buildUser.enabled() && chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1) throw SysError(format("cannot change ownership of ‘%1%’") % chrootStoreDir); foreach (PathSet::iterator, i, inputPaths) { @@ -1971,14 +1990,42 @@ void DerivationGoal::startBuilder() if (useChroot) { char stack[32 * 1024]; int flags = CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | SIGCHLD; - if (!fixedOutput) flags |= CLONE_NEWNET; + Pipe readiness; + if (!fixedOutput) { + flags |= CLONE_NEWNET; + } + if (!buildUser.enabled() || getuid() != 0) { + flags |= CLONE_NEWUSER; + readiness.create(); + } + /* Ensure proper alignment on the stack. On aarch64, it has to be 16 bytes. */ - pid = clone(childEntry, + pid = clone(childEntry, (char *)(((uintptr_t)stack + sizeof(stack) - 8) & ~(uintptr_t)0xf), flags, this); - if (pid == -1) - throw SysError("cloning builder process"); + if (pid == -1) { + if ((flags & CLONE_NEWUSER) != 0 && getuid() != 0) + /* 'clone' fails with EPERM on distros where unprivileged user + namespaces are disabled. Error out instead of giving up on + isolation. */ + throw SysError("cannot create process in unprivileged user namespace"); + else + throw SysError("cloning builder process"); + } + + if ((flags & CLONE_NEWUSER) != 0) { + /* Initialize the UID/GID mapping of the guest. */ + if (pid == 0) { + char str[20] = { '\0' }; + readFull(readiness.readSide, (unsigned char*)str, 3); + if (strcmp(str, "go\n") != 0) + throw Error("failed to initialize process in unprivileged user namespace"); + } else { + initializeUserNamespace(pid); + writeFull(readiness.writeSide, (unsigned char*)"go\n", 3); + } + } } else #endif { @@ -2030,17 +2077,19 @@ void DerivationGoal::runChild() #if CHROOT_ENABLED if (useChroot) { - /* Initialise the loopback interface. */ - AutoCloseFD fd(socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)); - if (fd == -1) throw SysError("cannot open IP socket"); + if (!fixedOutput) { + /* Initialise the loopback interface. */ + AutoCloseFD fd(socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)); + if (fd == -1) throw SysError("cannot open IP socket"); - struct ifreq ifr; - strcpy(ifr.ifr_name, "lo"); - ifr.ifr_flags = IFF_UP | IFF_LOOPBACK | IFF_RUNNING; - if (ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) - throw SysError("cannot set loopback interface flags"); + struct ifreq ifr; + strcpy(ifr.ifr_name, "lo"); + ifr.ifr_flags = IFF_UP | IFF_LOOPBACK | IFF_RUNNING; + if (ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) + throw SysError("cannot set loopback interface flags"); - fd.close(); + fd.close(); + } /* Set the hostname etc. to fixed values. */ char hostname[] = "localhost"; @@ -2463,8 +2512,16 @@ void DerivationGoal::registerOutputs() if (buildMode == bmRepair) replaceValidPath(path, actualPath); else - if (buildMode != bmCheck && rename(actualPath.c_str(), path.c_str()) == -1) - throw SysError(format("moving build output `%1%' from the chroot to the store") % path); + if (buildMode != bmCheck) { + if (S_ISDIR(st.st_mode)) + /* Change mode on the directory to allow for + rename(2). */ + chmod(actualPath.c_str(), st.st_mode | 0700); + if (rename(actualPath.c_str(), path.c_str()) == -1) + throw SysError(format("moving build output `%1%' from the chroot to the store") % path); + if (S_ISDIR(st.st_mode) && chmod(path.c_str(), st.st_mode) == -1) + throw SysError(format("restoring permissions on directory `%1%'") % actualPath); + } } if (buildMode != bmCheck) actualPath = path; } @@ -2723,8 +2780,25 @@ void DerivationGoal::deleteTmpDir(bool force) // Change the ownership if clientUid is set. Never change the // ownership or the group to "root" for security reasons. if (settings.clientUid != (uid_t) -1 && settings.clientUid != 0) { - _chown(tmpDir, settings.clientUid, - settings.clientGid != 0 ? settings.clientGid : -1); + uid_t uid = settings.clientUid; + gid_t gid = settings.clientGid != 0 ? settings.clientGid : -1; + try { + _chown(tmpDir, uid, gid); + + if (getuid() != 0) { + /* If, without being root, the '_chown' call above + succeeded, then it means we have CAP_CHOWN. Retake + ownership of tmpDir itself so it can be renamed + below. */ + chown(tmpDir.c_str(), getuid(), getgid()); + } + } catch (SysError & e) { + /* When running as an unprivileged user and without + CAP_CHOWN, we cannot chown the build tree. Print a + message and keep going. */ + printMsg(lvlInfo, format("cannot change ownership of build directory '%1%': %2%") + % tmpDir % strerror(e.errNo)); + } if (top != tmpDir) { // Rename tmpDir to its parent, with an intermediate step. @@ -2733,6 +2807,11 @@ void DerivationGoal::deleteTmpDir(bool force) throw SysError("pivoting failed build tree"); if (rename((pivot + "/top").c_str(), top.c_str()) == -1) throw SysError("renaming failed build tree"); + + if (getuid() != 0) + /* Running unprivileged but with CAP_CHOWN. */ + chown(top.c_str(), uid, gid); + rmdir(pivot.c_str()); } } diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc index 0883a4bbce..4308264a4f 100644 --- a/nix/libstore/local-store.cc +++ b/nix/libstore/local-store.cc @@ -306,14 +306,14 @@ void LocalStore::openDB(bool create) void LocalStore::makeStoreWritable() { #if HAVE_UNSHARE && HAVE_STATVFS && HAVE_SYS_MOUNT_H && defined(MS_BIND) && defined(MS_REMOUNT) - if (getuid() != 0) return; /* Check if /nix/store is on a read-only mount. */ struct statvfs stat; if (statvfs(settings.nixStore.c_str(), &stat) != 0) throw SysError("getting info about the store mount point"); if (stat.f_flag & ST_RDONLY) { - if (unshare(CLONE_NEWNS) == -1) + int flags = CLONE_NEWNS | (getpid() == 0 ? 0 : CLONE_NEWUSER); + if (unshare(flags) == -1) throw SysError("setting up a private mount namespace"); if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) @@ -1614,11 +1614,19 @@ void LocalStore::createUser(const std::string & userName, uid_t userId) { auto dir = settings.nixStateDir + "/profiles/per-user/" + userName; - createDirs(dir); - if (chmod(dir.c_str(), 0755) == -1) - throw SysError(format("changing permissions of directory '%s'") % dir); - if (chown(dir.c_str(), userId, -1) == -1) - throw SysError(format("changing owner of directory '%s'") % dir); + auto created = createDirs(dir); + if (!created.empty()) { + if (chmod(dir.c_str(), 0755) == -1) + throw SysError(format("changing permissions of directory '%s'") % dir); + + /* The following operation requires CAP_CHOWN or can be handled + manually by a user with CAP_CHOWN. */ + if (chown(dir.c_str(), userId, -1) == -1) { + rmdir(dir.c_str()); + string message = strerror(errno); + printMsg(lvlInfo, format("failed to change owner of directory '%1%' to %2%: %3%") % dir % userId % message); + } + } } From patchwork Fri Jan 24 17:24:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 37685 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 2A38827BBEA; Fri, 24 Jan 2025 17:26:46 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE, SPF_HELO_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 706C227BBE2 for ; Fri, 24 Jan 2025 17:26:45 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tbNRV-0005fd-P6; Fri, 24 Jan 2025 12:26:05 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNRT-0005eg-RG for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:03 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tbNRT-00087P-1W for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:References:In-Reply-To:Date:From:To:Subject; bh=bRN6Nu59+C3SYAE0PEM9bbTrcQYq/PayE8qd5RFzwjI=; b=UbtG1zBf2+k22tum+ThBIJJBguUFPvJOucE0tW6zJrP0PVnEAfQiix6noXbPKAzq3gsYyGQHTCt5c3ClsDHZXYM1V6q0E4CGNBNp3qMLf3MPq0fjpHFeWmX5AOFQztaQ7KjsYErt7wx4mhdtBmPPW18MWpJHubhGjcNnQi0szigVroSpDdyuZ9yooOKxF9Qgx5z2/mWtPrbC2BzQYlfM2PNfOT9bbIZ1pfSq5rC3qCdJz1UaOLe7e1jw/ns3NHVpsqUN3EUwwvSW5ApT5zyH5qQNIVucj8m2ERzwNhelTJCozmizHY9PzRJeYZZLcv0ESS1XhfmBFRHyG/zZlJUjXA==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tbNRS-0003VZ-Rv for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:02 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#75810] [PATCH 2/6] DRAFT tests: Run in a chroot and unprivileged user namespaces. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 24 Jan 2025 17:26:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75810 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75810@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 75810-submit@debbugs.gnu.org id=B75810.173773952413386 (code B ref 75810); Fri, 24 Jan 2025 17:26:02 +0000 Received: (at 75810) by debbugs.gnu.org; 24 Jan 2025 17:25:24 +0000 Received: from localhost ([127.0.0.1]:46898 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tbNQq-0003To-5Q for submit@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:24 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39746) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tbNQi-0003NN-Tg for 75810@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:17 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNQd-00082m-D2; Fri, 24 Jan 2025 12:25:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:In-Reply-To:Date:Subject:To: From; bh=bRN6Nu59+C3SYAE0PEM9bbTrcQYq/PayE8qd5RFzwjI=; b=M9DURPznSXpt/+0Faw8C EdqRR1TvbFB7f6yj81bRRhFhl1Vc1JeO65oV8gml+XdJTxFRZ5ijqmD853y1AoMF0nbhaeLxgdq4f q7hmO+LYKdWkIvi4uEzUVVCHdHl0CNtMVbIt4YWgZ1b6bAedkxM8DtSVBeI/dDCMoJ6XplYoNIvXB WKD3IamMG5IxYZlDg7gBjEoEK45fms4irhWHmes9jcc++Riww16spzf0+6NLr4ZJG0M2ElvMexhAv F5ngTtp3LOzbY5eid1vrzM9akT4G6GAGL1oNUaJDm8r9ntfwuM4r4FzjoR/p1YOrKA2FJgu7l1bJP vBZ7RxfdQgwm4w==; From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Fri, 24 Jan 2025 18:24:52 +0100 Message-ID: <6fb69ee481d628317ed09c6e762f38489bab0ea7.1737738362.git.ludo@gnu.org> X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches DRAFT: - Double-check the test suite. * build-aux/test-env.in: Pass ‘--disable-chroot’ only when unprivileged user namespace support is lacking. * tests/store.scm ("build-things, check mode"): Use ‘gettimeofday’ rather than a shared file as a source of entropy. ("isolated environment"): New test. Change-Id: Iedb816ef548c77799e5b2f9b6a3b7510ad19ec2a --- build-aux/test-env.in | 14 ++++++- tests/store.scm | 89 ++++++++++++++++++++++++++----------------- 2 files changed, 66 insertions(+), 37 deletions(-) diff --git a/build-aux/test-env.in b/build-aux/test-env.in index 9caa29da58..5626152b34 100644 --- a/build-aux/test-env.in +++ b/build-aux/test-env.in @@ -1,7 +1,7 @@ #!/bin/sh # GNU Guix --- Functional package management for GNU -# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2021 Ludovic Courtès +# Copyright © 2012-2019, 2021, 2025 Ludovic Courtès # # This file is part of GNU Guix. # @@ -102,10 +102,20 @@ then rm -rf "$GUIX_STATE_DIRECTORY/daemon-socket" mkdir -m 0700 "$GUIX_STATE_DIRECTORY/daemon-socket" + # If unprivileged user namespaces are not supported, pass + # '--disable-chroot'. + if [ ! -f /proc/sys/kernel/unprivileged_userns_clone ] \ + || [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" -eq 1 ]; then + extra_options="" + else + extra_options="--disable-chroot" + fi + # Launch the daemon without chroot support because is may be # unavailable, for instance if we're not running as root. "@abs_top_builddir@/pre-inst-env" \ - "@abs_top_builddir@/guix-daemon" --disable-chroot \ + "@abs_top_builddir@/guix-daemon" \ + $extra_options \ --substitute-urls="$GUIX_BINARY_SUBSTITUTE_URL" & daemon_pid=$! diff --git a/tests/store.scm b/tests/store.scm index 45948f4f43..bdbb026dd9 100644 --- a/tests/store.scm +++ b/tests/store.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012-2021, 2023 Ludovic Courtès +;;; Copyright © 2012-2021, 2023, 2025 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -30,6 +30,8 @@ (define-module (test-store) #:use-module (guix derivations) #:use-module (guix serialization) #:use-module (guix build utils) + #:use-module ((gnu build linux-container) + #:select (unprivileged-user-namespace-supported?)) #:use-module (guix gexp) #:use-module (gnu packages) #:use-module (gnu packages bootstrap) @@ -391,6 +393,32 @@ (define %shell (equal? (valid-derivers %store o) (list (derivation-file-name d)))))) +(unless (unprivileged-user-namespace-supported?) + (test-skip 1)) +(test-equal "isolated environment" + (string-join (append + '("PID: 1" "UID: 30001") + (delete-duplicates + (sort (list "/dev" "/tmp" "/proc" "/etc" + (match (string-tokenize (%store-prefix) + (char-set-complement + (char-set #\/))) + ((top _ ...) (string-append "/" top)))) + string $out")) + (s (add-to-store %store "bash" #t "sha256" + (search-bootstrap-binary "bash" + (%current-system)))) + (d (derivation %store "the-thing" + s `("-e" ,b) + #:env-vars `(("foo" . ,(random-text))) + #:inputs `((,b) (,s)))) + (o (derivation->output-path d))) + (and (build-derivations %store (list d)) + (call-with-input-file o get-string-all)))) + (test-equal "with-build-handler" 'success (let* ((b (add-text-to-store %store "build" "echo $foo > $out" '())) @@ -1333,40 +1361,31 @@ (define %shell (test-assert "build-things, check mode" (with-store store - (call-with-temporary-output-file - (lambda (entropy entropy-port) - (write (random-text) entropy-port) - (force-output entropy-port) - (let* ((drv (build-expression->derivation - store "non-deterministic" - `(begin - (use-modules (rnrs io ports)) - (let ((out (assoc-ref %outputs "out"))) - (call-with-output-file out - (lambda (port) - ;; Rely on the fact that tests do not use the - ;; chroot, and thus ENTROPY is readable. - (display (call-with-input-file ,entropy - get-string-all) - port))) - #t)) - #:guile-for-build - (package-derivation store %bootstrap-guile (%current-system)))) - (file (derivation->output-path drv))) - (and (build-things store (list (derivation-file-name drv))) - (begin - (write (random-text) entropy-port) - (force-output entropy-port) - (guard (c ((store-protocol-error? c) - (pk 'determinism-exception c) - (and (not (zero? (store-protocol-error-status c))) - (string-contains (store-protocol-error-message c) - "deterministic")))) - ;; This one will produce a different result. Since we're in - ;; 'check' mode, this must fail. - (build-things store (list (derivation-file-name drv)) - (build-mode check)) - #f)))))))) + (let* ((drv (build-expression->derivation + store "non-deterministic" + `(begin + (use-modules (rnrs io ports)) + (let ((out (assoc-ref %outputs "out"))) + (call-with-output-file out + (lambda (port) + (let ((now (gettimeofday))) + (display (+ (car now) (cdr now)) port)))) + #t)) + #:guile-for-build + (package-derivation store %bootstrap-guile (%current-system)))) + (file (derivation->output-path drv))) + (and (build-things store (list (derivation-file-name drv))) + (begin + (guard (c ((store-protocol-error? c) + (pk 'determinism-exception c) + (and (not (zero? (store-protocol-error-status c))) + (string-contains (store-protocol-error-message c) + "deterministic")))) + ;; This one will produce a different result. Since we're in + ;; 'check' mode, this must fail. + (build-things store (list (derivation-file-name drv)) + (build-mode check)) + #f)))))) (test-assert "build-succeeded trace in check mode" (string-contains From patchwork Fri Jan 24 17:24:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 37686 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 8055D27BBEB; Fri, 24 Jan 2025 17:26:46 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE, SPF_HELO_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 5BC9E27BBE2 for ; Fri, 24 Jan 2025 17:26:46 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tbNRW-0005g7-KL; Fri, 24 Jan 2025 12:26:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNRT-0005eh-RQ for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:03 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tbNRT-00087Q-GP for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:References:In-Reply-To:Date:From:To:Subject; bh=+scMzR3E2mTiYzHwZP6c6yC+K2EC253ixfUcI5GQnC0=; b=keXpeY0v/4pGA0oxVQQP3yG0iVsPlcv/bgBKRGBD6lTM+LigaE4UI4V7SKhheIH4BlMc9TaYG6y/mjchmD0McUW7KnZ0fGMAKMYNAl4aK3SbTx7mFdkFmfe9rpZqlHqI42xj3GjFG2ZxAcCF73EjfkTCiiBtkypUi2H712cNrgy5Na/Z80K7a80756D1mf2kOmeDwddrrrerhIWDRkT3XZVrb7m1V5YCGSeV8j7EMIAc4L2T3QCQS/5etvsJ6s1MiboJTYQ6tfIFxqTVOS3TjiH9XLFmmxLEMX7bKh1r2EySTqQNXThKm8UrqgbvEF8khSidH3kw1Jbr+J4dD7DmTA==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tbNRT-0003Vi-AS for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:03 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#75810] [PATCH 3/6] daemon: Create /var/guix/profiles/per-user unconditionally. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 24 Jan 2025 17:26:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75810 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75810@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 75810-submit@debbugs.gnu.org id=B75810.173773952513393 (code B ref 75810); Fri, 24 Jan 2025 17:26:03 +0000 Received: (at 75810) by debbugs.gnu.org; 24 Jan 2025 17:25:25 +0000 Received: from localhost ([127.0.0.1]:46900 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tbNQq-0003Tt-T4 for submit@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39752) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tbNQj-0003Nd-Jy for 75810@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:17 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNQe-000830-9V; Fri, 24 Jan 2025 12:25:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:In-Reply-To:Date:Subject:To: From; bh=+scMzR3E2mTiYzHwZP6c6yC+K2EC253ixfUcI5GQnC0=; b=lHG2Nur75MT5dtAMk4hL 02G6w8l7tkVittNIFRzYryUXLQIdCZEKJKuqwkj+emUQPr9xB/1M5ZEqf5znvBFmiqYf03GgHVw7a jBGez9Ic4jlpwoOt6sVrvdOWv57oSQ7Sv3XkBb6pYqNL5z3O7efKYU6zFDIRUUP90g+t4bnwhEe2v TJCi1r3jDrbVbC/54JyrauF2BYj8bvQU0DPnHybBUyUfKbfQOj09Ne7NquZRfLRQ4rRxsST7bpi06 P7Pi2WDlp6RNQUZ77+zYFllKCLfMBDLZOcZr2rTJ9LxhifcSVJJ7NSVKvOOeCINLUn7ykwUl3ReXp XT83szKuVx62eA==; From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Fri, 24 Jan 2025 18:24:53 +0100 Message-ID: X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * nix/libstore/local-store.cc (LocalStore::LocalStore): Create ‘perUserDir’ unconditionally. Change-Id: I5188320f9630a81d16f79212d0fffabd55d94abe --- nix/libstore/local-store.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc index 4308264a4f..6384669519 100644 --- a/nix/libstore/local-store.cc +++ b/nix/libstore/local-store.cc @@ -79,12 +79,12 @@ LocalStore::LocalStore(bool reserveSpace) createSymlink(profilesDir, gcRootsDir + "/profiles"); } - /* Optionally, create directories and set permissions for a - multi-user install. */ + Path perUserDir = profilesDir + "/per-user"; + createDirs(perUserDir); + + /* Optionally, set permissions for a multi-user install. */ if (getuid() == 0 && settings.buildUsersGroup != "") { - Path perUserDir = profilesDir + "/per-user"; - createDirs(perUserDir); if (chmod(perUserDir.c_str(), 0755) == -1) throw SysError(format("could not set permissions on '%1%' to 755") % perUserDir); From patchwork Fri Jan 24 17:24:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 37688 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 3642E27BBEA; Fri, 24 Jan 2025 17:26:53 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE, SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 5B42927BBE2 for ; Fri, 24 Jan 2025 17:26:52 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tbNRW-0005fy-Dg; Fri, 24 Jan 2025 12:26:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNRU-0005ew-Eh for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:04 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tbNRT-00087d-Ul for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:References:In-Reply-To:Date:From:To:Subject; bh=EJBKOU++7w/goxoEBuHLi3cBsE8e18X1/aR/9Jrf8LE=; b=g3278LP54IUxqH4A7wWFlkQ0TYYxO1rsYw+/m9KgqA0YGvsGszS6QCbzkq0MqieG9IWtg9QTU47dJLpLFjN4zzgeFKjcoUV4/OzxUgm6iv2XMt7zJLfHTzE6/1EUbH22AQaDj6ybPeIjNm2R5mypCpoDCpMZT8StjJXDzr2y7c/6N6y/+RvjPUb5JZ2afqXj4Qlztu4Mi6HTSwaH3RGM+Gr0BFmc+Fo+R5xBKEFlvkWYwtyzvo7XBjQEF6Ye/FxDhURCb/IbhGHr1GCYsaQfFoSiR+Fj3vd01KOVTOB+O4iUH+9KDdh4MJiEGiG9Hz/ueV6NayNMvR2e5E3oQSe6xQ==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tbNRT-0003Vq-PN for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:03 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#75810] [PATCH 4/6] daemon: Drop Linux ambient capabilities before executing builder. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 24 Jan 2025 17:26:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75810 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75810@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 75810-submit@debbugs.gnu.org id=B75810.173773952513401 (code B ref 75810); Fri, 24 Jan 2025 17:26:03 +0000 Received: (at 75810) by debbugs.gnu.org; 24 Jan 2025 17:25:25 +0000 Received: from localhost ([127.0.0.1]:46902 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tbNQr-0003Ty-8R for submit@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39768) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tbNQk-0003Oo-Ky for 75810@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:19 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNQf-00083D-9K; Fri, 24 Jan 2025 12:25:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:In-Reply-To:Date:Subject:To: From; bh=EJBKOU++7w/goxoEBuHLi3cBsE8e18X1/aR/9Jrf8LE=; b=fB+G4mN2dIcVTtbIfWdw MgcupQqBw2810LhWVSmlEWRVsjDJKjpS8Vtm/MZcnSIsV0naVdz+oEePbqjPrqKWhHrygl0HBP0E8 WRH5WFPvzxEzoXoq/eXYxloUG31MGrzu1nVjbnhRalfOhIyqwhqYuD+yGfd2QQqNQOEhaF7Hn6Mz8 TveWbZ4iO2wnzMxmO67lJZShHgwTQVY5sgSof18plO49997H+u+c3E0bMX21RNZuao1TSQ2KeXqnU 7xeQbH1hpueJKB/xYjcXskeNcywddrfXJrpymARsRQdSlKjsE663erac8q8lnr0Wju1icfctI8scT XnLfPgve3bG0yQ==; From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Fri, 24 Jan 2025 18:24:54 +0100 Message-ID: X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * config-daemon.ac: Check for . * nix/libstore/build.cc (DerivationGoal::runChild): When ‘useChroot’ is true, call ‘prctl’ to drop all ambient capabilities. Change-Id: If34637fc508e5fb6d278167f5df7802fc595284f --- config-daemon.ac | 2 +- nix/libstore/build.cc | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/config-daemon.ac b/config-daemon.ac index 6731c68bc3..aeec5f3239 100644 --- a/config-daemon.ac +++ b/config-daemon.ac @@ -78,7 +78,7 @@ if test "x$guix_build_daemon" = "xyes"; then dnl Chroot support. AC_CHECK_FUNCS([chroot unshare]) - AC_CHECK_HEADERS([sched.h sys/param.h sys/mount.h sys/syscall.h]) + AC_CHECK_HEADERS([sched.h sys/param.h sys/mount.h sys/syscall.h sys/prctl.h]) if test "x$ac_cv_func_chroot" != "xyes"; then AC_MSG_ERROR(['chroot' function missing, bailing out]) diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 727472c77f..c95bd2821f 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -50,6 +50,9 @@ #if HAVE_SCHED_H #include #endif +#if HAVE_SYS_PRCTL_H +#include +#endif #define CHROOT_ENABLED HAVE_CHROOT && HAVE_SYS_MOUNT_H && defined(MS_BIND) && defined(MS_PRIVATE) @@ -2077,6 +2080,12 @@ void DerivationGoal::runChild() #if CHROOT_ENABLED if (useChroot) { +# if HAVE_SYS_PRCTL_H + /* Drop ambient capabilities such as CAP_CHOWN that might have + been granted when starting guix-daemon. */ + prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0); +# endif + if (!fixedOutput) { /* Initialise the loopback interface. */ AutoCloseFD fd(socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)); From patchwork Fri Jan 24 17:24:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 37690 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 1772C27BBE2; Fri, 24 Jan 2025 17:26:56 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE, SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id BFB4B27BBE9 for ; Fri, 24 Jan 2025 17:26:55 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tbNRX-0005gL-Cf; Fri, 24 Jan 2025 12:26:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNRU-0005fE-NX for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:04 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tbNRU-00087i-DK for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:References:In-Reply-To:Date:From:To:Subject; bh=fSDfv9Lxo7q8Hsp8XW9PKQoYdqQwT7VmmKky0xhAbcI=; b=uzILMadjwuac0gjD7XriPxavoSfYhqamSE5yMwYT+pQ2ncstTDeoadn+Pg0y/6Fg72fprXrCKY4lb4swRHCwxyZmv5CIV3fkVvvJIhAhG8G+Pl+W3jz5RIFeboxePQUjI7eyskuc6Bumxeimqg0c4VTqqPPqhz0A9gY33tquwfrU1UIzxUemgOBKYMmuSwsCN+cYNQIuWwH5m9boAuomKWnwvdIAjUSfpulzBGSs+RUii3UgV/kXEy7F0jCr0JVLvSUfyxEefjPT0r1TB2P/V+iRwYEkBe0OoCPjeXBvmq6coqWmcxIQvDASgGTtovNY3nye95PNuc+tVrV1Rlfr1w==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tbNRU-0003Vx-8d for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:04 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#75810] [PATCH 5/6] etc: systemd services: Run =?utf-8?b?4oCY?= =?utf-8?b?Z3VpeC1kYWVtb27igJk=?= as an unprivileged user. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 24 Jan 2025 17:26:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75810 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75810@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 75810-submit@debbugs.gnu.org id=B75810.173773952613408 (code B ref 75810); Fri, 24 Jan 2025 17:26:04 +0000 Received: (at 75810) by debbugs.gnu.org; 24 Jan 2025 17:25:26 +0000 Received: from localhost ([127.0.0.1]:46904 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tbNQr-0003U6-N7 for submit@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39776) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tbNQm-0003Pe-0g for 75810@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:20 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNQg-00083e-Lr; Fri, 24 Jan 2025 12:25:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:In-Reply-To:Date:Subject:To: From; bh=fSDfv9Lxo7q8Hsp8XW9PKQoYdqQwT7VmmKky0xhAbcI=; b=W6eLg23Pxz1Cteorp7el 9OMHLil4xhz9F2DC3McI82HhKJIjEMuj7TuZIq9QiVKr0JSxYTwlTDyviiE+fbf2puVxawKUvFJKB WQzzYNPm/82UHzOV/6x97Uy+K87Gcadis+eiJjbUI8QtLfW7m5FLBRT+hcaavBH+x3+AEFHNABr0J cSYxEbX80yG/ThhrJQo+gXCLKrllHtNof/wZYBAXfMkOK6gpB9R/xcGogDITvk0MsWSfnER/50Gbf K8S6jqEatajb4sMX2J2C2ZKXwHQ/e0kzkHxUFqQnnKq/61lX2uTh2BXsWyTpUtEnAdZpKUf4Z0xpf IkcW8dccFhci4w==; From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Fri, 24 Jan 2025 18:24:55 +0100 Message-ID: <713be4d9b744226c4922f3eec66adfb3547c95bc.1737738362.git.ludo@gnu.org> X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * etc/guix-daemon.service.in (ExecStart): Remove ‘--build-users-group’. (User, AmbientCapabilities): New fields. Change-Id: Id826b8ab535844b6024d777f6bd15fd49db6d65e --- etc/guix-daemon.service.in | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/etc/guix-daemon.service.in b/etc/guix-daemon.service.in index 5c43d9b7f1..f9f0b28b35 100644 --- a/etc/guix-daemon.service.in +++ b/etc/guix-daemon.service.in @@ -7,9 +7,19 @@ Description=Build daemon for GNU Guix [Service] ExecStart=@localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix-daemon \ - --build-users-group=guixbuild --discover=no \ + --discover=no \ --substitute-urls='@GUIX_SUBSTITUTE_URLS@' Environment='GUIX_LOCPATH=@localstatedir@/guix/profiles/per-user/root/guix-profile/lib/locale' LC_ALL=en_US.utf8 + +# Run under a dedicated unprivileged user account. +User=guix-daemon + +# Provide the CAP_CHOWN capability so that guix-daemon cran create and chown +# /var/guix/profiles/per-user/$USER and also chown failed build directories +# when using '--keep-failed'. Note that guix-daemon explicitly drops ambient +# capabilities before executing build processes so they don't inherit them. +AmbientCapabilities=CAP_CHOWN + StandardOutput=journal StandardError=journal From patchwork Fri Jan 24 17:24:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 37689 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 5706227BBE2; Fri, 24 Jan 2025 17:26:53 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE, SPF_HELO_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id BA6A227BBE9 for ; Fri, 24 Jan 2025 17:26:52 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tbNRX-0005gj-PT; Fri, 24 Jan 2025 12:26:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNRV-0005fQ-7B for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:05 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tbNRU-00087v-UI for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:References:In-Reply-To:Date:From:To:Subject; bh=CyAW63unydjdK3bGh0fu/fzPuWtUxy3K5XUchGmxeSg=; b=BwIgvAVXfyvqZ56ImH0TXH/FeQtFUBQy/BkSHVEGgrO3njdcXrbkF9t8bTSYFUTTiUmO8vKt3seqmbpbnX0PJJQ825+IqeR1KJ4hEVDNTYA4tlzRQfeXN5VZAWXn4uO+nPHOusQgD/YEiL8QWkJwk1Po+hFFMpHhF67f9IXluBx6K/xhFNKhGSeJ9+RCsCEl7yvCb9dLB0Nwo8RoXwBqENJplBfHTN95HO2Uz+GT+9/NO6H+TyijURRMRnX3cYAf7IvPanV6b4GKww8Rr4vgOPRz8pLof3RVCAcJP7ZfRLQ2lop5x91yJuc04AEs//l0wyAf3A4+HEWVBu53SUDZ9g==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tbNRU-0003W6-P0 for guix-patches@gnu.org; Fri, 24 Jan 2025 12:26:04 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#75810] [PATCH 6/6] guix-install.sh: Support the unprivileged daemon where possible. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 24 Jan 2025 17:26:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 75810 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 75810@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 75810-submit@debbugs.gnu.org id=B75810.173773952613415 (code B ref 75810); Fri, 24 Jan 2025 17:26:04 +0000 Received: (at 75810) by debbugs.gnu.org; 24 Jan 2025 17:25:26 +0000 Received: from localhost ([127.0.0.1]:46906 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tbNQs-0003UD-52 for submit@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39782) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tbNQm-0003Qt-U1 for 75810@debbugs.gnu.org; Fri, 24 Jan 2025 12:25:21 -0500 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tbNQh-00083r-LL; Fri, 24 Jan 2025 12:25:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:In-Reply-To:Date:Subject:To: From; bh=CyAW63unydjdK3bGh0fu/fzPuWtUxy3K5XUchGmxeSg=; b=KT72z/lctyH4OjwoNNdE o5/75ESzb5N8Y0bW9U+789AIm3B/KcEQtRgp4avGhwqOkstsB2pjEFbmNFEYZtLlcb3KV6UOWZ+0H iDqAmTZEPj2zYqrUHhGmYd5L3uQCe8CtBVD0js0xl+3dNuiluNcmXe6UVGCSDag9sIHGEbZsXZWSe EPm9dlasF+3h8xAf23rAmlQiFqyFVG//XTcRPEL2WzeJy8rxapf/9V8/iYVsZ3a9TJEmE5dHEtFkk Ty19FaunyVISMYeWGOBJZ6pDfom1DX5WOVIIyB/klw30bxZSliHi6+wBmPF8+TyH3kIhwO1abLXG1 a8MOeentOPwwmg==; From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Fri, 24 Jan 2025 18:24:56 +0100 Message-ID: <2c04ad0cb868e4f41047f971c05915c5419729bd.1737738362.git.ludo@gnu.org> X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches * etc/guix-install.sh (create_account): New function. (sys_create_build_user): Use it. When ‘guix-daemon.service’ contains “User=guix-daemon” only create the ‘guix-daemon’ user and group. (sys_delete_build_user): Delete the ‘guix-daemon’ user and group. (can_install_unprivileged_daemon): New function. (sys_create_store): When installing the unprivileged daemon, change ownership of /gnu and /var/guix, and create /var/log/guix. (sys_authorize_build_farms): When the ‘guix-daemon’ account exists, change ownership of /etc/guix. (sys_enable_guix_daemon): Do not install ‘gnu-store.mount’ when running an unprivileged daemon. Change-Id: I73e573f1cc5c0cb3794aaaa6b576616b66e0c5e9 --- etc/guix-install.sh | 114 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 23 deletions(-) diff --git a/etc/guix-install.sh b/etc/guix-install.sh index f07b2741bb..4f08eff847 100755 --- a/etc/guix-install.sh +++ b/etc/guix-install.sh @@ -389,6 +389,11 @@ sys_create_store() cd "$tmp_path" _msg "${INF}Installing /var/guix and /gnu..." # Strip (skip) the leading ‘.’ component, which fails on read-only ‘/’. + # + # TODO: Eventually extract with ‘--owner=guix-daemon’ when installing + # and unprivileged guix-daemon service; for now, this script may install + # from both an old release that does not support unprivileged guix-daemon + # and a new release that does, so ‘chown -R’ later if needed. tar --extract --strip-components=1 --file "$pkg" -C / _msg "${INF}Linking the root user's profile" @@ -414,38 +419,82 @@ sys_delete_store() rm -rf ~root/.config/guix } +create_account() +{ + local user="$1" + local group="$2" + local supplementary_groups="$3" + local comment="$4" + + if id "$user" &>/dev/null; then + _msg "${INF}user '$user' is already in the system, reset" + usermod -g "$group" -G "$supplementary_groups" \ + -d /var/empty -s "$(which nologin)" \ + -c "$comment" "$user" + else + useradd -g "$group" -G "$supplementary_groups" \ + -d /var/empty -s "$(which nologin)" \ + -c "$comment" --system "$user" + _msg "${PAS}user added <$user>" + fi +} + +can_install_unprivileged_daemon() +{ # Return true if we can install guix-daemon running without privileges. + [ "$INIT_SYS" = systemd ] && \ + grep -q "User=guix-daemon" \ + ~root/.config/guix/current/lib/systemd/system/guix-daemon.service \ + && ([ ! -f /proc/sys/kernel/unprivileged_userns_clone ] \ + || [ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" -eq 1 ]) +} + sys_create_build_user() { # Create the group and user accounts for build users. _debug "--- [ ${FUNCNAME[0]} ] ---" - if getent group guixbuild > /dev/null; then - _msg "${INF}group guixbuild exists" - else - groupadd --system guixbuild - _msg "${PAS}group created" - fi - if getent group kvm > /dev/null; then _msg "${INF}group kvm exists and build users will be added to it" local KVMGROUP=,kvm fi - for i in $(seq -w 1 10); do - if id "guixbuilder${i}" &>/dev/null; then - _msg "${INF}user is already in the system, reset" - usermod -g guixbuild -G guixbuild${KVMGROUP} \ - -d /var/empty -s "$(which nologin)" \ - -c "Guix build user $i" \ - "guixbuilder${i}"; - else - useradd -g guixbuild -G guixbuild${KVMGROUP} \ - -d /var/empty -s "$(which nologin)" \ - -c "Guix build user $i" --system \ - "guixbuilder${i}"; - _msg "${PAS}user added " - fi - done + if [ "$INIT_SYS" = systemd ] && \ + grep -q "User=guix-daemon" \ + ~root/.config/guix/current/lib/systemd/system/guix-daemon.service + then + if getent group guix-daemon > /dev/null; then + _msg "${INF}group guix-daemon exists" + else + groupadd --system guix-daemon + _msg "${PAS}group guix-daemon created" + fi + + create_account guix-daemon guix-daemon \ + guix-daemon$KVMGROUP \ + "Unprivileged Guix Daemon User" + + # ‘tar xf’ creates root:root files. Change that. + chown -R guix-daemon:guix-daemon \ + /gnu /var/guix + + # The unprivileged cannot create the log directory by itself. + mkdir /var/log/guix + chown guix-daemon:guix-daemon /var/log/guix + chmod 755 /var/log/guix + else + if getent group guixbuild > /dev/null; then + _msg "${INF}group guixbuild exists" + else + groupadd --system guixbuild + _msg "${PAS}group created" + fi + + for i in $(seq -w 1 10); do + create_account "guixbuilder${i}" "guixbuild" \ + "guixbuild${KVMGROUP}" \ + "Guix build user $i" + done + fi } sys_delete_build_user() @@ -460,6 +509,14 @@ sys_delete_build_user() if getent group guixbuild &>/dev/null; then groupdel -f guixbuild fi + + _msg "${INF}remove guix-daemon user" + if id guix-daemon &>/dev/null; then + userdel -f guix-daemon + fi + if getent group guix-daemon &>/dev/null; then + groupdel -f guix-daemon + fi } sys_enable_guix_daemon() @@ -503,7 +560,14 @@ sys_enable_guix_daemon() # Install after guix-daemon.service to avoid a harmless warning. # systemd .mount units must be named after the target directory. # Here we assume a hard-coded name of /gnu/store. - install_unit gnu-store.mount + # + # FIXME: This feature is unavailable when running an + # unprivileged daemon. + if ! grep -q "User=guix-daemon" \ + /etc/systemd/system/guix-daemon.service + then + install_unit gnu-store.mount + fi systemctl daemon-reload && systemctl start guix-daemon; } && @@ -627,6 +691,10 @@ project's build farms?"; then && guix archive --authorize < "$key" \ && _msg "${PAS}Authorized public key for $host" done + if id guix-daemon &>/dev/null; then + # /etc/guix/acl must be readable by the unprivileged guix-daemon. + chown -R guix-daemon:guix-daemon /etc/guix + fi else _msg "${INF}Skipped authorizing build farm public keys" fi