Re: [PATCH 17/23] sched/isolation: Extend housekeeping_dereference_check() to cover changes in nohz_full or manged_irqs cpumasks
Waiman Long <[email protected]>
| Newsgroups | dev.linux.lists.sashiko,org.kernel.vger.linux-hwmon |
|---|---|
| Message-ID | <[email protected]> |
On 4/21/26 11:09 PM, [email protected] wrote: > Sashiko AI review found 2 potential issue(s): > - [Critical] Unprotected access to newly dynamic HK_TYPE_KERNEL_NOISE causes lockdep splats and Use-After-Free. > - [Critical] Flawed lockdep exemptions mask genuine Use-After-Free vulnerabilities. > -- > > commit 7b12dcd17d401c6b135ee53ba4e8384a7bd3d867 > Author: Waiman Long <[email protected]> > > sched/isolation: Extend housekeeping_dereference_check() to cover changes in nohz_full or manged_irqs cpumasks > > This commit extends housekeeping_dereference_check() to apply the same > lockdep exemptions used by HK_TYPE_DOMAIN to HK_TYPE_KERNEL_NOISE and > HK_TYPE_MANAGED_IRQ, preparing them to be runtime changeable. > >> diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c >> --- a/kernel/sched/isolation.c >> +++ b/kernel/sched/isolation.c >> @@ -38,7 +38,8 @@ EXPORT_SYMBOL_GPL(housekeeping_enabled); >> >> static bool housekeeping_dereference_check(enum hk_type type) >> { >> - if (IS_ENABLED(CONFIG_LOCKDEP) && type == HK_TYPE_DOMAIN) { >> + if (IS_ENABLED(CONFIG_LOCKDEP) && >> + (BIT(type) & (HK_FLAG_DOMAIN | HK_FLAG_KERNEL_NOISE | HK_FLAG_MANAGED_IRQ))) { > Because HK_TYPE_KERNEL_NOISE is becoming runtime changeable, does this > expose existing readers to concurrent updates and use-after-free? > > For example, housekeeping_show() reads this mask without holding > rcu_read_lock(). Similarly, tmigr_isolated_exclude_cpumask() reads it > holding only cpus_read_lock(), not the write lock. The housekeeping_show() function is a known issue and will be fixed in the next version. tmigr_isolated_exclude_cpumask() will only be called from housekeeping_update() where the top_cpuset mutex will be held. So it is the same process that modifies the housekeeping cpumasks and call tmigr_isolated_exclude_cpumask() before freeing the old cpumasks. There is no use-after-free problem here. > > If housekeeping_update() allocates a new mask, calls synchronize_rcu(), > and frees the old mask while these functions are accessing the pointer, > could this result in a use-after-free? > > Additionally, does extending this lockdep exemption mask genuine > use-after-free vulnerabilities? > > The exemptions below assume that holding cpuset_mutex or cpus_write_lock() > protects the pointer: > >> /* Cpuset isn't even writable yet? */ >> if (system_state <= SYSTEM_SCHEDULING) >> return true; >> >> /* CPU hotplug write locked, so cpuset partition can't be overwritten */ >> if (IS_ENABLED(CONFIG_HOTPLUG_CPU) && lockdep_is_cpus_write_held()) >> return true; >> >> /* Cpuset lock held, partitions not writable */ >> if (IS_ENABLED(CONFIG_CPUSETS) && lockdep_is_cpuset_held()) >> return true; > However, housekeeping_update() explicitly drops cpuset_mutex and > cpus_read_lock() before updating masks and calling synchronize_rcu(). > > This means housekeeping_update() can run in parallel with readers > holding cpuset_mutex or CPU hotplug callbacks holding cpus_write_lock(). housekeeping_update() must be run with the top_cpuset mutex held. So it is not possible for 2 different processes to run housekeeping_update() concurrently. I will add a lockdep assertion to clarify that. Cheers, Longman