Linux Security Modules development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
Cc: linux-security-module@vger.kernel.org
Subject: Re: [PATCH 2/8] userns: introduce capability bounding set for user namespaces
Date: Thu, 29 Oct 2026 22:18:25 +0000	[thread overview]
Message-ID: <sashiko-outbox-190063@kernel.org> (raw)
In-Reply-To: <20261028221705.3915340-3-halg@google.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] userns: cap_ptrace_access_check() denies owner access without CAP_SYS_PTRACE
--

commit 16037e714ad5686658566ccf9fa3273e7c4c0615
Author: Hallgrimur H. Gunnarsson <halg@google.com>

userns: introduce capability bounding set for user namespaces

This commit introduces a per-user-namespace capability bounding set
(cap_bset) and a global sysctl ceiling knob
(kernel.unprivileged_userns_caps_allowed) to restrict the capabilities
granted when unprivileged tasks create user namespaces. It also bounds
the implicit capabilities granted to a parent-namespace owner over an
owned child user namespace by the child namespace's cap_bset.

> diff --git a/security/commoncap.c b/security/commoncap.c
> index 3399535808fec..f153e7bad1baf 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -88,11 +88,13 @@ static inline int cap_capable_helper(const struct cred *cred,
>  		if (ns->level <= cred_ns->level)
>  			return -EPERM;
>  
> -		/* 
> +		/*
>  		 * The owner of the user namespace in the parent of the
> -		 * user namespace has all caps.
> +		 * user namespace has all caps, subject to the bounding
> +		 * set of the owned user namespace.
>  		 */
> -		if ((ns->parent == cred_ns) && uid_eq(ns->owner, cred->euid))
> +		if (ns->parent == cred_ns && uid_eq(ns->owner, cred->euid) &&
> +		    userns_has_cap(ns, cap))
>  			return 0;

[Severity: Medium]
When CAP_SYS_PTRACE is excluded from a child user namespace's cap_bset
(either via the unprivileged_userns_caps_allowed sysctl or via
CLONE_NEWUSER_BSET in "userns: allow restricting capability bounding set
via clone3()"), does this break ptrace_may_access() and PTRACE_TRACEME for
the parent-namespace owner inspecting its own child processes in that
namespace?

In __ptrace_may_access(), a caller with the same UID/GID as a dumpable
target passes the UID/GID and dumpability checks without needing
CAP_SYS_PTRACE, and then calls security_ptrace_access_check() ->
cap_ptrace_access_check():

security/commoncap.c:cap_ptrace_access_check() {
	...
	if (cred->user_ns == child_cred->user_ns &&
	    cap_issubset(child_cred->cap_permitted, *caller_caps))
		goto out;
	if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
		goto out;
	ret = -EPERM;
}

And similarly in cap_ptrace_traceme():

security/commoncap.c:cap_ptrace_traceme() {
	...
	if (cred->user_ns == child_cred->user_ns &&
	    cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
		goto out;
	if (has_ns_capability(parent, child_cred->user_ns, CAP_SYS_PTRACE))
		goto out;
	ret = -EPERM;
}

Although the kernel-doc comments on both functions state that access is
allowed if the caller is in the same or an ancestor user_ns and holds all
of the target task's capabilities (matching cred_cap_issubset() in
kernel/cred.c), both functions only check cap_issubset() when
cred->user_ns == child_cred->user_ns. For an ancestor user_ns, they rely
entirely on ns_capable(child_cred->user_ns, CAP_SYS_PTRACE) or
has_ns_capability(parent, child_cred->user_ns, CAP_SYS_PTRACE).

Because cap_capable_helper() now requires userns_has_cap(ns, cap) for the
owner in the parent namespace, ns_capable(child_cred->user_ns,
CAP_SYS_PTRACE) returns false whenever CAP_SYS_PTRACE is not in
child_ns->cap_bset. As a result, an unprivileged parent task that spawns a
sandboxed child in a new user namespace without CAP_SYS_PTRACE is denied
access to its own child even when the child has no capabilities beyond the
owned namespace (or cap_permitted == CAP_EMPTY_SET).

This causes parent-side operations gated on ptrace_may_access() to fail
with -EPERM, -EACCES, or -ENOENT, including opening /proc/<child>/ns/*,
setns(pidfd, ...) via validate_nsset() (even when CAP_SYS_ADMIN is set in
child_ns->cap_bset), pidfd_getfd(), reading /proc/<child>/maps or
/proc/<child>/fd/*, ptrace attach / PTRACE_TRACEME, and accessing
/proc/<child>/uid_map when procfs is mounted with hidepid.

Should cap_ptrace_access_check() and cap_ptrace_traceme() permit access
when the caller is the owner of an ancestor user namespace (similar to
cred_cap_issubset(), where all capabilities in the child namespace are a
subset of the owner's privileges over that namespace), rather than
requiring CAP_SYS_PTRACE to be present in the child namespace's cap_bset?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261028221705.3915340-1-halg@google.com?part=2

  reply	other threads:[~2026-10-29 22:18 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28 22:16 [PATCH 0/8] userns: per-namespace capability bounding set and opt-in netns loopback Hallgrimur H. Gunnarsson
2026-10-28 22:16 ` [PATCH 1/8] net: introduce CLONE_NEWNET_LOOPBACK to auto-enable loopback Hallgrimur H. Gunnarsson
2026-10-29 22:18   ` sashiko-bot
2026-10-28 22:16 ` [PATCH 2/8] userns: introduce capability bounding set for user namespaces Hallgrimur H. Gunnarsson
2026-10-29 22:18   ` sashiko-bot [this message]
2026-10-28 22:17 ` [PATCH 3/8] userns: allow restricting capability bounding set via clone3() Hallgrimur H. Gunnarsson
2026-10-29 22:18   ` sashiko-bot
2026-10-28 22:17 ` [PATCH 4/8] nsfs: add NS_USER_GET_INFO ioctl to inspect user namespace capabilities Hallgrimur H. Gunnarsson
2026-10-29 22:18   ` sashiko-bot
2026-10-28 22:17 ` [PATCH 5/8] selftests/net: add test suite for CLONE_NEWNET_LOOPBACK Hallgrimur H. Gunnarsson
2026-10-29 22:18   ` sashiko-bot
2026-10-28 22:17 ` [PATCH 6/8] selftests/capabilities: tests for user namespace capability bounding set Hallgrimur H. Gunnarsson
2026-10-29 22:18   ` sashiko-bot
2026-10-28 22:17 ` [PATCH 7/8] selftests/capabilities: add clone3() tests for CLONE_NEWUSER_BSET Hallgrimur H. Gunnarsson
2026-10-29 22:18   ` sashiko-bot
2026-10-28 22:17 ` [PATCH 8/8] selftests/nsfs: add tests for NS_USER_GET_INFO ioctl Hallgrimur H. Gunnarsson
2026-10-29 22:18   ` sashiko-bot
2026-10-28 22:56 ` [PATCH 0/8] userns: per-namespace capability bounding set and opt-in netns loopback Andy Lutomirski
2026-10-29 10:44   ` Alexey Gladkov
2026-10-29 12:11   ` Hallgrimur H. Gunnarsson

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=sashiko-outbox-190063@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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