[RFC PATCH] security: Allow dropping bounding set process-wide
sashiko-bot at kernel.org
sashiko-bot at kernel.org
Tue Sep 22 10:06:14 UTC 2026
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] security: PR_CAPBSET_DROP_MASK fails open on memory allocation failure
- [High] security: unbounded GFP_ATOMIC allocations in cap_bset_drop_process
--
commit 4012a62a02d93ede388203c8691ecc0410b4a911
Author: Jinjie Ruan <ruanjinjie at huawei.com>
security: Allow dropping bounding set process-wide
This commit adds a new prctl, PR_CAPBSET_DROP_MASK, to drop capabilities from
the bounding set of all threads in a thread group simultaneously. It achieves
this synchronously for the calling thread and queues a task_work item for each
sibling thread.
> diff --git a/security/commoncap.c b/security/commoncap.c
> index 3399535808fec..ae7ce50a81518 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
[ ... ]
> @@ -1283,6 +1290,123 @@ static int cap_prctl_drop(unsigned long cap)
> return commit_creds(new);
> }
>
> +/*
> + * Structure used to queue process-wide bounding set drops via task_work.
> + */
> +struct cap_bset_drop_work {
> + struct callback_head work;
> + struct task_struct *task;
> + kernel_cap_t mask;
> + struct cap_bset_drop_work *next;
> +};
> +
> +static void cap_bset_drop_work_fn(struct callback_head *work)
> +{
> + struct cap_bset_drop_work *w = container_of(work, struct cap_bset_drop_work, work);
> + struct cred *new = prepare_creds();
> +
> + if (!new) {
> + /* Out of memory: bounding set drop failed silently for this thread. */
> + pr_warn_ratelimited("capability bounding set drop failed for pid %d (%s)\n",
> + task_pid_nr(current), current->comm);
> + goto out;
> + }
[Severity: Critical]
Does this handle memory allocation failures safely?
If prepare_creds() fails, the capability drop is skipped and the target thread
retains its capabilities. However, the original prctl() caller has already
received a success code and may assume the entire process is successfully
sandboxed.
Should this fail closed (for example, by forcing a SIGKILL) to prevent
bypassing the intended security boundary?
> +
> + new->cap_bset = cap_drop(new->cap_bset, w->mask);
> + commit_creds(new);
> +
> +out:
> + put_task_struct(w->task);
> + kfree(w);
> +}
> +
> +/*
> + * cap_bset_drop_process - Drop capabilities from all threads in the group.
> + * @mask: Mask of capabilities to drop from the bounding set.
> + *
> + * Drops @mask from the calling thread synchronously, and queues a task_work
> + * item for each sibling thread to safely apply the drop in its own context.
> + *
> + * The caller must hold CAP_SETPCAP. Thread group must be quiescent to avoid
> + * racing with concurrent thread creation.
> + *
> + * Returns 0 on success, or -ENOMEM if allocations fail (all-or-nothing).
> + */
> +static int cap_bset_drop_process(kernel_cap_t mask)
> +{
> + struct cap_bset_drop_work *list = NULL, *w, *next;
> + struct task_struct *thread;
> + struct cred *new = NULL;
> + int ret = 0;
> +
> + rcu_read_lock();
> + for_each_thread(current, thread) {
> + const struct cred *cred;
> +
> + if (thread == current || (thread->flags & PF_EXITING))
> + continue;
> +
> + cred = __task_cred(thread);
> + if (cap_isclear(cap_intersect(cred->cap_bset, mask)))
> + continue;
> +
> + w = kmalloc_obj(*w, GFP_ATOMIC);
> + if (!w) {
> + ret = -ENOMEM;
> + break;
> + }
[Severity: High]
Can this loop exhaust the atomic memory pool?
An unprivileged user could create tens of thousands of threads and then call
prctl(PR_CAPBSET_DROP_MASK). This would execute an unbounded number of
GFP_ATOMIC allocations sequentially inside an RCU read-side critical section,
which could deplete emergency memory reserves and cause system instability.
> +
> + w->task = get_task_struct(thread);
> + w->mask = mask;
> + w->next = list;
> + list = w;
> + }
> + rcu_read_unlock();
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260922095816.1191799-1-ruanjinjie@huawei.com?part=1
More information about the Linux-security-module-archive
mailing list