Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp3430250iog; Mon, 27 Jun 2022 16:13:35 -0700 (PDT) X-Google-Smtp-Source: AGRyM1u8VZlCAn+QO+e6qIEOtkExfpiKXSmS4wgXgpA8VAf30LjPgjsMuGTr6RuP1qHoZj512QKf X-Received: by 2002:a17:907:94c9:b0:726:9747:edbc with SMTP id dn9-20020a17090794c900b007269747edbcmr10131628ejc.698.1656371615480; Mon, 27 Jun 2022 16:13:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656371615; cv=none; d=google.com; s=arc-20160816; b=ZnVP7qMspYoSxiqbgdZUKuPxsCtB5rP9TgiNw5E4nwSr82ppc40rUbR8VwNgyNg/yl Hi64W58QhzVHwlWJrtE/5S1p3fKeibTtvcanzDxoltbVbFtBVDp6cHaLs0GINQotmAi1 XNam56/dcchneDJ3Nz52MLA9+e6ymZ1Kua3x6rKbeMTGJzby0lakBq6JgubR69jCd3n8 PUE20GA4bqDVFNIltmGiSqhWj7gc+fOCmD+jDVJki+HyjLXS8rbicSYF4gl69ymomtJg aL1wnTBBhs7t794D3ZnWCxCuK+aOy9xBLY2ZhK8NbTTnAGay/uvo/N6hh7sh5hqX7X6z TcPA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=S6bwOwkX5Z4SGSfVMm1UXqbEyn0vLvM5TyBgzsUl/Fc=; b=K9R+itBAzsNacd4Is55NPS2c/ESVTluX67N/+C/sPi+6mO8jLixQCTkcIKKjc6g2Wg kRtmoEfrffMTyFhd2AUccYXWta+9aId/dhDo5Qb9yt36taNACVeVct8QK7HZ8rIi9TRe Oz+YgVkQ2jxZqj+KrYvdw6JmjtHORg9VGKH8EAVqvAUCqDFpPdkocKMIqezAmi/8L0TZ qIjmbfv7fQy7G+mdwotKDBQfqedb6dTXROljruL63tS5R3AFf3N1eKZk2TCn2LW/mzv+ h6WH9jJWDAAmq6BfCbXdKjsUNcYLKnhpp+yVQvB3WuhEJltiDmWfmeSyor2qzu5tUb3A OYag== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@paul-moore-com.20210112.gappssmtp.com header.s=20210112 header.b="WIN/GT25"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 1-20020a508e41000000b0042dd79cd7a6si13225845edx.557.2022.06.27.16.13.10; Mon, 27 Jun 2022 16:13:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@paul-moore-com.20210112.gappssmtp.com header.s=20210112 header.b="WIN/GT25"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240129AbiF0WNX (ORCPT + 99 others); Mon, 27 Jun 2022 18:13:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241914AbiF0WNT (ORCPT ); Mon, 27 Jun 2022 18:13:19 -0400 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3386560FB for ; Mon, 27 Jun 2022 15:13:17 -0700 (PDT) Received: by mail-wm1-x332.google.com with SMTP id m6-20020a05600c3b0600b003a0489f412cso1972828wms.1 for ; Mon, 27 Jun 2022 15:13:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paul-moore-com.20210112.gappssmtp.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=S6bwOwkX5Z4SGSfVMm1UXqbEyn0vLvM5TyBgzsUl/Fc=; b=WIN/GT25JMWQXYpou5yhbufZOZ52jehFNogFtuMhPrGblHj3rgciMNCiLXwB6buaTn PeuLPWBx8Z3cZ1u2Aj7Jvmkt77i0llP2A/+n7Lgw4VWMxoSZetHhy1RPuHxS0qWMHlxs VdjP86ZaE0PknIxnbZSM6dqtHVHfZHc9o5qGGj3VwMqvkf/JpVHW6Efnxgb04JSwPH7r PLFTqTtQG6Ft9JiFXcInmfitBMZ7kHX84lvwNy43yHqsWqgXRJagzDu5rRnkhwE5LlIh In1mPJP1AAK07noCszmXhRFUnacTse7du2Ka9gmKHkMBcFr1UN6ITpzQ+3Rzqh8BsNs1 kxng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=S6bwOwkX5Z4SGSfVMm1UXqbEyn0vLvM5TyBgzsUl/Fc=; b=lrntf8CTYW5Ff5uld03BsJWimMSNc3jui3g9KBI0IyTGN83v0RYSAB8CiH+cjJ3pdy qpXPSp7U9LGAnsld5YGOLUlfVzEdHRRrQSWHHT0m9DdA2F9yNC5/ujmyeFA06M3E+4sA vK+WPgMnm1+JRNSk27/2Xo3GvQP1zIcNsC27jCC5aHoXoARN/qJGp1lnjxra6v/5fltQ 4CRiZxCsQD9PkkjgelLjmnguHBz2HXMURHqMsQAyuZ18QOzFiLK86lBCqPrGudZUESgw EMo5MQd5YlqyTaZE+wJWMOU+4wHF7AHtYkq9PT3fa4ZPWwTbHDC0iGpdI8W+iN0nakQm 5smQ== X-Gm-Message-State: AJIora+/R8Gji4fo/QtTVHczL4fC3sndXEveZG6Q88FskWLLAHAq7CX3 YMWXmPB0B5UlsjeUgi7/SSZke6JWvff9bvdawWPa X-Received: by 2002:a05:600c:2246:b0:3a0:4d14:e9d5 with SMTP id a6-20020a05600c224600b003a04d14e9d5mr5318298wmm.70.1656367995692; Mon, 27 Jun 2022 15:13:15 -0700 (PDT) MIME-Version: 1.0 References: <20220621233939.993579-1-fred@cloudflare.com> <20220627121137.cnmctlxxtcgzwrws@wittgenstein> In-Reply-To: From: Paul Moore Date: Mon, 27 Jun 2022 18:13:04 -0400 Message-ID: Subject: Re: [PATCH 0/2] Introduce security_create_user_ns() To: Frederick Lawler Cc: Christian Brauner , Casey Schaufler , kpsingh@kernel.org, revest@chromium.org, jackmanb@chromium.org, ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, kafai@fb.com, songliubraving@fb.com, yhs@fb.com, john.fastabend@gmail.com, jmorris@namei.org, serge@hallyn.com, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-team@cloudflare.com Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Jun 27, 2022 at 11:51 AM Frederick Lawler wrote: > On 6/27/22 7:11 AM, Christian Brauner wrote: > > On Thu, Jun 23, 2022 at 11:21:37PM -0400, Paul Moore wrote: > >> On Wed, Jun 22, 2022 at 10:24 AM Frederick Lawler wrote: > >>> On 6/21/22 7:19 PM, Casey Schaufler wrote: > >>>> On 6/21/2022 4:39 PM, Frederick Lawler wrote: ... > >>>>> While creating a LSM BPF MAC policy to block user namespace creation, we > >>>>> used the LSM cred_prepare hook because that is the closest hook to > >>>>> prevent > >>>>> a call to create_user_ns(). > >>>>> > >>>>> The calls look something like this: > >>>>> > >>>>> cred = prepare_creds() > >>>>> security_prepare_creds() > >>>>> call_int_hook(cred_prepare, ... > >>>>> if (cred) > >>>>> create_user_ns(cred) > >>>>> > >>>>> We noticed that error codes were not propagated from this hook and > >>>>> introduced a patch [1] to propagate those errors. > >>>>> > >>>>> The discussion notes that security_prepare_creds() > >>>>> is not appropriate for MAC policies, and instead the hook is > >>>>> meant for LSM authors to prepare credentials for mutation. [2] > >>>>> > >>>>> Ultimately, we concluded that a better course of action is to introduce > >>>>> a new security hook for LSM authors. [3] > >>>>> > >>>>> This patch set first introduces a new security_create_user_ns() function > >>>>> and create_user_ns LSM hook, then marks the hook as sleepable in BPF. > >>>> > >>>> Why restrict this hook to user namespaces? It seems that an LSM that > >>>> chooses to preform controls on user namespaces may want to do so for > >>>> network namespaces as well. > >>> > >>> IIRC, CLONE_NEWUSER is the only namespace flag that does not require > >>> CAP_SYS_ADMIN. There is a security use case to prevent this namespace > >>> from being created within an unprivileged environment. I'm not opposed > >>> to a more generic hook, but I don't currently have a use case to block > >>> any others. We can also say the same is true for the other namespaces: > >>> add this generic security function to these too. > >>> > >>> I'm curious what others think about this too. > >> > >> While user namespaces are obviously one of the more significant > >> namespaces from a security perspective, I do think it seems reasonable > >> that the LSMs could benefit from additional namespace creation hooks. > >> However, I don't think we need to do all of them at once, starting > >> with a userns hook seems okay to me. > >> > >> I also think that using the same LSM hook as an access control point > >> for all of the different namespaces would be a mistake. At the very > > > > Agreed. > > >> least we would need to pass a flag or some form of context to the hook > >> to indicate which new namespace(s) are being requested and I fear that > >> is a problem waiting to happen. That isn't to say someone couldn't > >> mistakenly call the security_create_user_ns(...) from the mount > >> namespace code, but I suspect that is much easier to identify as wrong > >> than the equivalent security_create_ns(USER, ...). > > > > Yeah, I think that's a pretty unlikely scenario. > > > >> > >> We also should acknowledge that while in most cases the current task's > >> credentials are probably sufficient to make any LSM access control > >> decisions around namespace creation, it's possible that for some > >> namespaces we would need to pass additional, namespace specific info > >> to the LSM. With a shared LSM hook this could become rather awkward. > > > > Agreed. > > > >> > >>>> Also, the hook seems backwards. You should > >>>> decide if the creation of the namespace is allowed before you create it. > >>>> Passing the new namespace to a function that checks to see creating a > >>>> namespace is allowed doesn't make a lot off sense. > >>> > >>> I think having more context to a security hook is a good thing. > >> > >> This is one of the reasons why I usually like to see at least one LSM > >> implementation to go along with every new/modified hook. The > >> implementation forces you to think about what information is necessary > >> to perform a basic access control decision; sometimes it isn't always > >> obvious until you have to write the access control :) > > > > I spoke to Frederick at length during LSS and as I've been given to > > understand there's a eBPF program that would immediately use this new > > hook. Now I don't want to get into the whole "Is the eBPF LSM hook > > infrastructure an LSM" but I think we can let this count as a legitimate > > first user of this hook/code. > > > >> > >> [aside: If you would like to explore the SELinux implementation let me > >> know, I'm happy to work with you on this. I suspect Casey and the > >> other LSM maintainers would also be willing to do the same for their > >> LSMs.] > >> > > I can take a shot at making a SELinux implementation, but the question > becomes: is that for v2 or a later patch? I don't think the > implementation for SELinux would be too complicated (i.e. make a call to > avc_has_perm()?) but, testing and revisions might take a bit longer. Isn't that the truth, writing code is easy(ish); testing it well is the hard part ;) Joking aside, I would suggest starting with v2. As an example, the code below might be a good place to start - we would need to discuss this on the SELinux list as there are some design decisions I'm glossing over[1]. int selinux_userns_create(struct cred *new) { u32 sid = current_sid(); return avc_has_perm(&selinux_state, sid, sid, SECCLASS_NAMESPACE, NAMESPACE__USERNS_CREATE); } You would also need to add the "namespace" class and the "userns_create" permission in security/selinux/include/classmap.h. const struct security_class_mapping secclass_map[] = { ... { "namespace", { "userns_create", NULL } }, } As I mentioned earlier, if you find yourself getting stuck, or needing some help, please feel free to send mail. [1] This code snippet uses a new object class and permission for this (namespace:userns_create). I made that choice as object classes are limited to 32 unique permissions and I expect the number of namespaces to continue to grow. -- paul-moore.com