From patchwork Sat Mar 22 15:57:45 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: 40617 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 896F327BBE9; Sat, 22 Mar 2025 15:59:16 +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 920C827BBE2 for ; Sat, 22 Mar 2025 15:59:14 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tw1Fc-00071Q-Vz; Sat, 22 Mar 2025 11:59:09 -0400 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 1tw1FX-00070v-8q for guix-patches@gnu.org; Sat, 22 Mar 2025 11:59:06 -0400 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 1tw1FW-0006fg-2U for guix-patches@gnu.org; Sat, 22 Mar 2025 11:59:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:Date:References:In-Reply-To:From:To:Subject; bh=dejlCC7VuaOU8Tp+QpyWfbh4dWhHwyViELFNXJdoyUI=; b=dYm+i1ov1o4H/LNrwMnnWqVNUuzYtgbRPfDWW1zc4syBMdtM4G6NVgvsX+vw9l0B0oP/D57oHQaLeJonaCu/2vkho5PNCg+kfqis6Seu6tC1wSMBorvmKCxmu3L+LA48pLfkRolFvgRneZdkuH5Ekyrq900DGommQujqCgPy1d6p6iycOCSvoziCirRRfOKkU7AsnaQgqGTKCZqNExH59nNE+bGvQZvqdxkQwL54EAwRj+jtqb3xH1OD4E3PoRwg42mZjHPqJZ/QLDJMJtH1Ry2CDmuPegGnM3UTOPHXN9wLE1MiS0qHK7/SwU5dP6klnrfE2N6NYOobnq6bRrnQXA==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tw1FV-0000Np-UR for guix-patches@gnu.org; Sat, 22 Mar 2025 11:59:01 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#75810] [PATCH v6 00/16] Rootless guix-daemon Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Sat, 22 Mar 2025 15:59:01 +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: Reepca Russelstein Cc: 75810@debbugs.gnu.org Received: via spool by 75810-submit@debbugs.gnu.org id=B75810.17426590831406 (code B ref 75810); Sat, 22 Mar 2025 15:59:01 +0000 Received: (at 75810) by debbugs.gnu.org; 22 Mar 2025 15:58:03 +0000 Received: from localhost ([127.0.0.1]:44829 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tw1EY-0000Mb-NQ for submit@debbugs.gnu.org; Sat, 22 Mar 2025 11:58:03 -0400 Received: from hera.aquilenet.fr ([185.233.100.1]:49184) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1tw1ER-0000Lv-OJ for 75810@debbugs.gnu.org; Sat, 22 Mar 2025 11:58:00 -0400 Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 0BB74D5D; Sat, 22 Mar 2025 16:57:48 +0100 (CET) Authentication-Results: hera.aquilenet.fr; none X-Virus-Scanned: Debian amavis at hera.aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavis, port 10024) with ESMTP id WdJmg-tfMJ3f; Sat, 22 Mar 2025 16:57:47 +0100 (CET) Received: from ribbon (91-160-117-201.subs.proxad.net [91.160.117.201]) by hera.aquilenet.fr (Postfix) with ESMTPSA id A4C4A7E7; Sat, 22 Mar 2025 16:57:45 +0100 (CET) From: Ludovic =?utf-8?q?Court=C3=A8s?= In-Reply-To: <87iko2gpgd.fsf@russelstein.xyz> (Reepca Russelstein's message of "Fri, 21 Mar 2025 14:21:06 -0500") References: <875xk7594u.fsf@russelstein.xyz> <87v7s6h21b.fsf@gnu.org> <871puu53mf.fsf@russelstein.xyz> <87tt7na08n.fsf@gnu.org> <87iko2gpgd.fsf@russelstein.xyz> Date: Sat, 22 Mar 2025 16:57:45 +0100 Message-ID: <87sen55a86.fsf@gnu.org> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 X-Rspamd-Queue-Id: 0BB74D5D X-Spamd-Result: default: False [4.90 / 15.00]; SPAM_FLAG(5.00)[]; BAYES_HAM(-3.00)[100.00%]; NEURAL_SPAM(3.00)[1.000]; MIME_GOOD(-0.10)[multipart/mixed,text/plain,text/x-patch]; RCVD_COUNT_TWO(0.00)[2]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+,1:+,2:+,3:+]; RCPT_COUNT_TWO(0.00)[2]; ARC_NA(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCVD_TLS_ALL(0.00)[]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; MID_RHS_MATCH_FROM(0.00)[] X-Rspamd-Action: no action X-Spamd-Bar: ++++ X-Rspamd-Server: hera 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 Hi Reepca, Reepca Russelstein skribis: > Ludovic Courtès writes: > >>> While ensuring that what actually gets execve'd is in the store suffices >>> to eliminate the vulnerability, it may be "conceptually purer" to >>> require that the links pointing to it are all in the store as well. For >>> example, while a builder that is a symlink pointing to /proc/self/exe >>> wouldn't be able to modify the daemon binary, it's still a piece of >>> basically "undefined behavior" as far as the build environment is >>> concerned, which could be closed up. But that can come later just as >>> well. >> >> Yes. But in practice, “normal” symlinks (i.e., not /proc/self/exe) will >> lead ‘canonPath’ to throw if one component is outside the store, since >> ‘canonPath’ operates within the chroot. > > Unless the component actually exists and is outside of the store. If we > just rely on canonPath throwing an exception to be safe, then if there > ever arose a situation where a non-symlink executable existed outside of > the store, it would still be possible to convince the daemon to execute > it. [...] > I mention this because I see that patch 07/16 of v7 has left out the > isInStore check, and I think it should remain. Hmm right (I was very much assuming that /proc/self/exe was the only non-store executable, but better be safe than sorry). Re-adding this: > While researching container escape vulnerabilities, I recently came > across CAP_DAC_READ_SEARCH and open_by_handle_at, which is a system call > so insanely powerful it is outright banned in all but the root user > namespace. Or at least, it was. 10 months ago, in commit > 620c266f394932e5decc4b34683a75dfc59dc2f4 of > https://github.com/torvalds/linux, the requirements were relaxed so > that, in certain cases, processes in non-root user namespaces could use > open_by_handle_at. The way ‘open_by_handle_at’ is documented (“half” of ‘openat’) does not make it immediately obvious to me what makes it “powerful”. I see the risk of a confused deputy problem though because of the ‘mount_id’ argument in addition to ‘handle’. Is that what you have in mind? > The consequences of this for same-user containers are not clear to me > yet, as I haven't studied the kernel source enough to know what exactly > that commit message means by "privileges over the filesystem" or > "privileges over a subtree". I also haven't been able to test this > behavior yet, because my kernel is actually too old (I do my rebases and > upgrades rather less regularly than is recommended). I'll try to look > into this more once I update my system (and man-pages!), but figured I > should mention it, because aside from that, and the aforementioned > isInStore check, I can't think of any remaining concerns. Alright. I’ll send v8 with the change above. Thanks again! Ludo’. diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index 1733322316..d0fcc99854 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -2390,6 +2390,9 @@ void DerivationGoal::runChild() within the chroot. */ builderBasename = baseNameOf(drv.builder); drv.builder = canonPath(drv.builder, true); + + if (!isInStore(drv.builder)) + throw Error(format("derivation builder '%1%' is outside the store") % drv.builder); } /* Fill in the arguments. */