From nobody Sun Apr 19 00:24:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 103B5CCA485 for ; Thu, 7 Jul 2022 22:32:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237066AbiGGWcw (ORCPT ); Thu, 7 Jul 2022 18:32:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236764AbiGGWck (ORCPT ); Thu, 7 Jul 2022 18:32:40 -0400 Received: from mail-oi1-x229.google.com (mail-oi1-x229.google.com [IPv6:2607:f8b0:4864:20::229]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D6CB665D76 for ; Thu, 7 Jul 2022 15:32:38 -0700 (PDT) Received: by mail-oi1-x229.google.com with SMTP id t189so25036231oie.8 for ; Thu, 07 Jul 2022 15:32:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloudflare.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2ze62Gr6yFI9YlZaCLh0XPJZ5QPI4eIkzUPPZ4mag1A=; b=Hjz2P6X2I1Fth6pZf+hGpgOQm1DMiy9L3g2o/gJ5yJGZFPSgpQkF362RzMHiiUskYa ngBdGQovMO2B3pfO+EpXtaDC79YUJJvDLqDr+oJrNm3GwsaNflwgOG6TSCmAD/tuwdsE o8CjTO+CykD3nVVlWp1MldRIv8CUqJ0r/ok6w= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2ze62Gr6yFI9YlZaCLh0XPJZ5QPI4eIkzUPPZ4mag1A=; b=ff4Qx9NUJRNxaCl2PTtfXLGp+umpK+atkgcjmbkxEVZU+HQgsmnhaZfARPYHCtHk3q /oYQiSw2f0M62IRsbloPxNrSwykTn454ncRgekB6fhceAYdM0aH4E878e+Cry/b0SEMg VRYjztiNnZErQh8I7Go6L/OcuqSL2WGCFhlELo/yyeIaAdj1KFa+fGUwrAKQFu70lkDr yHXxmN5+HlVlB9yaiZ2vaAFw7dSroFnZ3+xHWvV2+pZ5NXSMzFZCYBZrTuF0Jz0eTAqS vz5UxmyvJoHeD24wfPwRdkp9tWM1JeTTmzj7l0LzduWWQxDWxN8D7384RsJn6Y2yQQC1 Txeg== X-Gm-Message-State: AJIora+LcTLPPq7gRBVoIjKHeYq9VES2ArsMoxPJ6zCVIcWf3RRRzQXv kd3OQNNN4TkENgD8NRAEUK4dWw== X-Google-Smtp-Source: AGRyM1spTnHtSiohzejr09iqgEQq6SB21VULSXN2tn7SabY+Ll4UuXdWDcBCQ14/WEJipjBZIcHNCQ== X-Received: by 2002:a54:4393:0:b0:335:cdb9:16a9 with SMTP id u19-20020a544393000000b00335cdb916a9mr157809oiv.112.1657233158219; Thu, 07 Jul 2022 15:32:38 -0700 (PDT) Received: from localhost.localdomain ([184.4.90.121]) by smtp.gmail.com with ESMTPSA id i16-20020a05683033f000b00616b835f5e7sm16246222otu.43.2022.07.07.15.32.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Jul 2022 15:32:37 -0700 (PDT) From: Frederick Lawler To: 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, paul@paul-moore.com, stephen.smalley.work@gmail.com, eparis@parisplace.org, shuah@kernel.org, brauner@kernel.org, casey@schaufler-ca.com, ebiederm@xmission.com, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kernel-team@cloudflare.com, Frederick Lawler Subject: [PATCH v2 1/4] security, lsm: Introduce security_create_user_ns() Date: Thu, 7 Jul 2022 17:32:25 -0500 Message-Id: <20220707223228.1940249-2-fred@cloudflare.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220707223228.1940249-1-fred@cloudflare.com> References: <20220707223228.1940249-1-fred@cloudflare.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Preventing user namespace (privileged or otherwise) creation comes in a few of forms in order of granularity: 1. /proc/sys/user/max_user_namespaces sysctl 2. OS specific patch(es) 3. CONFIG_USER_NS To block a task based on its attributes, the LSM hook cred_prepare is a good candidate for use because it provides more granular control, and it is called before create_user_ns(): cred =3D prepare_creds() security_prepare_creds() call_int_hook(cred_prepare, ... if (cred) create_user_ns(cred) Since security_prepare_creds() is meant for LSMs to copy and prepare credentials, access control is an unintended use of the hook. Therefore introduce a new function security_create_user_ns() with an accompanying create_user_ns LSM hook. This hook takes the prepared creds for LSM authors to write policy against. On success, the new namespace is applied to credentials, otherwise an error is returned. Signed-off-by: Frederick Lawler --- Changes since v1: - Changed commit wording - Moved execution to be after id mapping check - Changed signature to only accept a const struct cred * --- include/linux/lsm_hook_defs.h | 1 + include/linux/lsm_hooks.h | 4 ++++ include/linux/security.h | 6 ++++++ kernel/user_namespace.c | 5 +++++ security/security.c | 5 +++++ 5 files changed, 21 insertions(+) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index eafa1d2489fd..3eabd6b10776 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -223,6 +223,7 @@ LSM_HOOK(int, -ENOSYS, task_prctl, int option, unsigned= long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) LSM_HOOK(void, LSM_RET_VOID, task_to_inode, struct task_struct *p, struct inode *inode) +LSM_HOOK(int, 0, create_user_ns, const struct cred *cred) LSM_HOOK(int, 0, ipc_permission, struct kern_ipc_perm *ipcp, short flag) LSM_HOOK(void, LSM_RET_VOID, ipc_getsecid, struct kern_ipc_perm *ipcp, u32 *secid) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 91c8146649f5..07f833da0bbf 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -799,6 +799,10 @@ * security attributes, e.g. for /proc/pid inodes. * @p contains the task_struct for the task. * @inode contains the inode structure for the inode. + * @create_user_ns: + * Check permission prior to creating a new user namespace. + * @cred points to prepared creds. + * Return 0 if successful, otherwise < 0 error code. * * Security hooks for Netlink messaging. * diff --git a/include/linux/security.h b/include/linux/security.h index 7fc4e9f49f54..a195bf33246a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -435,6 +435,7 @@ int security_task_kill(struct task_struct *p, struct ke= rnel_siginfo *info, int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); void security_task_to_inode(struct task_struct *p, struct inode *inode); +int security_create_user_ns(const struct cred *cred); int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid); int security_msg_msg_alloc(struct msg_msg *msg); @@ -1185,6 +1186,11 @@ static inline int security_task_prctl(int option, un= signed long arg2, static inline void security_task_to_inode(struct task_struct *p, struct in= ode *inode) { } =20 +static inline int security_create_user_ns(const struct cred *cred) +{ + return 0; +} + static inline int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) { diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 5481ba44a8d6..3f464bbda0e9 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -113,6 +114,10 @@ int create_user_ns(struct cred *new) !kgid_has_mapping(parent_ns, group)) goto fail_dec; =20 + ret =3D security_create_user_ns(new); + if (ret < 0) + goto fail_dec; + ret =3D -ENOMEM; ns =3D kmem_cache_zalloc(user_ns_cachep, GFP_KERNEL); if (!ns) diff --git a/security/security.c b/security/security.c index 188b8f782220..c700dbdc14fe 100644 --- a/security/security.c +++ b/security/security.c @@ -1903,6 +1903,11 @@ void security_task_to_inode(struct task_struct *p, s= truct inode *inode) call_void_hook(task_to_inode, p, inode); } =20 +int security_create_user_ns(const struct cred *cred) +{ + return call_int_hook(create_user_ns, 0, cred); +} + int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) { return call_int_hook(ipc_permission, 0, ipcp, flag); --=20 2.30.2 From nobody Sun Apr 19 00:24:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6136CCA480 for ; Thu, 7 Jul 2022 22:32:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237031AbiGGWc4 (ORCPT ); Thu, 7 Jul 2022 18:32:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237026AbiGGWcv (ORCPT ); Thu, 7 Jul 2022 18:32:51 -0400 Received: from mail-oi1-x236.google.com (mail-oi1-x236.google.com [IPv6:2607:f8b0:4864:20::236]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22E026758C for ; Thu, 7 Jul 2022 15:32:41 -0700 (PDT) Received: by mail-oi1-x236.google.com with SMTP id s204so3581777oif.5 for ; Thu, 07 Jul 2022 15:32:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloudflare.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HPI3ojZnM++1c4f61ZRwt4MaisU1ny63+tYPCLxBNyU=; b=pPJLzKN/n3H53u85lbMzUgP5UsS4fil38YQ7/dfmeg3M8/AKwxVBk+o8JUNfyzo0BU Ma1+B6VEHpA2z1r2kpEhbf43UigQAbI7DljAQ2RMp1GasHdit7vE00Ayz/lHyMPIYe7S pfSyPARlPQPu+9DCiuXMHuQvu7ASo5GBxM43g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HPI3ojZnM++1c4f61ZRwt4MaisU1ny63+tYPCLxBNyU=; b=w21s77losl3R9wlXL3xDg680f1NAgWaLwl467P1QekcFssec4nZ1ZOW+2tnYUyV2vk 9n+t1/RQ8fvzMc46KakDTmMkhawx2HMuHS79J9f6l6IO1op9p/9a2lb97LaM5PQSgJTb y9W0YLnbhL82TYaGtfsLvN3Zhm1M/rzHVXgZjp/YOlMjBxejJOGCwoibKjxJboc2y97T IzZVOFTlPF+QszYtQ7cu4iwF/DPAS9LhEMKXAUMr19FxJIGhcIXSvMy8+TEQgAwjloXh 70XwIxYNxaUDPa+UOzLYszBbgmbIatSmBKO4GpYRo9zajEfNKMjOHGhEeWfzrcym/SfL OrGw== X-Gm-Message-State: AJIora/wQmWY0fcpgwBS2RaCTE5jpm+dFwGLig6oZ87KpDEPOpJxdyz4 vnyzSYnwVxgVrV0kbR2csLlXLg== X-Google-Smtp-Source: AGRyM1tcIEZsE2gFDfWZ+ydTaErjmU0vLWY1y/NAd+s5mkdDoWOmXG6TCxhhNFR7u0n6nfjScfGdRg== X-Received: by 2002:a05:6808:11c4:b0:2d9:c395:f15e with SMTP id p4-20020a05680811c400b002d9c395f15emr3824812oiv.47.1657233160506; Thu, 07 Jul 2022 15:32:40 -0700 (PDT) Received: from localhost.localdomain ([184.4.90.121]) by smtp.gmail.com with ESMTPSA id i16-20020a05683033f000b00616b835f5e7sm16246222otu.43.2022.07.07.15.32.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Jul 2022 15:32:39 -0700 (PDT) From: Frederick Lawler To: 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, paul@paul-moore.com, stephen.smalley.work@gmail.com, eparis@parisplace.org, shuah@kernel.org, brauner@kernel.org, casey@schaufler-ca.com, ebiederm@xmission.com, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kernel-team@cloudflare.com, Frederick Lawler Subject: [PATCH v2 2/4] bpf-lsm: Make bpf_lsm_create_user_ns() sleepable Date: Thu, 7 Jul 2022 17:32:26 -0500 Message-Id: <20220707223228.1940249-3-fred@cloudflare.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220707223228.1940249-1-fred@cloudflare.com> References: <20220707223228.1940249-1-fred@cloudflare.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Users may want to audit calls to security_create_user_ns() and access user space memory. Also create_user_ns() runs without pagefault_disabled(). Therefore, make bpf_lsm_create_user_ns() sleepable for mandatory access control policies. Signed-off-by: Frederick Lawler --- Changes since v1: - None --- kernel/bpf/bpf_lsm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index c1351df9f7ee..75853965e7b0 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -250,6 +250,7 @@ BTF_ID(func, bpf_lsm_task_getsecid_obj) BTF_ID(func, bpf_lsm_task_prctl) BTF_ID(func, bpf_lsm_task_setscheduler) BTF_ID(func, bpf_lsm_task_to_inode) +BTF_ID(func, bpf_lsm_create_user_ns) BTF_SET_END(sleepable_lsm_hooks) =20 bool bpf_lsm_is_sleepable_hook(u32 btf_id) --=20 2.30.2 From nobody Sun Apr 19 00:24:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08724CCA480 for ; Thu, 7 Jul 2022 22:33:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237100AbiGGWdL (ORCPT ); Thu, 7 Jul 2022 18:33:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237033AbiGGWcv (ORCPT ); Thu, 7 Jul 2022 18:32:51 -0400 Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2F7D67597 for ; Thu, 7 Jul 2022 15:32:42 -0700 (PDT) Received: by mail-oi1-x230.google.com with SMTP id w83so25083629oiw.1 for ; Thu, 07 Jul 2022 15:32:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloudflare.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=j5md+eRaroN3b4x5GXk8vDK0Yn23IzIrTWAe3e+Lx7Q=; b=aNBBpDIdjJ8tvtO8GaBiWmkh9oQhGcb6KAdgM/0e35zl+mr2r/xgzUWjFkfNmJOaEm Jvhr+t6gmYTNnCQMTKv+oMfi4pLA4Ogl9NJlch8V8tQGl16wtwfJpFXSaYcVKfYfcrMM jMLEPkI/8F3wR7TAumcOZqojwn71aRJyKEYgU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=j5md+eRaroN3b4x5GXk8vDK0Yn23IzIrTWAe3e+Lx7Q=; b=DkFYSgSGLHtNTgu/Btm6+Mzvr+mt0kEwMN/jkQdx7O1/oIpOlJkuGBOODuKuyHqLMt oxcUJmrJrAwbVNfd5F8adeiuakRd6TNLBYhypMk6/MFrM824MP0Bs0sgBXtuWqmsW54I IpbpNUpF2h3srDwWo9Ha+m1VOYxexJ4ZqNPweTTuE9gaNcyZWFhVdee1+FC8tPvRjF6c tj+nvMLRbuNcxW3DNN+uyiQ9bLi1oZ+V7NP8QGlE7qLcL71pVUFXCf3r4TU5o68q3qv/ yPYuiKdKsjFBJKINJzj78/Ek0eOKeW6yZ1Jin0G10Q/y+omMWkhcUfJ1ACj4stGVdLzZ 5cUQ== X-Gm-Message-State: AJIora8QqHtzH0EyMEu4Y3b3duszY43D18umI/BMpq14C3DsWON42XM2 5SHhxvU+W75BT//kIfh/8cu8rA== X-Google-Smtp-Source: AGRyM1srNOFm7S5tg87SqlO14myBHyfKEwvfh+AVIicT3RMtZrigLBMXO3g8hWk7379whlu6136QGw== X-Received: by 2002:a05:6808:20a7:b0:337:a9f9:24fb with SMTP id s39-20020a05680820a700b00337a9f924fbmr157852oiw.220.1657233162560; Thu, 07 Jul 2022 15:32:42 -0700 (PDT) Received: from localhost.localdomain ([184.4.90.121]) by smtp.gmail.com with ESMTPSA id i16-20020a05683033f000b00616b835f5e7sm16246222otu.43.2022.07.07.15.32.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Jul 2022 15:32:41 -0700 (PDT) From: Frederick Lawler To: 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, paul@paul-moore.com, stephen.smalley.work@gmail.com, eparis@parisplace.org, shuah@kernel.org, brauner@kernel.org, casey@schaufler-ca.com, ebiederm@xmission.com, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kernel-team@cloudflare.com, Frederick Lawler Subject: [PATCH v2 3/4] selftests/bpf: Add tests verifying bpf lsm create_user_ns hook Date: Thu, 7 Jul 2022 17:32:27 -0500 Message-Id: <20220707223228.1940249-4-fred@cloudflare.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220707223228.1940249-1-fred@cloudflare.com> References: <20220707223228.1940249-1-fred@cloudflare.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The LSM hook create_user_ns was introduced to provide LSM's an opportunity to block or allow unprivileged user namespace creation. This test serves two purposes: it provides a test eBPF implementation, and tests the hook successfully blocks or allows user namespace creation. This tests 4 cases: 1. Unattached bpf program does not block unpriv user namespace creation. 2. Attached bpf program allows user namespace creation given CAP_SYS_ADMIN privileges. 3. Attached bpf program denies user namespace creation for a user without CAP_SYS_ADMIN. 4. The sleepable implementation loads Signed-off-by: Frederick Lawler --- The generic deny_namespace file name is used for future namespace expansion. I didn't want to limit these files to just the create_user_ns hook. Changes since v1: - Introduce this patch --- .../selftests/bpf/prog_tests/deny_namespace.c | 88 +++++++++++++++++++ .../selftests/bpf/progs/test_deny_namespace.c | 39 ++++++++ 2 files changed, 127 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/deny_namespace.c create mode 100644 tools/testing/selftests/bpf/progs/test_deny_namespace.c diff --git a/tools/testing/selftests/bpf/prog_tests/deny_namespace.c b/tool= s/testing/selftests/bpf/prog_tests/deny_namespace.c new file mode 100644 index 000000000000..a1fb07038dd5 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/deny_namespace.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE +#include +#include "test_deny_namespace.skel.h" +#include +#include "cap_helpers.h" + +#define STACK_SIZE (1024 * 1024) +static char child_stack[STACK_SIZE]; + +int clone_callback(void *arg) +{ + return 0; +} + +static int create_new_user_ns(void) +{ + int status; + pid_t cpid; + + cpid =3D clone(clone_callback, child_stack + STACK_SIZE, + CLONE_NEWUSER | SIGCHLD, NULL); + + if (cpid =3D=3D -1) + return errno; + + if (cpid =3D=3D 0) + return 0; + + waitpid(cpid, &status, 0); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + + return -1; +} + +static void test_create_user_ns_bpf(void) +{ + __u32 cap_mask =3D 1ULL << CAP_SYS_ADMIN; + __u64 old_caps =3D 0; + + ASSERT_OK(create_new_user_ns(), "priv new user ns"); + + cap_disable_effective(cap_mask, &old_caps); + + ASSERT_EQ(create_new_user_ns(), EPERM, "unpriv new user ns"); + + if (cap_mask & old_caps) + cap_enable_effective(cap_mask, NULL); +} + +static void test_unpriv_create_user_ns_no_bpf(void) +{ + __u32 cap_mask =3D 1ULL << CAP_SYS_ADMIN; + __u64 old_caps =3D 0; + + cap_disable_effective(cap_mask, &old_caps); + + ASSERT_OK(create_new_user_ns(), "no-bpf unpriv new user ns"); + + if (cap_mask & old_caps) + cap_enable_effective(cap_mask, NULL); +} + +void test_deny_namespace(void) +{ + struct test_deny_namespace *skel =3D NULL; + int err; + + if (test__start_subtest("unpriv_create_user_ns_no_bpf")) + test_unpriv_create_user_ns_no_bpf(); + + skel =3D test_deny_namespace__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel load")) + goto close_prog; + + err =3D test_deny_namespace__attach(skel); + if (!ASSERT_OK(err, "attach")) + goto close_prog; + + if (test__start_subtest("create_user_ns_bpf")) + test_create_user_ns_bpf(); + + test_deny_namespace__detach(skel); + +close_prog: + test_deny_namespace__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/test_deny_namespace.c b/tool= s/testing/selftests/bpf/progs/test_deny_namespace.c new file mode 100644 index 000000000000..eedede891431 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_deny_namespace.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +struct kernel_cap_struct { + __u32 cap[_LINUX_CAPABILITY_U32S_3]; +} __attribute__((preserve_access_index)); + +struct cred { + struct kernel_cap_struct cap_effective; +} __attribute__((preserve_access_index)); + +char _license[] SEC("license") =3D "GPL"; + +SEC("lsm/create_user_ns") +int BPF_PROG(test_create_user_ns, const struct cred *cred, int ret) +{ + struct kernel_cap_struct caps =3D cred->cap_effective; + int cap_index =3D CAP_TO_INDEX(CAP_SYS_ADMIN); + __u32 cap_mask =3D CAP_TO_MASK(CAP_SYS_ADMIN); + + if (ret) + return 0; + + ret =3D -EPERM; + if (caps.cap[cap_index] & cap_mask) + return 0; + + return -EPERM; +} + +SEC("lsm.s/create_user_ns") +int BPF_PROG(test_sleepable_create_user_ns, const struct cred *cred, int r= et) +{ + return 0; +} --=20 2.30.2 From nobody Sun Apr 19 00:24:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B067AC43334 for ; Thu, 7 Jul 2022 22:33:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237077AbiGGWdU (ORCPT ); Thu, 7 Jul 2022 18:33:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237023AbiGGWcw (ORCPT ); Thu, 7 Jul 2022 18:32:52 -0400 Received: from mail-ot1-x331.google.com (mail-ot1-x331.google.com [IPv6:2607:f8b0:4864:20::331]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED0C2675B6 for ; Thu, 7 Jul 2022 15:32:45 -0700 (PDT) Received: by mail-ot1-x331.google.com with SMTP id q18-20020a9d7c92000000b00616b27cda7cso14993457otn.9 for ; Thu, 07 Jul 2022 15:32:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloudflare.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gpnGP72y7AlRDZxLLIIKCxGjGB4QqIYx1EtuBERrAGY=; b=KfAsVex69jTCIdg5XmbRjXWWWy/S0Tca6CS8SwDAmazdBPIoDnrCREhbjrLFevHaGt 6ufFk77dMvGWeRIVQPkT2IDgHAiRo2457GzNSRpAj0LvK9u6HolMJoALdrhWiSJY3cDP lupYF3+zn3pi6FeorsgnBUBjJN6/6EstmhD80= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gpnGP72y7AlRDZxLLIIKCxGjGB4QqIYx1EtuBERrAGY=; b=lVQe8khsnVeieqTROpknLFOIs1qHp1wGcR6Bav3gryySPszeB37gGE3IchcSbG1w5K kJhzFQVNlJBr7yrMjTX8X0qRKxcyXbJNWMFg8tTxlxuk2IPTlafPrl7UKWN3sJ/ine1U Uhvf56AhsBqc9KV8sFXaK0zxTx7ub4l9imJxgNhbaMoGdB5aynccwNbnv3bSGyHrB4lZ oRMo0vZPA7fdYkhY4bywP+kXzbfaHGA7z1YzIyQe/+0ssXUi7ZmwCzGyAkNTycwuM+5U oottcUz3QA/t25Tyy4RO90ugTl1fNO8AyJfOCulAAD1ET13RjvOOPVDjtQ29/WfJYj+e 86yA== X-Gm-Message-State: AJIora/E4E/vz0TmDckfiH02ZFbahxf7l8+XS3oMfr7awKWX/DSJBrsM Y4cf1bEKvpgz2tg9MT/amkrKog== X-Google-Smtp-Source: AGRyM1sGIyzyI1rIE0sIpG00vgHQmsRFAehgN6hwD9szVgsHUkRW2ie4sEb+YtA6SNwdPP9ZDtc8qw== X-Received: by 2002:a9d:4c0e:0:b0:616:dd87:cb91 with SMTP id l14-20020a9d4c0e000000b00616dd87cb91mr182367otf.185.1657233164958; Thu, 07 Jul 2022 15:32:44 -0700 (PDT) Received: from localhost.localdomain ([184.4.90.121]) by smtp.gmail.com with ESMTPSA id i16-20020a05683033f000b00616b835f5e7sm16246222otu.43.2022.07.07.15.32.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Jul 2022 15:32:43 -0700 (PDT) From: Frederick Lawler To: 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, paul@paul-moore.com, stephen.smalley.work@gmail.com, eparis@parisplace.org, shuah@kernel.org, brauner@kernel.org, casey@schaufler-ca.com, ebiederm@xmission.com, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, kernel-team@cloudflare.com, Frederick Lawler Subject: [PATCH v2 4/4] selinux: Implement create_user_ns hook Date: Thu, 7 Jul 2022 17:32:28 -0500 Message-Id: <20220707223228.1940249-5-fred@cloudflare.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220707223228.1940249-1-fred@cloudflare.com> References: <20220707223228.1940249-1-fred@cloudflare.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Unprivileged user namespace creation is an intended feature to enable sandboxing, however this feature is often used to as an initial step to perform a privilege escalation attack. This patch implements a new namespace { userns_create } access control permission to restrict which domains allow or deny user namespace creation. This is necessary for system administrators to quickly protect their systems while waiting for vulnerability patches to be applied. This permission can be used in the following way: allow domA_t domB_t : namespace { userns_create }; Signed-off-by: Frederick Lawler --- Changes since v1: - Introduce this patch --- security/selinux/hooks.c | 9 +++++++++ security/selinux/include/classmap.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index beceb89f68d9..73fbcb434fe0 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4227,6 +4227,14 @@ static void selinux_task_to_inode(struct task_struct= *p, spin_unlock(&isec->lock); } =20 +static int selinux_userns_create(const struct cred *cred) +{ + u32 sid =3D current_sid(); + + return avc_has_perm(&selinux_state, sid, sid, SECCLASS_NAMESPACE, + NAMESPACE__USERNS_CREATE, NULL); +} + /* Returns error only if unable to parse addresses */ static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct common_audit_data *ad, u8 *proto) @@ -7117,6 +7125,7 @@ static struct security_hook_list selinux_hooks[] __ls= m_ro_after_init =3D { LSM_HOOK_INIT(task_movememory, selinux_task_movememory), LSM_HOOK_INIT(task_kill, selinux_task_kill), LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode), + LSM_HOOK_INIT(create_user_ns, selinux_userns_create), =20 LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission), LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), diff --git a/security/selinux/include/classmap.h b/security/selinux/include= /classmap.h index ff757ae5f253..9943e85c6b3e 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -254,6 +254,8 @@ const struct security_class_mapping secclass_map[] =3D { { COMMON_FILE_PERMS, NULL } }, { "io_uring", { "override_creds", "sqpoll", NULL } }, + { "namespace", + { "userns_create", NULL } }, { NULL } }; =20 --=20 2.30.2