From: sashiko-bot@kernel.org
To: "Vlastimil Babka (SUSE)" <vbabka@kernel.org>
Cc: linux-kernel@vger.kernel.org, bpf@vger.kernel.org,
linux-rt-devel@lists.linux.dev, media-ci@linuxtv.org,
dri-devel@lists.freedesktop.org
Subject: Re: [PATCH RFC 5/5] sched: use kfree_nolock() instead of kfree_rcu()
Date: Fri, 07 Aug 2026 15:22:28 +0000 [thread overview]
Message-ID: <20260807152229.750F11F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260807-kfree_nolock_kmalloc-v1-5-ba993cbf7a60@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] Replacing `kfree_rcu()` with `kfree_nolock()` introduces an 'Invalid wait context' lockdep warning and RT deadlock risk.
Pre-existing issues:
- [Critical] Pre-existing Use-After-Free (UAF) due to lockless access of `user_cpus_ptr` in `relax_compatible_cpus_allowed_ptr()` racing with concurrent `sched_setaffinity()`.
--
--- Patch [5]: [PATCH RFC 5/5] sched: use kfree_nolock() instead of kfree_rcu() ---
commit 59f1ba4e68974041e778f52147c67a01b2854ec6
Author: Vlastimil Babka (SUSE) <vbabka@kernel.org>
sched: use kfree_nolock() instead of kfree_rcu()
This commit replaces kfree_rcu() with kfree_nolock() in set_cpus_allowed_force()
to avoid unnecessary RCU grace period delays. It also updates
alloc_user_cpus_ptr() to no longer allocate extra space for the RCU head.
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 96226707c2f61..d2929e4e23f13 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -2807,20 +2807,15 @@ void set_cpus_allowed_force(struct task_struct *p, const struct cpumask *new_mas
> .user_mask = NULL,
> .flags = SCA_USER, /* clear the user requested mask */
> };
[ ... ]
> /*
> * Because this is called with p->pi_lock held, it is not possible
> - * to use kfree() here (when PREEMPT_RT=y), therefore punt to using
> - * kfree_rcu().
> + * to use kfree() here (when PREEMPT_RT=y), thus use kfree_nolock()
> */
> - kfree_rcu((union cpumask_rcuhead *)ac.user_mask, rcu);
> + kfree_nolock(ac.user_mask);
[Severity: High]
Does this change trigger an "Invalid wait context" lockdep warning and RT
deadlock risk?
set_cpus_allowed_force() is called with the target task's pi_lock held, which
is a raw_spinlock_t.
kfree_nolock() forwards the call to free_to_pcs():
mm/slub.c:kfree_nolock() {
...
if (likely(can_free_to_pcs(slab)) && likely(free_to_pcs(s, x, false)))
...
}
free_to_pcs() then unconditionally acquires a local_trylock_t:
mm/slub.c:free_to_pcs() {
...
if (!local_trylock(&s->cpu_sheaves->lock))
...
}
On PREEMPT_RT, local_trylock_t maps to a sleeping spinlock. Acquiring a
sleeping lock (even via a trylock) while holding a raw spinlock violates the
wait-context rules (WAIT_SLEEP under WAIT_RAW).
Could this cause a lockdep splat since CONFIG_PROVE_RAW_LOCK_NESTING checks
declared wait-types rather than runtime behavior?
[Severity: Critical]
This is a pre-existing issue, but can the lockless access of user_cpus_ptr in
relax_compatible_cpus_allowed_ptr() race with a concurrent sched_setaffinity()?
relax_compatible_cpus_allowed_ptr() performs a lockless read of
p->user_cpus_ptr and passes it as ctx->new_mask:
kernel/sched/core.c:relax_compatible_cpus_allowed_ptr() {
...
.new_mask = task_user_cpus(p),
...
}
__sched_setaffinity() then allocates temporary masks with GFP_KERNEL:
kernel/sched/syscalls.c:__sched_setaffinity() {
...
if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL))
...
}
Since GFP_KERNEL can sleep or be preempted, a concurrent thread calling the
sched_setaffinity() syscall on the same task can update user_cpus_ptr and free
the old mask.
When __sched_setaffinity() resumes, it dereferences the potentially freed
memory:
kernel/sched/syscalls.c:__sched_setaffinity() {
...
cpumask_and(new_mask, ctx->new_mask, cpus_allowed);
...
}
Can this use-after-free lead to memory corruption or a kernel crash if
triggered by unprivileged userspace executing a compat binary?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260807-kfree_nolock_kmalloc-v1-0-ba993cbf7a60@kernel.org?part=5
prev parent reply other threads:[~2026-08-07 15:22 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 13:50 [PATCH RFC 0/5] allow kfree_nolock() handle kmalloc() objects Vlastimil Babka (SUSE)
2026-08-07 13:50 ` [PATCH RFC 1/5] mm/slab: cleanup deferred free handling Vlastimil Babka (SUSE)
2026-08-07 13:50 ` [PATCH RFC 2/5] mm/slab, kfence: support kfence objects in kfree_nolock() Vlastimil Babka (SUSE)
2026-08-07 14:16 ` sashiko-bot
2026-08-07 13:50 ` [PATCH RFC 3/5] mm/slab, kmemleak: handle kmemleak freeing " Vlastimil Babka (SUSE)
2026-08-07 13:50 ` [PATCH RFC 4/5] mm/slab: handle large_kmalloc objects " Vlastimil Babka (SUSE)
2026-08-07 15:06 ` sashiko-bot
2026-08-07 13:50 ` [PATCH RFC 5/5] sched: use kfree_nolock() instead of kfree_rcu() Vlastimil Babka (SUSE)
2026-08-07 15:22 ` sashiko-bot [this message]
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=20260807152229.750F11F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=media-ci@linuxtv.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vbabka@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