From: Josef Bacik <josef@toxicpanda.com>
To: Serge Hallyn <serge@hallyn.com>, Paul Moore <paul@paul-moore.com>,
Christian Brauner <brauner@kernel.org>
Cc: 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,
Josef Bacik <josef@toxicpanda.com>
Subject: [PATCH v2 4/5] capabilities: limit fscaps to where CAP_SETFCAP reaches
Date: Wed, 14 Oct 2026 20:47:49 +0000 [thread overview]
Message-ID: <20261014-b4-setfcap-userns-v2-4-fac4d19281d7@toxicpanda.com> (raw)
In-Reply-To: <20261014-b4-setfcap-userns-v2-0-fac4d19281d7@toxicpanda.com>
Commit db2e718a4798 ("capabilities: require CAP_SETFCAP to map uid 0")
keeps a root process without CAP_SETFCAP from creating a user namespace
that maps uid 0, in which it could attach capabilities to a file that
are then honoured outside. But the map doesn't have to be written by
that process. A privileged task can write it from the parent, and the
file capabilities are not checked against the outside at all:
task A: uid 0, full caps task B: uid 0, no CAP_SETFCAP
unshare(CLONE_NEWUSER)
ns->setfcap_level = 1
write "0 0 1" to B's uid_map, gid_map
A has CAP_SETFCAP -> allowed
setxattr(file, "security.capability")
rootid = kuid 0
uid 1000 in the initial namespace:
execve(file)
file capabilities apply
The map doesn't even have to show uid 0 of the parent as uid 0, since a
v3 xattr can name any mapped uid as the root user.
Check at the place where it matters, in cap_convert_nscap(). On an
idmapped mount the root user named in the xattr has two identities: the
kuid seen through this mount, and the kuid that is stored and seen
through every other mount of the filesystem. If either of them is the
root user of an ancestor of the caller's namespace too, CAP_SETFCAP has
to reach up to there, which ns->setfcap_level tells.
Tasks in the initial namespace, tasks in namespaces created by a task
with CAP_SETFCAP, and file capabilities for a root user that only exists
in namespaces within reach are not affected. That includes everything
an unprivileged user does in its own namespaces. The rest gets -EPERM.
Fixes: 8db6c34f1dbc ("Introduce v3 namespaced file capabilities")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
security/commoncap.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/security/commoncap.c b/security/commoncap.c
index f52f1c7a87be..2cae4354aeae 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -644,10 +644,24 @@ int cap_convert_nscap(const struct mnt_idmap *idmap, struct dentry *dentry,
if (!vfsuid_valid(vfsrootid))
return -EINVAL;
+ /*
+ * The root user may be the root user of ancestors of our namespace as
+ * well. CAP_SETFCAP that we got for entering it doesn't cover those.
+ * On an idmapped mount the root user is vfsrootid as seen through
+ * this mount and rootid as seen through every other mount of the
+ * filesystem, so both have to stay within reach.
+ */
+ if (cap_root_level(vfsuid_into_kuid(vfsrootid), task_ns) <
+ task_ns->setfcap_level)
+ return -EPERM;
+
rootid = from_vfsuid(idmap, fs_ns, vfsrootid);
if (!uid_valid(rootid))
return -EINVAL;
+ if (cap_root_level(rootid, task_ns) < task_ns->setfcap_level)
+ return -EPERM;
+
nsrootid = from_kuid(fs_ns, rootid);
if (nsrootid == -1)
return -EINVAL;
--
2.55.0
next prev parent reply other threads:[~2026-10-14 20:48 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 20:47 [PATCH v2 0/5] capabilities: close the ways around the CAP_SETFCAP rule for uid 0 Josef Bacik
2026-10-14 20:47 ` [PATCH v2 1/5] userns: record how far up CAP_SETFCAP reaches Josef Bacik
2026-10-14 20:55 ` Bradley Morgan
2026-10-17 4:24 ` Serge E. Hallyn
2026-10-14 20:47 ` [PATCH v2 2/5] userns: don't let setns() lend CAP_SETFCAP Josef Bacik
2026-10-14 20:54 ` Bradley Morgan
2026-10-17 4:05 ` Serge E. Hallyn
2026-10-14 20:47 ` [PATCH v2 3/5] userns: check the opener and the writer before mapping uid 0 Josef Bacik
2026-10-14 20:57 ` Bradley Morgan
2026-10-14 20:47 ` Josef Bacik [this message]
2026-10-14 20:47 ` [PATCH v2 5/5] capabilities: don't let ptrace borrow CAP_SETFCAP Josef Bacik
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=20261014-b4-setfcap-userns-v2-4-fac4d19281d7@toxicpanda.com \
--to=josef@toxicpanda.com \
--cc=brauner@kernel.org \
--cc=dhowells@redhat.com \
--cc=jarkko@kernel.org \
--cc=jmorris@namei.org \
--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 \
/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®