Re: [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu
From: Thomas Gleixner
Date: Sun Aug 30 2026 - 02:24:19 EST
On Thu, Aug 27 2026 at 22:41, Farhad Alemi wrote:
> As part of the kernel research at ASU's SEFCOM
> lab, we hit the crash below. Crash reports can be found here:
>
> https://github.com/farhad-alemi/public_bug_reports/tree/main/164-kasan-slab-use-after-free-read-in-irq-migrate-all-off-this-cpu/
>
> BUG: KASAN: slab-use-after-free in irq_can_move_pcntxt
> kernel/irq/internals.h:305 [inline]
> BUG: KASAN: slab-use-after-free in migrate_one_irq
> kernel/irq/cpuhotplug.c:57 [inline]
> BUG: KASAN: slab-use-after-free in
> irq_migrate_all_off_this_cpu+0xdf/0xc80 kernel/irq/cpuhotplug.c:181
> Call Trace:
> irq_can_move_pcntxt kernel/irq/internals.h:305 [inline]
> migrate_one_irq kernel/irq/cpuhotplug.c:57 [inline]
> irq_migrate_all_off_this_cpu+0xdf/0xc80 kernel/irq/cpuhotplug.c:181
> fixup_irqs+0x18/0x1e0 arch/x86/kernel/irq.c:527
> cpu_disable_common+0xb27/0xd90 arch/x86/kernel/smpboot.c:1354
> native_cpu_disable+0x2f/0x40 arch/x86/kernel/smpboot.c:1366
> take_cpu_down+0xca/0x330 kernel/cpu.c:1282
> multi_cpu_stop+0x227/0x420 kernel/stop_machine.c:238
> cpu_stopper_thread+0x259/0x3e0 kernel/stop_machine.c:512
>
> BUG: KASAN: slab-out-of-bounds in
> irq_migrate_all_off_this_cpu+0xdf/0xc80 kernel/irq/cpuhotplug.c:181
Please always provide the full KASAN splat along with all other required
information: Kernel version, commit id, config file, compiler version,
architecture. There is nothing wrong with additional artifacts and
information in a github place, e.g. the full dmesg and the reproducer.
Look at the syzkaller reports how they do this, .e.g.:
https://lore.kernel.org/lkml/6a9003f9.27659fcc.2ceef7.0012.GAE@xxxxxxxxxx
Also the failure is on kernel 7.1.0-rc5. Please always verify against
latest upstream.
Though based on the meager information I think I roughly can see how
that happens not only in the reported version. It's still the same
problem upstream.
Allocation happens at:
regmap_add_irq_chip_fwnode+0x375/0x2dd0 drivers/base/regmap/regmap-irq.c:709
d = kzalloc_obj(*d);
That's initialized and then handed in as host_data when the interrupt
domain is created.
When the domain is successfully created and the subsequent
request_threaded_irq()
fails, then it ends up here:
regmap_add_irq_chip_fwnode+0xd76/0x2dd0 drivers/base/regmap/regmap-irq.c:963
Interestingly enough the code has a comment in that failure path:
err_domain:
/* Should really dispose of the domain but... */
And it should dispose the domain properly which also would remove and
free the interrupt descriptors.
I bet that regmap_add_irq_chip_fwnode() was invoked with an irq_base !=
0 argument because that causes the interrupts to be associated. That
means they are mapped and the mapping code assigns 'd->chip' as the
interrupt chip in the descriptor. chip is handed in by the caller of
regmap_add_irq_chip_fwnode() and the caller frees it on failure.
Because the interrupt descriptors are leaked this causes any function
which accesses desc->chip to access freed memory.
Mark, do you remember why you ended up with adding this comment instead
of actualy mopping up the domain?
Thanks,
tglx