From unknown Wed Sep 10 18:55:33 2025 X-Loop: help-debbugs@gnu.org Subject: bug#47229: Local privilege escalation via guix-daemon and =?UTF-8?Q?=E2=80=98--keep-failed=E2=80=99?= Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: leo@famulari.name, bug-guix@gnu.org Resent-Date: Thu, 18 Mar 2021 11:18:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 47229 X-GNU-PR-Package: guix X-GNU-PR-Keywords: To: 47229@debbugs.gnu.org Cc: Leo Famulari X-Debbugs-Original-To: X-Debbugs-Original-Xcc: Leo Famulari Received: via spool by submit@debbugs.gnu.org id=B.16160662459670 (code B ref -1); Thu, 18 Mar 2021 11:18:02 +0000 Received: (at submit) by debbugs.gnu.org; 18 Mar 2021 11:17:25 +0000 Received: from localhost ([127.0.0.1]:45234 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMqea-0002Vt-EG for submit@debbugs.gnu.org; Thu, 18 Mar 2021 07:17:24 -0400 Received: from lists.gnu.org ([209.51.188.17]:56814) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMqeV-0002Ve-9c for submit@debbugs.gnu.org; Thu, 18 Mar 2021 07:17:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41040) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lMqeT-0001tS-Qx for bug-guix@gnu.org; Thu, 18 Mar 2021 07:17:18 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:52987) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lMqeT-0002vn-Bs for bug-guix@gnu.org; Thu, 18 Mar 2021 07:17:17 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=51680 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1lMqeS-0002A3-PW for bug-guix@gnu.org; Thu, 18 Mar 2021 07:17:17 -0400 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 28 =?UTF-8?Q?Vent=C3=B4se?= an 229 de la =?UTF-8?Q?R=C3=A9volution?= X-PGP-Key-ID: 0x090B11993D9AEBB5 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5 X-OS: x86_64-pc-linux-gnu Date: Thu, 18 Mar 2021 12:17:15 +0100 Message-ID: <87lfaksock.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable A security vulnerability that can lead to local privilege escalation has been found in =E2=80=99guix-daemon=E2=80=99. It affects multi-user setups = in which =E2=80=99guix-daemon=E2=80=99 runs locally. It does not affect multi-user setups where =E2=80=98guix-daemon=E2=80=99 ru= ns on a separate machine and is accessed over the network, via =E2=80=98GUIX_DAEMON_SOCKET=E2=80=99, as is customary on cluster setups. M= achines where the Linux =E2=80=9Cprotected hardlink=E2=80=9D[*] feature is enabled, which= is common, are also unaffected=E2=80=94this is the case when the contents of /proc/sys/fs/protected_hardlinks are 1. [*] https://www.kernel.org/doc/Documentation/sysctl/fs.txt Vulnerability ~~~~~~~~~~~~~ The attack consists in having an unprivileged user spawn a build process, for instance with =E2=80=98guix build=E2=80=99, that makes its bui= ld directory world-writable. The user then creates a hardlink within the build directory to a root-owned file from outside of the build directory, such as =E2=80=98/etc/shadow=E2=80=99. If the user passed the =E2=80=98--keep-f= ailed=E2=80=99 option and the build eventually fails, the daemon changes ownership of the whole build tree, including the hardlink, to the user. At that point, the user has write access to the target file. Fix ~~~ The fix (patch attached) consists in adding a root-owned =E2=80=9Cwrapper= =E2=80=9D directory in which the build directory itself is located. If the user passed the =E2=80=98--keep-failed=E2=80=99 option and the build fails, the = =E2=80=98guix-daemon=E2=80=99 first changes ownership of the build directory, and then, in two stages, moves the build directory into the location where users expect to find failed builds, roughly like this: 1. chown -R USER /tmp/guix-build-foo.drv-0/top 2. mv /tmp/guix-build-foo.drv-0{,.pivot} 3. mv /tmp/guix-build-foo.drv-0.pivot/top /tmp/guix-build-foo.drv-0 In step #1, /tmp/guix-build-foo.drv-0 remains root-owned, with permissions of #o700. Thus, only root can change directory into it or into =E2=80=98top=E2=80=99. Likewise in step #2. The build tree becomes accessible to the user once step #3 has succeeded, not before. These steps are performed after the package build scripts have stopped running. Additionally, the patch at enables protected hardlinks and symlinks by default on Guix System, which will protect against this class of vulnerability from now on. Credit ~~~~~~ We are grateful to Nathan Nye of WhiteBeam Security for reporting this bug and discussing fixes with us! Timeline ~~~~~~~~ We learned about this bug on the private guix-security@gnu.org list on February 7th, and discussed and prepared fixes in the interim. Ludo=E2=80=99 & Leo Famulari. --=-=-= Content-Type: text/x-patch Content-Disposition: inline diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 20d83fea4a..4f486f0822 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -1621,6 +1621,24 @@ void DerivationGoal::startBuilder() auto drvName = storePathToName(drvPath); tmpDir = createTempDir("", "guix-build-" + drvName, false, false, 0700); + if (useChroot) { + /* Make the build directory seen by the build process a sub-directory. + That way, "/tmp/guix-build-foo.drv-0" is root-owned, and thus its + permissions cannot be changed by the build process, while + "/tmp/guix-build-foo.drv-0/top" is owned by the build user. This + cannot be done when !useChroot because then $NIX_BUILD_TOP would + be inaccessible to the build user by its full file name. + + If the build user could make the build directory world-writable, + 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. */ + tmpDir += "/top"; + if (mkdir(tmpDir.c_str(), 0700) == 1) + throw SysError("creating top-level build directory"); + } + /* In a sandbox, for determinism, always use the same temporary directory. */ tmpDirInSandbox = useChroot ? canonPath("/tmp", true) + "/guix-build-" + drvName + "-0" : tmpDir; @@ -2626,20 +2644,41 @@ static void _chown(const Path & path, uid_t uid, gid_t gid) void DerivationGoal::deleteTmpDir(bool force) { if (tmpDir != "") { + // When useChroot is true, tmpDir looks like + // "/tmp/guix-build-foo.drv-0/top". Its parent is root-owned. + string top; + if (useChroot) { + if (baseNameOf(tmpDir) != "top") abort(); + top = dirOf(tmpDir); + } else top = tmpDir; + if (settings.keepFailed && !force) { printMsg(lvlError, format("note: keeping build directory `%2%'") - % drvPath % tmpDir); + % drvPath % top); chmod(tmpDir.c_str(), 0755); + // 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); + + if (top != tmpDir) { + // Rename tmpDir to its parent, with an intermediate step. + string pivot = top + ".pivot"; + if (rename(top.c_str(), pivot.c_str()) == -1) + throw SysError("pivoting failed build tree"); + if (rename((pivot + "/top").c_str(), top.c_str()) == -1) + throw SysError("renaming failed build tree"); + rmdir(pivot.c_str()); + } } } - else + else { deletePath(tmpDir); + if (top != tmpDir) rmdir(dirOf(tmpDir).c_str()); + } tmpDir = ""; } } --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Thu Mar 18 07:18:42 2021 Received: (at control) by debbugs.gnu.org; 18 Mar 2021 11:18:42 +0000 Received: from localhost ([127.0.0.1]:45248 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMqfq-0002Yr-1O for submit@debbugs.gnu.org; Thu, 18 Mar 2021 07:18:42 -0400 Received: from eggs.gnu.org ([209.51.188.92]:48548) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMqfl-0002YR-UI for control@debbugs.gnu.org; Thu, 18 Mar 2021 07:18:40 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:53016) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lMqfg-0003eD-PD for control@debbugs.gnu.org; Thu, 18 Mar 2021 07:18:32 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=51690 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1lMqfg-0002Ht-7o for control@debbugs.gnu.org; Thu, 18 Mar 2021 07:18:32 -0400 Date: Thu, 18 Mar 2021 12:18:30 +0100 Message-Id: <87k0q4soah.fsf@gnu.org> To: control@debbugs.gnu.org From: =?utf-8?Q?Ludovic_Court=C3=A8s?= Subject: control message for bug #47229 MIME-version: 1.0 Content-type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) tags 47229 + security quit From debbugs-submit-bounces@debbugs.gnu.org Thu Mar 18 07:18:46 2021 Received: (at control) by debbugs.gnu.org; 18 Mar 2021 11:18:46 +0000 Received: from localhost ([127.0.0.1]:45251 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMqfu-0002Z7-Bc for submit@debbugs.gnu.org; Thu, 18 Mar 2021 07:18:46 -0400 Received: from eggs.gnu.org ([209.51.188.92]:48568) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMqfs-0002Yg-7b for control@debbugs.gnu.org; Thu, 18 Mar 2021 07:18:44 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:53017) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lMqfn-0003iT-3O for control@debbugs.gnu.org; Thu, 18 Mar 2021 07:18:39 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=51692 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1lMqfm-0002IL-FG for control@debbugs.gnu.org; Thu, 18 Mar 2021 07:18:38 -0400 Date: Thu, 18 Mar 2021 12:18:36 +0100 Message-Id: <87im5osoab.fsf@gnu.org> To: control@debbugs.gnu.org From: =?utf-8?Q?Ludovic_Court=C3=A8s?= Subject: control message for bug #47229 MIME-version: 1.0 Content-type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) severity 47229 serious quit From unknown Wed Sep 10 18:55:33 2025 X-Loop: help-debbugs@gnu.org Subject: bug#47229: Local privilege escalation via guix-daemon and =?UTF-8?Q?=E2=80=98--keep-failed=E2=80=99?= Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Thu, 18 Mar 2021 11:46:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47229 X-GNU-PR-Package: guix X-GNU-PR-Keywords: security To: 47229@debbugs.gnu.org Cc: Leo Famulari Received: via spool by 47229-submit@debbugs.gnu.org id=B47229.161606794720860 (code B ref 47229); Thu, 18 Mar 2021 11:46:02 +0000 Received: (at 47229) by debbugs.gnu.org; 18 Mar 2021 11:45:47 +0000 Received: from localhost ([127.0.0.1]:45292 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMr62-0005QO-QR for submit@debbugs.gnu.org; Thu, 18 Mar 2021 07:45:47 -0400 Received: from eggs.gnu.org ([209.51.188.92]:54834) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMr60-0005Q4-5x for 47229@debbugs.gnu.org; Thu, 18 Mar 2021 07:45:44 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:53299) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lMr5u-0002LZ-SS; Thu, 18 Mar 2021 07:45:38 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=51782 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1lMr5u-0004bW-7t; Thu, 18 Mar 2021 07:45:38 -0400 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= References: <87lfaksock.fsf@gnu.org> Date: Thu, 18 Mar 2021 12:45:36 +0100 In-Reply-To: <87lfaksock.fsf@gnu.org> ("Ludovic =?UTF-8?Q?Court=C3=A8s?="'s message of "Thu, 18 Mar 2021 12:17:15 +0100") Message-ID: <878s6ksn1b.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Ludovic Court=C3=A8s skribis: > The fix (patch attached) consists in adding a root-owned =E2=80=9Cwrapper= =E2=80=9D > directory in which the build directory itself is located. The fix has now been pushed: https://git.savannah.gnu.org/cgit/guix.git/commit/?id=3Dec7fb669945bfb47c= 5e1fdf7de3a5d07f7002ccf Followed by an update of the =E2=80=98guix=E2=80=99 package to make the fix= available: https://git.savannah.gnu.org/cgit/guix.git/commit/?id=3D94f03125463ee0dba= 2f7916fcd43fd19d4b6c892 We recommend upgrading the daemon (using commit 94f03125 or later). On Guix System, you achieve that by running something along these lines: guix pull sudo guix system reconfigure /run/current-system/configuration.scm sudo herd restart guix-daemon On other distros, assuming services are managed by systemd: sudo --login guix pull sudo systemctl restart guix-daemon.service (See .) Ludo=E2=80=99. From unknown Wed Sep 10 18:55:33 2025 X-Loop: help-debbugs@gnu.org Subject: bug#47229: Local privilege escalation via guix-daemon and =?UTF-8?Q?=E2=80=98--keep-failed=E2=80=99?= Resent-From: =?UTF-8?Q?L=C3=A9o?= Le Bouter Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Thu, 18 Mar 2021 11:55:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47229 X-GNU-PR-Package: guix X-GNU-PR-Keywords: security To: Ludovic =?UTF-8?Q?Court=C3=A8s?= , 47229@debbugs.gnu.org Received: via spool by 47229-submit@debbugs.gnu.org id=B47229.161606846221645 (code B ref 47229); Thu, 18 Mar 2021 11:55:02 +0000 Received: (at 47229) by debbugs.gnu.org; 18 Mar 2021 11:54:22 +0000 Received: from localhost ([127.0.0.1]:45303 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMrEK-0005d2-Ts for submit@debbugs.gnu.org; Thu, 18 Mar 2021 07:54:21 -0400 Received: from mail.zaclys.net ([178.33.93.72]:37415) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMrE3-0005cE-Rv for 47229@debbugs.gnu.org; Thu, 18 Mar 2021 07:54:19 -0400 Received: from [192.168.0.27] (82-64-145-38.subs.proxad.net [82.64.145.38]) (authenticated bits=0) by mail.zaclys.net (8.14.7/8.14.7) with ESMTP id 12IBrvCJ008119 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 18 Mar 2021 12:53:57 +0100 DMARC-Filter: OpenDMARC Filter v1.3.2 mail.zaclys.net 12IBrvCJ008119 Authentication-Results: mail.zaclys.net; dmarc=fail (p=reject dis=none) header.from=zaclys.net Authentication-Results: mail.zaclys.net; spf=fail smtp.mailfrom=lle-bout@zaclys.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zaclys.net; s=default; t=1616068437; bh=iDiuIas2hnDKK1LATH2AI9WEoEj0Q501a6nr0C9o+M0=; h=Subject:From:To:Date:In-Reply-To:References:From; b=klMf8ZStDDpbAo5gC3YVUiE9bV9B/wknFfu4Lw7ZVjDF15cauXurnZKX8b9bA9sQ5 ftylrelrWpmw0cQzNeZjRkRS+ltu6ZBfZ8zQ18LwYZ772MkKvcy/eUrygA5+3JcDpo wFN4L6hZg2kkpASHG7sM0b8gSBOyj3sBot4g/FNs= Message-ID: <9cd72f29cb33019439d2d71d6a313f930b3e7941.camel@zaclys.net> From: =?UTF-8?Q?L=C3=A9o?= Le Bouter Date: Thu, 18 Mar 2021 12:53:51 +0100 In-Reply-To: <87lfaksock.fsf@gnu.org> References: <87lfaksock.fsf@gnu.org> Content-Type: multipart/signed; micalg="pgp-sha512"; protocol="application/pgp-signature"; boundary="=-CdZYuIofjoJ5+1YZsMHT" User-Agent: Evolution 3.34.2 MIME-Version: 1.0 X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) --=-CdZYuIofjoJ5+1YZsMHT Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Thanks a lot to the reporter and for working on this! --=-CdZYuIofjoJ5+1YZsMHT Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEFIvLi9gL+xax3g6RRaix6GvNEKYFAmBTP08ACgkQRaix6GvN EKZemw/+Lzhig+JBobZMvUq58WOC1Am98EFd8FmNzlTan7T1CHYevgJ1bi79dOho exqyQ6Vd9klEQGSImOdHivvB7xd5Ds/VQqPGrT+wmNI+29hL3yx4Eh0wdwbsLUbU rMwpuEA/gNNQgmJplRkmhzVRwdfxVcYOzmTfOj4yUmaCPUjLxsy9a4HuFmuSMzL9 qyt6EjCJvXx9GWp2iOt4+3ON8diIYgl/k8d+9an907mSBmJbJoD5+pb7mwqb+SCV 9nGz8eGsHBLXK8YVo55CfkHQJ3lf6E96WM+PgF3cfIVQbOBfSmHsX4DGv9spnbV6 SOP9ucT1Miuvqs1XqzIHRM5NAmkF2Pg07mfWUpSDd5DXFLtwYpWBuX2F4t5stIyF 7Yut+mLrWF8ImV4Mk4Ut1VDtjtpANkwXYr4WbSrL06DQlYeF0wW62UrEHElyCMVV J+B0Xk9Z3Z5OFEUXeOltwMzEYOYT/LxbUm8W5iQVnHMXY6ufTg3RNod1JqOP3Rhx SJkmSj9hpNlGzJLWdYtpJEldaZLlU4Ufcm/+YGYhVgDHV+cOQIPY1H5zv/PTehJs abT2iCQzDy4ZuSybW8Qxt7Up2dUS+lzrjrB3psooIuOBf4zXmz0Zeozm2hVxx1uX cHVJcAOdntAb30+P/YjLNEwTTDLpJ8+D9pw6ios4hc4OT3yYUC8= =25iD -----END PGP SIGNATURE----- --=-CdZYuIofjoJ5+1YZsMHT-- From unknown Wed Sep 10 18:55:33 2025 X-Loop: help-debbugs@gnu.org Subject: bug#47229: Local privilege escalation via guix-daemon and =?UTF-8?Q?=E2=80=98--keep-failed=E2=80=99?= Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Thu, 18 Mar 2021 13:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47229 X-GNU-PR-Package: guix X-GNU-PR-Keywords: security To: 47229@debbugs.gnu.org Cc: Leo Famulari Received: via spool by 47229-submit@debbugs.gnu.org id=B47229.161607327828956 (code B ref 47229); Thu, 18 Mar 2021 13:15:02 +0000 Received: (at 47229) by debbugs.gnu.org; 18 Mar 2021 13:14:38 +0000 Received: from localhost ([127.0.0.1]:45331 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMsU2-0007Wy-H5 for submit@debbugs.gnu.org; Thu, 18 Mar 2021 09:14:38 -0400 Received: from eggs.gnu.org ([209.51.188.92]:46598) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMsU1-0007Wk-H7 for 47229@debbugs.gnu.org; Thu, 18 Mar 2021 09:14:37 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:54700) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lMsTv-0002mP-0G; Thu, 18 Mar 2021 09:14:32 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=53122 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1lMsTu-0001vF-CM; Thu, 18 Mar 2021 09:14:30 -0400 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= References: <87lfaksock.fsf@gnu.org> <878s6ksn1b.fsf@gnu.org> Date: Thu, 18 Mar 2021 14:14:28 +0100 In-Reply-To: <878s6ksn1b.fsf@gnu.org> ("Ludovic =?UTF-8?Q?Court=C3=A8s?="'s message of "Thu, 18 Mar 2021 12:45:36 +0100") Message-ID: <87tup8r4cr.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) An additional data point: guix-daemon chowns build trees to the caller upon failure (a very handy feature) since this 2016 commit: https://git.savannah.gnu.org/cgit/guix.git/commit/?id=2608e40988ba8cf51723fe0d21bdedf6b3997c9c The Nix build daemon, which guix-daemon is based on, did not have this feature. From debbugs-submit-bounces@debbugs.gnu.org Thu Mar 18 09:27:08 2021 Received: (at control) by debbugs.gnu.org; 18 Mar 2021 13:27:08 +0000 Received: from localhost ([127.0.0.1]:45366 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMsg8-0007sq-7A for submit@debbugs.gnu.org; Thu, 18 Mar 2021 09:27:08 -0400 Received: from eggs.gnu.org ([209.51.188.92]:49202) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMsg6-0007sK-Tq for control@debbugs.gnu.org; Thu, 18 Mar 2021 09:27:07 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:54833) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lMsg1-0001Yw-Ol for control@debbugs.gnu.org; Thu, 18 Mar 2021 09:27:01 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=53156 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1lMsg0-000384-WF for control@debbugs.gnu.org; Thu, 18 Mar 2021 09:27:01 -0400 Date: Thu, 18 Mar 2021 14:26:59 +0100 Message-Id: <877dm4r3rw.fsf@gnu.org> To: control@debbugs.gnu.org From: =?utf-8?Q?Ludovic_Court=C3=A8s?= Subject: control message for bug #47229 MIME-version: 1.0 Content-type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) tags 47229 fixed close 47229 quit From unknown Wed Sep 10 18:55:33 2025 X-Loop: help-debbugs@gnu.org Subject: bug#47229: Local privilege escalation via guix-daemon and =?UTF-8?Q?=E2=80=98--keep-failed=E2=80=99?= Resent-From: Leo Famulari Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Thu, 18 Mar 2021 21:11:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47229 X-GNU-PR-Package: guix X-GNU-PR-Keywords: security fixed To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Cc: 47229@debbugs.gnu.org Received: via spool by 47229-submit@debbugs.gnu.org id=B47229.16161018595244 (code B ref 47229); Thu, 18 Mar 2021 21:11:02 +0000 Received: (at 47229) by debbugs.gnu.org; 18 Mar 2021 21:10:59 +0000 Received: from localhost ([127.0.0.1]:48214 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMzv1-0001MW-CN for submit@debbugs.gnu.org; Thu, 18 Mar 2021 17:10:59 -0400 Received: from wout4-smtp.messagingengine.com ([64.147.123.20]:44155) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lMzuz-0001MJ-Ok for 47229@debbugs.gnu.org; Thu, 18 Mar 2021 17:10:58 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.west.internal (Postfix) with ESMTP id DFFEC1032; Thu, 18 Mar 2021 17:10:51 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Thu, 18 Mar 2021 17:10:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=famulari.name; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=mesmtp; bh=8TLljeB3SoeHAoBN+XuZKK0D 8txlXCK4cAEQbusTF/c=; b=RkAwBBAjbcjeGbkd4Ml5sdtYTxIP6XjMnSZG7Wmk uIKFSOQgY9Zt+msrh6yWQcFBxzQM+Lk4CUlTQdT65fWDgjxfgTn3hnkiaFUhOqnc LeVUVRjHalXKGLwmIBReeDo6mwbUDuljt+uhosHTm9liZjBSGkyEkq6kqXF31T2N 5xo= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=8TLlje B3SoeHAoBN+XuZKK0D8txlXCK4cAEQbusTF/c=; b=QeVYIT7H732MtS+4jgh5jw rKimPuCwx02hmihDSF5h/ozmGdsEKh7BwZoAhBcXn0twamGllc9Lv7I6V2bB5RQL pXsqWsZpN0EIyQK/vy+/5uRkhxNqI3kfj7gnZkk53/8QC8KJp4G+h5YGkmgjS3Tk ZehMBrjmmuRQ+Nm+KxaF5j2yiuOUfqIJKrljRfgWilE5FdKWEBhF4KQg2mGKGQCi mya6XTIFy75YybLi9vtldUq12moOLP/dEgrhhV/pNUtCabXtk7JwlOEX1HQX62Su vyliRw74de6wF5s2ksA3tG7dYKFVqwE72e0m9PcI35OtPehauCFl8JVqrarI1iYw == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrudefiedgudegkecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtjeenucfhrhhomhepnfgvohcu hfgrmhhulhgrrhhiuceolhgvohesfhgrmhhulhgrrhhirdhnrghmvgeqnecuggftrfgrth htvghrnhephfekvdduieehfedttdduledvgfehleevleejheettddvffevgeejgeetueff keetnecuffhomhgrihhnpehgnhhurdhorhhgnecukfhppedutddtrdduuddrudeiledrud dukeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehl vghosehfrghmuhhlrghrihdrnhgrmhgv X-ME-Proxy: Received: from localhost (pool-100-11-169-118.phlapa.fios.verizon.net [100.11.169.118]) by mail.messagingengine.com (Postfix) with ESMTPA id 31B7B24005D; Thu, 18 Mar 2021 17:10:51 -0400 (EDT) Date: Thu, 18 Mar 2021 17:10:49 -0400 From: Leo Famulari Message-ID: References: <87lfaksock.fsf@gnu.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="dzF1svFDk/IQH/JI" Content-Disposition: inline In-Reply-To: <87lfaksock.fsf@gnu.org> X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --dzF1svFDk/IQH/JI Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Mar 18, 2021 at 12:17:15PM +0100, Ludovic Court=C3=A8s wrote: > It does not affect multi-user setups where =E2=80=98guix-daemon=E2=80=99 = runs on a > separate machine and is accessed over the network, via > =E2=80=98GUIX_DAEMON_SOCKET=E2=80=99, as is customary on cluster setups. = Machines where > the Linux =E2=80=9Cprotected hardlink=E2=80=9D[*] feature is enabled, whi= ch is common, > are also unaffected=E2=80=94this is the case when the contents of > /proc/sys/fs/protected_hardlinks are 1. After publishing the advisory, we received a clarification about the impact of "protected hardlinks". When using a guix-daemon that does not include the fix [0] for the bug reported here, it is still possible for rogue build scripts to escape the build environment, even when protected hardlinks are enabled. Protected hardlinks do make exploitation significantly more difficult, but not impossible. For this reason, we continue to recommend that all Guix users upgrade their guix-daemons, as described in the original advisory. [0] https://git.savannah.gnu.org/cgit/guix.git/commit/?id=3Dec7fb669945bfb47c5e= 1fdf7de3a5d07f7002ccf --dzF1svFDk/IQH/JI Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEsFFZSPHn08G5gDigJkb6MLrKfwgFAmBTwdkACgkQJkb6MLrK fwhRjhAA7Q1QD4rjWsQv3r83DUZs2lGrH7lh8nJQTevij6xmFBNda4g+aFicdmq9 mHOeQLqnZKw/KOdVAcND1IXghKrjq0fiLA8cwxUG0XcrVAQjwCv58KLQMfjYbYfs L99rbFWLUbw6T9PlarWsiNOZSKfW0i8rycNGaWoYpNqhWczR4cdSWOcAjkt6u6Ps Wqk3PZmALPnT3gSMP4b6j8Ra/H8jgpo4RT4DmleMtt6aiVrA9r+ssRN8z2UwAVMg UZ2afiHyaQWN1flUzwCM0mVgaGhMUWAUriIWLTykRBZnI0hoboNrBvHrLa0lge81 oZBQ5cFepFMshTRLHXjP44A7KGRAH5WJlUGXCNlTr6s2ATxyfD6ZkcsU/a2HPxOj BJVvgZuSa78yNo3uHNzwkGsU6Ghi0muYFiet/gqUytH/BCHR44PyosKKRrChgfPa p/hnaA752w5bwYpUs10KcGjRGFsTLBlLl+cFqVGBa+oRT1Aq7DbdPFh1bBSREDfg piMX+L+4tweC0isOy7SaM2dnj1BNfg05hYwjDY4lY1uCTZ98dGRXaYElEev1h35c LHdunj8xM5HOJ18uNJ8pPxtyheR5WwSE4bb5IVOHRzfi7MXJja8ofrx7CBfb9IiO PWmmwrXWsSaLg+OjI1NXIfGgCFH+sH3uzmNaT4hs63IysIYKEo0= =QbGk -----END PGP SIGNATURE----- --dzF1svFDk/IQH/JI-- From unknown Wed Sep 10 18:55:33 2025 X-Loop: help-debbugs@gnu.org Subject: bug#47229: Hardlink mitigation limits Resent-From: Nathan Nye Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Tue, 23 Mar 2021 19:01:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47229 X-GNU-PR-Package: guix X-GNU-PR-Keywords: security fixed To: 47229@debbugs.gnu.org Received: via spool by 47229-submit@debbugs.gnu.org id=B47229.161652603027007 (code B ref 47229); Tue, 23 Mar 2021 19:01:01 +0000 Received: (at 47229) by debbugs.gnu.org; 23 Mar 2021 19:00:30 +0000 Received: from localhost ([127.0.0.1]:33007 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lOmGQ-00071U-I1 for submit@debbugs.gnu.org; Tue, 23 Mar 2021 15:00:30 -0400 Received: from mail-qk1-f182.google.com ([209.85.222.182]:36743) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lOlbm-0005zu-Gb for 47229@debbugs.gnu.org; Tue, 23 Mar 2021 14:18:28 -0400 Received: by mail-qk1-f182.google.com with SMTP id c4so15347973qkg.3 for <47229@debbugs.gnu.org>; Tue, 23 Mar 2021 11:18:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=whitebeamsec.com; s=google; h=references:to:from:organization:subject:message-id:date:user-agent :mime-version:in-reply-to:content-language; bh=Y9LUfY/800DANE7OF7b2/GwfJWxirD6xrL/HqcZuMb8=; b=lrLrv8QU1v6AsI8gFF0ISARvVqmjlPXvuLYOFGvLAY/BAIE8VUPxLEeKTAYtMON3nt HMAURVn09cEpbGXZ2dSdxElyN95k6tfoAYHMsTjQDGW5a9zfOd8NltM2FbbjduWglW1M 4i1JWzUURoE97QR2VBAm0rAsP38XDSnWb6COKWiCuqDSHQ7e3OCu92fnwANvpESZlaS1 NwcX+xblWKEH2LYWOOZGShm427mO/jBzyChR6z9lqLQrUlJlwwko9UUI/uI6j50sBdcM kxyFj41yS36uHvA7X8y40bk7ugDtaPsR0RzT3/hcBYtwF34D32Cs8CPF4IY3UvS6s0gu xZeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:references:to:from:organization:subject :message-id:date:user-agent:mime-version:in-reply-to :content-language; bh=Y9LUfY/800DANE7OF7b2/GwfJWxirD6xrL/HqcZuMb8=; b=U2jadky+Jmr6+/cvcZ+q5C5o5lnAMaZh90KiIGsysMkC0q7C1bakzxTyy770/tiRGg bomEz2eQDZIr5YVWujkHVHGzO0qiuEuybcBxldSsvPtP28FlAwYKyufiEKtvs/am2qB6 P2vXDgNUDsOxjLpPY6D+ul+n1zq1XzDRkbjxPeZkVjh6G+drFTfh0OW9AnQC9mthYpUa pVANh/lbfORdApVfH952jqo+DZ5CZeYC44B7PPvH3NZVpFW0m83Qar8U5Sp+z6I5ii1B s7/cSRX0UGegBBnu6fxKBHORZGo0CAOrTC3C1OWiVpayo24hzEmYjsFGTDjCNPg7qWWx SKZA== X-Gm-Message-State: AOAM531iiH8fr+pFW3VfDojweT7Sk2ZC5bfAun6pTTmF3o1sRQmCvf6H umXG1XZAIkN7GmdIoYeTtx/AJPiy/w89Momi0Ls= X-Google-Smtp-Source: ABdhPJySEJkVYzuUu019qNtK3lARwkZKUAff4taLD/7eRcy6Tkkzyv1X2+VMVN0D7WhB9QyIgxkX/w== X-Received: by 2002:a37:a9cf:: with SMTP id s198mr6432295qke.143.1616523500268; Tue, 23 Mar 2021 11:18:20 -0700 (PDT) Received: from [10.0.2.15] (93-94-240-221.mobileaccess.monzoon.net. [93.94.240.221]) by smtp.gmail.com with ESMTPSA id z5sm13796671qkz.2.2021.03.23.11.18.18 for <47229@debbugs.gnu.org> (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 23 Mar 2021 11:18:19 -0700 (PDT) References: From: Nathan Nye Organization: WhiteBeam Security, Inc. X-Forwarded-Message-Id: Message-ID: <8f95179a-5574-98bd-c44e-f5ee74638dc3@whitebeamsec.com> Date: Tue, 23 Mar 2021 14:18:14 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------56E58B699AC93465FA9C8949" Content-Language: en-US X-Spam-Score: 0.0 (/) X-Mailman-Approved-At: Tue, 23 Mar 2021 15:00:25 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) This is a multi-part message in MIME format. --------------56E58B699AC93465FA9C8949 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Hello, I'm sharing here for future reference why protected hardlinks alone did=20 not mitigate the recent LPE security advisory, pre-patch: "The reasons why are lines 2633 and 2637 of nix/libstore/build.cc: * https://git.savannah.gnu.org/cgit/guix.git/tree/nix/libstore/build.cc= #n2633 * https://git.savannah.gnu.org/cgit/guix.git/tree/nix/libstore/build.cc= #n2637 When a package fails to build and the keep failed flag is set=20 (-K/--keep-failed), it runs a recursive chown on the build directory=20 (which is writable following guixbuilder01 changing the permissions to=20 777). It starts at the top level and chowns downwards. The first important thing to notice here is that at any point (even=20 pre-chown) the build user has been compromised. The build user can write = a SUID /bin/sh to the build path, and because a normal user can traverse = into the directory before and during the chown, they can run a SUID=20 shell (allowing them to become guixbuilder01 even after the build user=20 processes are terminated). Becoming the build user allows multiple paths = to privilege escalation, but in this scenario we have faster ways of=20 becoming root. Moving on to getting root, we're choosing not to use a hardlink to show=20 why it isn't necessary. Instead, we create a directory under the build=20 directory with thousands of sequentially named files, the final entry=20 being "passwd" or "shadow". Then we terminate the build and watch for=20 the first entry to be chowned to our user ID (possibly with the inotify=20 API). This way, we have opened a lengthy window of time where it is=20 enumerating over a list of file paths in our chosen directory and=20 chowning each of them. Now we can execute our TOCTOU race condition=20 vulnerability. At the time of check (TOC), the guix-daemon has a list of file paths to=20 chown under what it assumes is a regular directory (because it ran=20 S_ISDIR on the directory). But we can swap out the directory from under=20 it with a symlink to /etc (most efficiently with renameat2() and using=20 the RENAME_EXCHANGE flag to atomically exchange the paths). At the time=20 of use (TOU) lchown() only checks if the file /itself/ that is being=20 chowned is a symlink, not if the path components are, as can be=20 demonstrated with Python: $ mkdir td;touch td/tf;python3 -c 'import os;os.lchown("/home/example/td/= tf", 1000, 4)';ls -lahtrd td td/tf -rw-rw-r-- 1 example adm=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0 Mar 19 = 19:20 td/tf drwxrwxr-x 2 example example 4.0K Mar 19 19:20 td $ rm -rf td $ mkdir td; ln -s td td2;touch td2/tf;python3 -c 'import os;os.lchown("/h= ome/example/td2/tf", 1000, 4)';ls -lahtrd td2 td2/tf lrwxrwxrwx 1 example example 2 Mar 19 19:21 td2 -> td -rw-rw-r-- 1 example adm=C2=A0=C2=A0=C2=A0 0 Mar 19 19:21 td2/tf So lchown can blindly chown /etc/passwd to our user by following the=20 directory symlink and subsequently verifying that passwd itself is not a = symlink. I hope this explains the TOCTOU race condition and why=20 protected hardlinks help (forcing an attacker to get root using this=20 race condition), but they are not a solution to the problem (alone)." - Nathan --------------56E58B699AC93465FA9C8949 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit

Hello,

I'm sharing here for future reference why protected hardlinks alone did not mitigate the recent LPE security advisory, pre-patch:

"The reasons why are lines 2633 and 2637 of nix/libstore/build.cc:

When a package fails to build and the keep failed flag is set (-K/--keep-failed), it runs a recursive chown on the build directory (which is writable following guixbuilder01 changing the permissions to 777). It starts at the top level and chowns downwards.

The first important thing to notice here is that at any point (even pre-chown) the build user has been compromised. The build user can write a SUID /bin/sh to the build path, and because a normal user can traverse into the directory before and during the chown, they can run a SUID shell (allowing them to become guixbuilder01 even after the build user processes are terminated). Becoming the build user allows multiple paths to privilege escalation, but in this scenario we have faster ways of becoming root.

Moving on to getting root, we're choosing not to use a hardlink to show why it isn't necessary. Instead, we create a directory under the build directory with thousands of sequentially named files, the final entry being "passwd" or "shadow". Then we terminate the build and watch for the first entry to be chowned to our user ID (possibly with the inotify API). This way, we have opened a lengthy window of time where it is enumerating over a list of file paths in our chosen directory and chowning each of them. Now we can execute our TOCTOU race condition vulnerability.

At the time of check (TOC), the guix-daemon has a list of file paths to chown under what it assumes is a regular directory (because it ran S_ISDIR on the directory). But we can swap out the directory from under it with a symlink to /etc (most efficiently with renameat2() and using the RENAME_EXCHANGE flag to atomically exchange the paths). At the time of use (TOU) lchown() only checks if the file itself that is being chowned is a symlink, not if the path components are, as can be demonstrated with Python:

$ mkdir td;touch td/tf;python3 -c 'import os;os.lchown("/home/example/td/tf", 1000, 4)';ls -lahtrd td td/tf
-rw-rw-r-- 1 example adm       0    Mar 19 19:20 td/tf
drwxrwxr-x 2 example example   4.0K Mar 19 19:20 td
$ rm -rf td
$ mkdir td; ln -s td td2;touch td2/tf;python3 -c 'import os;os.lchown("/home/example/td2/tf", 1000, 4)';ls -lahtrd td2 td2/tf
lrwxrwxrwx 1 example example 2 Mar 19 19:21 td2 -> td
-rw-rw-r-- 1 example adm     0 Mar 19 19:21 td2/tf

So lchown can blindly chown /etc/passwd to our user by following the directory symlink and subsequently verifying that passwd itself is not a symlink. I hope this explains the TOCTOU race condition and why protected hardlinks help (forcing an attacker to get root using this race condition), but they are not a solution to the problem (alone)."

- Nathan

--------------56E58B699AC93465FA9C8949-- From unknown Wed Sep 10 18:55:33 2025 X-Loop: help-debbugs@gnu.org Subject: bug#47229: Hardlink mitigation limits Resent-From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Mon, 29 Mar 2021 15:23:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47229 X-GNU-PR-Package: guix X-GNU-PR-Keywords: security fixed To: Nathan Nye Cc: 47229@debbugs.gnu.org Received: via spool by 47229-submit@debbugs.gnu.org id=B47229.16170313585919 (code B ref 47229); Mon, 29 Mar 2021 15:23:02 +0000 Received: (at 47229) by debbugs.gnu.org; 29 Mar 2021 15:22:38 +0000 Received: from localhost ([127.0.0.1]:49277 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lQtiw-0001XO-Bd for submit@debbugs.gnu.org; Mon, 29 Mar 2021 11:22:38 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33940) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lQtiv-0001X6-TF for 47229@debbugs.gnu.org; Mon, 29 Mar 2021 11:22:38 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:45959) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lQtiq-00063Y-Mj; Mon, 29 Mar 2021 11:22:32 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=49154 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1lQtiq-0001oZ-4k; Mon, 29 Mar 2021 11:22:32 -0400 From: Ludovic =?UTF-8?Q?Court=C3=A8s?= References: <8f95179a-5574-98bd-c44e-f5ee74638dc3@whitebeamsec.com> X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 9 Germinal an 229 de la =?UTF-8?Q?R=C3=A9volution?= X-PGP-Key-ID: 0x090B11993D9AEBB5 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5 X-OS: x86_64-pc-linux-gnu Date: Mon, 29 Mar 2021 17:22:30 +0200 In-Reply-To: <8f95179a-5574-98bd-c44e-f5ee74638dc3@whitebeamsec.com> (Nathan Nye's message of "Tue, 23 Mar 2021 14:18:14 -0400") Message-ID: <87h7kunfwp.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Hi Nathan, Nathan Nye skribis: > I'm sharing here for future reference why protected hardlinks alone > did not mitigate the recent LPE security advisory, pre-patch: Thanks a lot for this clarification! Ludo=E2=80=99. From unknown Wed Sep 10 18:55:33 2025 X-Loop: help-debbugs@gnu.org Subject: bug#47229: Local privilege escalation via guix-daemon and =?UTF-8?Q?=E2=80=98--keep-failed=E2=80=99?= Resent-From: Leo Famulari Original-Sender: "Debbugs-submit" Resent-CC: bug-guix@gnu.org Resent-Date: Sat, 10 Apr 2021 17:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47229 X-GNU-PR-Package: guix X-GNU-PR-Keywords: security fixed To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Cc: 47229@debbugs.gnu.org Received: via spool by 47229-submit@debbugs.gnu.org id=B47229.161807739626370 (code B ref 47229); Sat, 10 Apr 2021 17:57:02 +0000 Received: (at 47229) by debbugs.gnu.org; 10 Apr 2021 17:56:36 +0000 Received: from localhost ([127.0.0.1]:53240 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lVHqW-0006rF-Fr for submit@debbugs.gnu.org; Sat, 10 Apr 2021 13:56:36 -0400 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:48553) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lVHqU-0006r2-Mz for 47229@debbugs.gnu.org; Sat, 10 Apr 2021 13:56:35 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id 869A25C0109; Sat, 10 Apr 2021 13:56:29 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Sat, 10 Apr 2021 13:56:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=famulari.name; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=mesmtp; bh=inXO13LDm/8EtoCypMGDy20b Xl7D7U9SKiXBW1Hx6K0=; b=E+ceK5ngUaeKDrNYm9lusB7AR5ZvvkkeWetfucDP 2iDzB6aHsMMADdjbrB2xLKYDShAZMgubbbV+te5kZ3PX0HueqQw9eubaQ3Gi7mi6 ucf7P013sc/yYD2syIjoBkwp2BNqyH1n7TQljRbyT4kl4b7WvhPZOwLW5/WogozW +eU= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=inXO13 LDm/8EtoCypMGDy20bXl7D7U9SKiXBW1Hx6K0=; b=AIzr3nWyINo0PSlDG3bMmH V89JDxbByxv45IudLJv8mWIlf+RYXB3P48pXV9F1QvgQEPYfSIQhaHwu/WosDCzU 1oqMoCC3neTDOcUI/if2h0ZKWl0YdyjbglC9MOBB1q81TucS8l2aUqFgpsf7EypK Q4TLYVHBgzS0R2UaxgyMiked5mtbJfB67hPIoRfCOPoy5R+k8bySmRjyziAuVlK7 JVzy/g54A9t6bZhR7H4AyQoVA2a5ipAZ8UiYGkgyBgRCD8vtBQinCiZZJa2RAR+1 mQvCyn4xYhtVdTKjY7t1JIIk4ZU6wF3Ulhjnkg3KF3MvlRST069HbubiKa+IGuwA == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrudekfedguddvtdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtjeenucfhrhhomhepnfgvohcu hfgrmhhulhgrrhhiuceolhgvohesfhgrmhhulhgrrhhirdhnrghmvgeqnecuggftrfgrth htvghrnhepvdehheelueevleevhedvkeeitdehheejveegkeehgeeuiedugfekgeduudeg udelnecuffhomhgrihhnpehmihhtrhgvrdhorhhgnecukfhppedutddtrdduuddrudeile druddukeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhm pehlvghosehfrghmuhhlrghrihdrnhgrmhgv X-ME-Proxy: Received: from localhost (pool-100-11-169-118.phlapa.fios.verizon.net [100.11.169.118]) by mail.messagingengine.com (Postfix) with ESMTPA id 0C4EE24005E; Sat, 10 Apr 2021 13:56:29 -0400 (EDT) Date: Sat, 10 Apr 2021 13:56:27 -0400 From: Leo Famulari Message-ID: References: <87lfaksock.fsf@gnu.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="1vCzjLauL+NnVyKm" Content-Disposition: inline In-Reply-To: <87lfaksock.fsf@gnu.org> X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) --1vCzjLauL+NnVyKm Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Thu, Mar 18, 2021 at 12:17:15PM +0100, Ludovic Court=C3=A8s wrote: > Vulnerability > ~~~~~~~~~~~~~ >=20 > The attack consists in having an unprivileged user spawn a build > process, for instance with =E2=80=98guix build=E2=80=99, that makes its b= uild directory > world-writable. The user then creates a hardlink within the build > directory to a root-owned file from outside of the build directory, such > as =E2=80=98/etc/shadow=E2=80=99. If the user passed the =E2=80=98--keep= -failed=E2=80=99 option and the > build eventually fails, the daemon changes ownership of the whole build > tree, including the hardlink, to the user. At that point, the user has > write access to the target file. This has been assigned CVE-2021-27851. Soon, it should be available in the CVE database at --1vCzjLauL+NnVyKm Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEsFFZSPHn08G5gDigJkb6MLrKfwgFAmBx5sgACgkQJkb6MLrK fwhIwBAAwbuP3cK68tXgVV4ho8HoCPa9Aww5EynTNrZcmPkElJgCgdg3Phb3i+Mo QY8S2jOXHlSg0cMgtYjePkPeL7bSeEmRGtUSiTq/HGXucJlfDT3D0wHNgtqBcIYN Mt6Z9ROHjb9GPkD29Si0H3UovwBOKDS5QlUWXGuaeC9Y5Itl7MYhhnJpsDRBhLGk +vCmWjxbgKh/qm2KYkKH/b3KR2BMSmPQhZ7MT37E9CTGo2eiodtbfUYhWh5OfpM+ iLIIcyMgULjF887KqSf6RGnt5ajolSh9zOZUXDwSqoEiMyH5g7g9rJyua7DvXYfO xrpXVtu5tRxuN6ME4g9m8eoakV28fSZ6VVR9X6mODcT1fD2amB8q32/kuOt6SORX NWvDwU0qcW+RAaN97KyrdQ95EQfYa0PTEdze+VUoar6LV124zCpvbqa8FkPJ1fF7 sKJw4+LvhVMWf+zhFfTeKCv+JgxZi06WFcaEMQSwvfI0wBhfsOE9P8M364t9BQ/l 5f05HxoySSEPpi9POoQGe38rKLlwkhIQvyiidSpEDn5azo6LLe577PCzdlQT7xqg lqvcfJIstD9jss43TdAQffZmaTrdaJe/AaY1SPh2HCzPe6dN3BGOP1FaZ94ltyZp q1/86spDa8eKW+LcLZng3TxUufjvQn5nIx8FUU+pHR110krvJ1s= =bt5R -----END PGP SIGNATURE----- --1vCzjLauL+NnVyKm--