From: "Mickaël Salaün" <mic@digikod.net>
Cc: "Mickaël Salaün" <mic@digikod.net>,
"Josef Bacik" <josef@toxicpanda.com>,
"Serge Hallyn" <serge@hallyn.com>,
"Paul Moore" <paul@paul-moore.com>,
"Christian Brauner" <brauner@kernel.org>,
"James Morris" <jmorris@namei.org>,
"David Howells" <dhowells@redhat.com>,
"Jarkko Sakkinen" <jarkko@kernel.org>,
"Andrew G. Morgan" <morgan@kernel.org>,
"Serge Hallyn" <sergeh@kernel.org>,
linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org, keyrings@vger.kernel.org,
linux-fsdevel@vger.kernel.org,
"Bradley Morgan" <brads@mainlining.org>,
stable@vger.kernel.org
Subject: [PATCH] userns: Let LSMs deny the CAP_SETFCAP snapshot for mapping uid 0
Date: Tue, 10 Nov 2026 15:42:04 +0100 [thread overview]
Message-ID: <20261110144205.2404088-1-mic@digikod.net> (raw)
Commit db2e718a4798 ("capabilities: require CAP_SETFCAP to map uid 0")
records in parent_could_setfcap whether the creator of a user namespace
had CAP_SETFCAP, because a creator writing its own uid_map only has
capabilities in the new namespace. The snapshot uses cap_raised(), so a
task whose LSM policy denies CAP_SETFCAP can still map uid 0 in a
namespace it creates.
Use security_capable() against the parent namespace instead: the
creator's credentials still belong to it at this point, so commoncap
returns the same result, and only LSM denials are added.
Do not audit this check: creating a user namespace does not use
CAP_SETFCAP, and most namespaces never map uid 0. The uid_map write
that later fails has no LSM audit record.
Checking CAP_SETFCAP when the map is written would not work: the
writer's credentials then belong to the new namespace, where commoncap
grants the creator all capabilities.
Cc: Christian Brauner <brauner@kernel.org>
Cc: Josef Bacik <josef@toxicpanda.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: stable@vger.kernel.org
Fixes: db2e718a4798 ("capabilities: require CAP_SETFCAP to map uid 0")
Signed-off-by: Mickaël Salaün <mic@digikod.net>
---
This is independent from Josef Bacik's series, which reworks this code
to close other ways around the CAP_SETFCAP rule:
https://patch.msgid.link/20261027-b4-setfcap-userns-v8-0-2674adc63f3c@toxicpanda.com
That series still computes the creator's CAP_SETFCAP with cap_capable()
and cap_raised() in cap_setfcap_level(), so it would need the same
change.
---
include/linux/user_namespace.h | 5 +++--
kernel/user_namespace.c | 8 +++++++-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 91232053775d..370961fde45f 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -86,8 +86,9 @@ struct user_namespace {
kgid_t group;
struct ns_common ns;
unsigned long flags;
- /* parent_could_setfcap: true if the creator if this ns had CAP_SETFCAP
- * in its effective capability set at the child ns creation time. */
+ /* parent_could_setfcap: true if the creator of this ns could use
+ * CAP_SETFCAP in the parent ns at the child ns creation time.
+ */
bool parent_could_setfcap;
#ifdef CONFIG_KEYS
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index cd748e1cbace..57b7f10be74e 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -128,7 +128,13 @@ int create_user_ns(struct cred *new)
if (!ns)
goto fail_dec;
- ns->parent_could_setfcap = cap_raised(new->cap_effective, CAP_SETFCAP);
+ /*
+ * verify_root_map() relies on this once the creator only has
+ * capabilities in the new namespace. Let LSMs deny it, but do not
+ * audit: the creator may never map uid 0.
+ */
+ ns->parent_could_setfcap =
+ !security_capable(new, parent_ns, CAP_SETFCAP, CAP_OPT_NOAUDIT);
ret = ns_common_init(ns);
if (ret)
--
2.56.0
next reply other threads:[~2026-11-10 14:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 14:42 Mickaël Salaün [this message]
2026-11-10 14:51 ` Paul Moore
2026-11-10 15:08 ` Serge E. Hallyn
2026-11-10 15:51 ` Bradley Morgan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261110144205.2404088-1-mic@digikod.net \
--to=mic@digikod.net \
--cc=brads@mainlining.org \
--cc=brauner@kernel.org \
--cc=dhowells@redhat.com \
--cc=jarkko@kernel.org \
--cc=jmorris@namei.org \
--cc=josef@toxicpanda.com \
--cc=keyrings@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=morgan@kernel.org \
--cc=paul@paul-moore.com \
--cc=serge@hallyn.com \
--cc=sergeh@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®