mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu
@ 2026-08-28  5:41 Farhad Alemi
  2026-08-29 20:34 ` Radu Rendec
  2026-08-30  6:24 ` Thomas Gleixner
  0 siblings, 2 replies; 7+ messages in thread
From: Farhad Alemi @ 2026-08-28  5:41 UTC (permalink / raw)
  To: Thomas Gleixner, Mark Brown; +Cc: falemi, Radu Rendec, linux-kernel

Hello,

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

Our reproducer.c is available upon request.

Happy to test a patch if that would help.

Regards,

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu
  2026-08-28  5:41 [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu Farhad Alemi
@ 2026-08-29 20:34 ` Radu Rendec
  2026-08-30 18:30   ` Thomas Gleixner
  2026-08-30  6:24 ` Thomas Gleixner
  1 sibling, 1 reply; 7+ messages in thread
From: Radu Rendec @ 2026-08-29 20:34 UTC (permalink / raw)
  To: Farhad Alemi, Thomas Gleixner, Mark Brown; +Cc: falemi, linux-kernel

Hello Farhad,

On Thu, 2026-08-27 at 22:41 -0700, 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

Thanks for reporting this. For everyone interested, please note that it
had been also reported by syzbot a few days before:
https://lore.kernel.org/all/6a8c23a0.dbb3a75c.7844.0001.GAE@google.com/
Currently there is no follow up to the syzbot report.

> Our reproducer.c is available upon request.

If you could please send me the reproducer, I'd be happy to take a
look.

> Happy to test a patch if that would help.

Thanks. If I figure it out and send a patch, I'll be sure to copy you.

-- 
Regards,
Radu

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu
  2026-08-28  5:41 [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu Farhad Alemi
  2026-08-29 20:34 ` Radu Rendec
@ 2026-08-30  6:24 ` Thomas Gleixner
  2026-08-30 14:16   ` Mark Brown
  1 sibling, 1 reply; 7+ messages in thread
From: Thomas Gleixner @ 2026-08-30  6:24 UTC (permalink / raw)
  To: Farhad Alemi, Mark Brown; +Cc: falemi, Radu Rendec, linux-kernel

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@google.com

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu
  2026-08-30  6:24 ` Thomas Gleixner
@ 2026-08-30 14:16   ` Mark Brown
  0 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2026-08-30 14:16 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: Farhad Alemi, falemi, Radu Rendec, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1863 bytes --]

On Sun, Aug 30, 2026 at 08:24:04AM +0200, Thomas Gleixner wrote:

> 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.

Huh, due to the lack of information in the report that you noted I'd
thought this was misdirected due to -next or something...

> 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.

...

> Mark, do you remember why you ended up with adding this comment instead
> of actualy mopping up the domain?

I believe that at the time there was no way of freeing irqdomains, or I
couldn't find it.  irq_domain_remove() was added in May 2012 as a bit of
an afterthought in 58ee99ada293b (irqdomain: Support removal of IRQ
domains.), the above comment was added in the same month so won't have
been in the kernel I was working on.  This was one of the first users
that wasn't arch code I think, having an interrupt controller that wasnt
arch code had a bunch of fun at that point in time.  I do remember being
confused about why there wasn't a remove function and I imagine I meant
to go back and figure something out there but clearly never got round to
it, practically speaking the regmap-irq code was being used by things
like PMICs that would never actually get removed so this path was never
getting exercised.

I'll add the cleanup.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu
  2026-08-29 20:34 ` Radu Rendec
@ 2026-08-30 18:30   ` Thomas Gleixner
  2026-08-30 18:48     ` Radu Rendec
  0 siblings, 1 reply; 7+ messages in thread
From: Thomas Gleixner @ 2026-08-30 18:30 UTC (permalink / raw)
  To: Radu Rendec, Farhad Alemi, Mark Brown; +Cc: falemi, linux-kernel

On Sat, Aug 29 2026 at 16:34, Radu Rendec wrote:
> On Thu, 2026-08-27 at 22:41 -0700, Farhad Alemi wrote:
>>   BUG: KASAN: slab-out-of-bounds in
>> irq_migrate_all_off_this_cpu+0xdf/0xc80 kernel/irq/cpuhotplug.c:181
>
> Thanks for reporting this. For everyone interested, please note that it
> had been also reported by syzbot a few days before:
> https://lore.kernel.org/all/6a8c23a0.dbb3a75c.7844.0001.GAE@google.com/
> Currently there is no follow up to the syzbot report.

The syzbot report is useless. It mumbles about memory allocated in the
networking stack which definitely can't end up in the interrupt
descriptor :)

>> Our reproducer.c is available upon request.

See further down the thread :)


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu
  2026-08-30 18:30   ` Thomas Gleixner
@ 2026-08-30 18:48     ` Radu Rendec
  2026-09-09 17:56       ` Farhad Alemi
  0 siblings, 1 reply; 7+ messages in thread
From: Radu Rendec @ 2026-08-30 18:48 UTC (permalink / raw)
  To: Thomas Gleixner, Farhad Alemi, Mark Brown; +Cc: falemi, linux-kernel

On Sun, 2026-08-30 at 20:30 +0200, Thomas Gleixner wrote:
> On Sat, Aug 29 2026 at 16:34, Radu Rendec wrote:
> > On Thu, 2026-08-27 at 22:41 -0700, Farhad Alemi wrote:
> > >   BUG: KASAN: slab-out-of-bounds in
> > > irq_migrate_all_off_this_cpu+0xdf/0xc80 kernel/irq/cpuhotplug.c:181
> > 
> > Thanks for reporting this. For everyone interested, please note that it
> > had been also reported by syzbot a few days before:
> > https://lore.kernel.org/all/6a8c23a0.dbb3a75c.7844.0001.GAE@google.com/
> > Currently there is no follow up to the syzbot report.
> 
> The syzbot report is useless. It mumbles about memory allocated in the
> networking stack which definitely can't end up in the interrupt
> descriptor :)

I know, and that's why I asked for the reproducer :)

The stack trace of the UAF is valid though (and pretty much identical
to the one in Farhad's report). I was just trying to point out that
it's very likely the same bug.

> > > Our reproducer.c is available upon request.
> 
> See further down the thread :)

Yes, I saw your and Mark's replies, and you're clearly many steps ahead :)
In hindsight, I admit I was lazy and didn't bother to look further - partly
because I thought it would be easier to investigate once I had the reproducer.

If I could go back in time and start doing this kind of work 20 years
ago (or even 10), I would. It certainly helps figure things out much
faster when you've been doing this for a long time and also know how
the code evolved over the years.

-- 
Best regards,
Radu

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu
  2026-08-30 18:48     ` Radu Rendec
@ 2026-09-09 17:56       ` Farhad Alemi
  0 siblings, 0 replies; 7+ messages in thread
From: Farhad Alemi @ 2026-09-09 17:56 UTC (permalink / raw)
  To: Radu Rendec; +Cc: Thomas Gleixner, Mark Brown, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1770 bytes --]

Hi Radu,

Please find attached the reproducer and the log; thanks!

On Sun, Aug 30, 2026 at 11:48 AM Radu Rendec <radu@rendec.net> wrote:
>
> On Sun, 2026-08-30 at 20:30 +0200, Thomas Gleixner wrote:
> > On Sat, Aug 29 2026 at 16:34, Radu Rendec wrote:
> > > On Thu, 2026-08-27 at 22:41 -0700, Farhad Alemi wrote:
> > > >   BUG: KASAN: slab-out-of-bounds in
> > > > irq_migrate_all_off_this_cpu+0xdf/0xc80 kernel/irq/cpuhotplug.c:181
> > >
> > > Thanks for reporting this. For everyone interested, please note that it
> > > had been also reported by syzbot a few days before:
> > > https://lore.kernel.org/all/6a8c23a0.dbb3a75c.7844.0001.GAE@google.com/
> > > Currently there is no follow up to the syzbot report.
> >
> > The syzbot report is useless. It mumbles about memory allocated in the
> > networking stack which definitely can't end up in the interrupt
> > descriptor :)
>
> I know, and that's why I asked for the reproducer :)
>
> The stack trace of the UAF is valid though (and pretty much identical
> to the one in Farhad's report). I was just trying to point out that
> it's very likely the same bug.
>
> > > > Our reproducer.c is available upon request.
> >
> > See further down the thread :)
>
> Yes, I saw your and Mark's replies, and you're clearly many steps ahead :)
> In hindsight, I admit I was lazy and didn't bother to look further - partly
> because I thought it would be easier to investigate once I had the reproducer.
>
> If I could go back in time and start doing this kind of work 20 years
> ago (or even 10), I would. It certainly helps figure things out much
> faster when you've been doing this for a long time and also know how
> the code evolved over the years.
>
> --
> Best regards,
> Radu

[-- Attachment #2: 164_console.log --]
[-- Type: application/octet-stream, Size: 12631 bytes --]

Linux version 7.3.0-rc2-00006-g28924df2a08f (x@y) (Ubuntu clang version 21.1.8 (6ubuntu1), Ubuntu LLD 21.1.8) #1 SMP PREEMPT_DYNAMIC Mon Sep  7 16:56:53 MST 2026

[   44.021699][    T9] usb 3-1: new high-speed USB device number 2 using dummy_hcd
[   44.173291][    T9] usb 3-1: New USB device found, idVendor=0403, idProduct=c631, bcdDevice= 1.00
[   44.179109][    T9] usb 3-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[   44.200627][    T9] i2c-tiny-usb 3-1:1.0: version 1.00 found at bus 003 address 002
[   44.208211][    T9] i2c i2c-2: connected i2c-tiny-usb device
[   44.255216][ T9485] retu-mfd 2-0001: Retu v0.0 found
[   44.263308][ T9485] genirq: Flags mismatch irq 0. 00002000 (RETU) vs. 00215a00 (timer)
[   44.264283][ T9485] retu-mfd 2-0001: Failed to request IRQ 0 for RETU: -16
[   44.265987][ T9485] retu-mfd 2-0001: probe with driver retu-mfd failed with error -16
[   44.267048][ T9485] i2c i2c-2: new_device: Instantiated device retu at 0x01
[   44.271471][ T9485] retu-mfd 2-0002: Tahvo v0.0 found
[   44.275820][ T9485] genirq: Flags mismatch irq 0. 00002000 (TAHVO) vs. 00215a00 (timer)
[   44.278060][ T9485] retu-mfd 2-0002: Failed to request IRQ 0 for TAHVO: -16
[   44.282408][ T9485] retu-mfd 2-0002: probe with driver retu-mfd failed with error -16
[   44.284261][ T9485] i2c i2c-2: new_device: Instantiated device tahvo at 0x02
[   44.307505][   T23] numa_remove_cpu cpu 1 node 0: mask now 0
[   44.307515][   T23] numa_remove_cpu cpu 1 node 1: mask now 0
[   44.307972][   T23] ==================================================================
[   44.307978][   T23] BUG: KASAN: slab-use-after-free in irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.307998][   T23] Read of size 8 at addr ffff888021c431a8 by task migration/1/23
[   44.308004][   T23] 
[   44.308014][   T23] CPU: 1 UID: 0 PID: 23 Comm: migration/1 Not tainted 7.3.0-rc2-00006-g28924df2a08f #1 PREEMPT(full) 
[   44.308022][   T23] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
[   44.308027][   T23] Stopper: multi_cpu_stop+0x0/0x4a0 <- stop_cpus+0x130/0x1d0
[   44.308048][   T23] Call Trace:
[   44.308053][   T23]  <TASK>
[   44.308057][   T23]  dump_stack_lvl+0xe8/0x150
[   44.308066][   T23]  print_address_description+0x55/0x1e0
[   44.308074][   T23]  ? irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.308081][   T23]  print_report+0x58/0x70
[   44.308087][   T23]  kasan_report+0x117/0x150
[   44.308098][   T23]  ? irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.308105][   T23]  irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.308114][   T23]  fixup_irqs+0x18/0x1e0
[   44.308122][   T23]  cpu_disable_common+0xb27/0xd90
[   44.308131][   T23]  native_cpu_disable+0x2f/0x40
[   44.308138][   T23]  take_cpu_down+0xca/0x330
[   44.308147][   T23]  ? __pfx_take_cpu_down+0x10/0x10
[   44.308155][   T23]  multi_cpu_stop+0x231/0x4a0
[   44.308165][   T23]  ? __pfx_multi_cpu_stop+0x10/0x10
[   44.308175][   T23]  cpu_stopper_thread+0x25e/0x3f0
[   44.308185][   T23]  smpboot_thread_fn+0x562/0xa60
[   44.308194][   T23]  ? smpboot_thread_fn+0x4d/0xa60
[   44.308202][   T23]  kthread+0x38b/0x480
[   44.308210][   T23]  ? __pfx_smpboot_thread_fn+0x10/0x10
[   44.308217][   T23]  ? __pfx_kthread+0x10/0x10
[   44.308225][   T23]  ret_from_fork+0x514/0xb70
[   44.308233][   T23]  ? __pfx_ret_from_fork+0x10/0x10
[   44.308248][   T23]  ? __switch_to+0xc79/0x1410
[   44.308256][   T23]  ? __pfx_kthread+0x10/0x10
[   44.308263][   T23]  ret_from_fork_asm+0x1a/0x30
[   44.308273][   T23]  </TASK>
[   44.308276][   T23] 
[   44.308279][   T23] Allocated by task 9485:
[   44.308283][   T23]  kasan_save_track+0x3e/0x80
[   44.308291][   T23]  __kasan_kmalloc+0x93/0xb0
[   44.308298][   T23]  __kmalloc_cache_noprof+0x325/0x610
[   44.308306][   T23]  regmap_add_irq_chip_fwnode+0x380/0x2e90
[   44.308320][   T23]  regmap_add_irq_chip+0x6b/0x80
[   44.308329][   T23]  retu_probe+0x3ba/0x680
[   44.308334][   T23]  i2c_device_probe+0x894/0xc00
[   44.308346][   T23]  really_probe+0x267/0xaf0
[   44.308353][   T23]  __driver_probe_device+0x1e2/0x350
[   44.308359][   T23]  driver_probe_device+0x4f/0x240
[   44.308365][   T23]  __device_attach_driver+0x270/0x410
[   44.308372][   T23]  bus_for_each_drv+0x258/0x2f0
[   44.308380][   T23]  __device_attach+0x2c5/0x450
[   44.308386][   T23]  device_initial_probe+0xa1/0xd0
[   44.308391][   T23]  bus_probe_device+0x12a/0x220
[   44.308399][   T23]  device_add+0x7ec/0xb90
[   44.308408][   T23]  i2c_new_client_device+0xa1f/0x1160
[   44.308417][   T23]  new_device_store+0x24b/0x520
[   44.308424][   T23]  kernfs_fop_write_iter+0x3af/0x540
[   44.308434][   T23]  vfs_write+0x61d/0xb90
[   44.308441][   T23]  ksys_write+0x150/0x270
[   44.308447][   T23]  do_syscall_64+0x155/0x510
[   44.308456][   T23]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   44.308463][   T23] 
[   44.308464][   T23] Freed by task 9485:
[   44.308467][   T23]  kasan_save_track+0x3e/0x80
[   44.308474][   T23]  kasan_save_free_info+0x46/0x50
[   44.308481][   T23]  __kasan_slab_free+0x5c/0x80
[   44.308488][   T23]  kfree+0x1c5/0x650
[   44.308494][   T23]  regmap_add_irq_chip_fwnode+0xd96/0x2e90
[   44.308503][   T23]  regmap_add_irq_chip+0x6b/0x80
[   44.308512][   T23]  retu_probe+0x3ba/0x680
[   44.308517][   T23]  i2c_device_probe+0x894/0xc00
[   44.308525][   T23]  really_probe+0x267/0xaf0
[   44.308531][   T23]  __driver_probe_device+0x1e2/0x350
[   44.308537][   T23]  driver_probe_device+0x4f/0x240
[   44.308544][   T23]  __device_attach_driver+0x270/0x410
[   44.308550][   T23]  bus_for_each_drv+0x258/0x2f0
[   44.308557][   T23]  __device_attach+0x2c5/0x450
[   44.308563][   T23]  device_initial_probe+0xa1/0xd0
[   44.308569][   T23]  bus_probe_device+0x12a/0x220
[   44.308576][   T23]  device_add+0x7ec/0xb90
[   44.308585][   T23]  i2c_new_client_device+0xa1f/0x1160
[   44.308593][   T23]  new_device_store+0x24b/0x520
[   44.308600][   T23]  kernfs_fop_write_iter+0x3af/0x540
[   44.308609][   T23]  vfs_write+0x61d/0xb90
[   44.308615][   T23]  ksys_write+0x150/0x270
[   44.308621][   T23]  do_syscall_64+0x155/0x510
[   44.308629][   T23]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   44.308635][   T23] 
[   44.308636][   T23] The buggy address belongs to the object at ffff888021c43000
[   44.308636][   T23]  which belongs to the cache kmalloc-1k of size 1024
[   44.308645][   T23] The buggy address is located 424 bytes inside of
[   44.308645][   T23]  freed 1024-byte region [ffff888021c43000, ffff888021c43400)
[   44.308652][   T23] 
[   44.308654][   T23] The buggy address belongs to the physical page:
[   44.308659][   T23] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x21c40
[   44.308666][   T23] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[   44.308672][   T23] flags: 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff)
[   44.308682][   T23] page_type: f5(slab)
[   44.308692][   T23] raw: 00fff00000000040 ffff88801b041dc0 dead000000000100 dead000000000122
[   44.308698][   T23] raw: 0000000000000000 0000000000100010 00000000f5000000 0000000000000000
[   44.308704][   T23] head: 00fff00000000040 ffff88801b041dc0 dead000000000100 dead000000000122
[   44.308710][   T23] head: 0000000000000000 0000000000100010 00000000f5000000 0000000000000000
[   44.308715][   T23] head: 00fff00000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
[   44.308721][   T23] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
[   44.308724][   T23] page dumped because: kasan: bad access detected
[   44.308730][   T23] page_owner tracks the page as allocated
[   44.308733][   T23] page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd60c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_RETRY_MAYFAIL|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 1, tgid 1 (systemd), ts 8849800896
[   44.308744][   T23]  post_alloc_hook+0x1f9/0x250
[   44.308751][   T23]  get_page_from_freelist+0x235a/0x23e0
[   44.308759][   T23]  __alloc_frozen_pages_noprof+0x217/0x5a0
[   44.308767][   T23]  allocate_slab+0x7d/0x610
[   44.308773][   T23]  refill_objects+0x2d6/0x350
[   44.308778][   T23]  __pcs_replace_empty_main+0x2c9/0x6c0
[   44.308787][   T23]  __kvmalloc_node_noprof+0x64e/0x830
[   44.308795][   T23]  file_tty_write+0x2aa/0x9f0
[   44.308803][   T23]  do_iter_readv_writev+0x619/0x8c0
[   44.308811][   T23]  vfs_writev+0x33c/0x990
[   44.308819][   T23]  do_writev+0x154/0x2e0
[   44.308826][   T23]  do_syscall_64+0x155/0x510
[   44.308835][   T23]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   44.308841][   T23] page last free pid 1 tgid 1 ts 8368557793 stack trace:
[   44.308845][   T23]  __free_frozen_pages+0xc9f/0xd90
[   44.308852][   T23]  __slab_free+0x274/0x2c0
[   44.308859][   T23]  qlist_free_all+0x99/0x100
[   44.308866][   T23]  kasan_quarantine_reduce+0x148/0x160
[   44.308874][   T23]  __kasan_slab_alloc+0x22/0x80
[   44.308882][   T23]  __kmalloc_noprof+0x30b/0x720
[   44.308888][   T23]  tomoyo_realpath_from_path+0xe3/0x5d0
[   44.308899][   T23]  tomoyo_path_number_perm+0x246/0x630
[   44.308906][   T23]  security_file_ioctl+0xc3/0x2a0
[   44.308914][   T23]  __se_sys_ioctl+0x47/0x170
[   44.308921][   T23]  do_syscall_64+0x155/0x510
[   44.308929][   T23]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   44.308935][   T23] 
[   44.308937][   T23] Memory state around the buggy address:
[   44.308941][   T23]  ffff888021c43080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   44.308945][   T23]  ffff888021c43100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   44.308950][   T23] >ffff888021c43180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   44.308953][   T23]                                   ^
[   44.308956][   T23]  ffff888021c43200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   44.308961][   T23]  ffff888021c43280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   44.308964][   T23] ==================================================================
[   44.308973][   T23] Kernel panic - not syncing: KASAN: panic_on_warn set ...
[   44.382675][   T23] CPU: 1 UID: 0 PID: 23 Comm: migration/1 Not tainted 7.3.0-rc2-00006-g28924df2a08f #1 PREEMPT(full) 
[   44.383651][   T23] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
[   44.384605][   T23] Stopper: multi_cpu_stop+0x0/0x4a0 <- stop_cpus+0x130/0x1d0
[   44.385282][   T23] Call Trace:
[   44.385589][   T23]  <TASK>
[   44.385954][   T23]  vpanic+0x56d/0xa60
[   44.386351][   T23]  ? __pfx_vpanic+0x10/0x10
[   44.386792][   T23]  panic+0xc5/0xd0
[   44.387164][   T23]  ? __pfx_panic+0x10/0x10
[   44.387581][   T23]  ? __pfx__printk+0x10/0x10
[   44.388006][   T23]  ? irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.388554][   T23]  ? irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.389102][   T23]  check_panic_on_warn+0x89/0xb0
[   44.389565][   T23]  ? irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.390111][   T23]  end_report+0x73/0x170
[   44.390537][   T23]  ? irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.391113][   T23]  kasan_report+0x128/0x150
[   44.391566][   T23]  ? irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.392111][   T23]  irq_migrate_all_off_this_cpu+0xdf/0xc50
[   44.392645][   T23]  fixup_irqs+0x18/0x1e0
[   44.393039][   T23]  cpu_disable_common+0xb27/0xd90
[   44.393508][   T23]  native_cpu_disable+0x2f/0x40
[   44.393955][   T23]  take_cpu_down+0xca/0x330
[   44.394383][   T23]  ? __pfx_take_cpu_down+0x10/0x10
[   44.394852][   T23]  multi_cpu_stop+0x231/0x4a0
[   44.395293][   T23]  ? __pfx_multi_cpu_stop+0x10/0x10
[   44.395789][   T23]  cpu_stopper_thread+0x25e/0x3f0
[   44.396327][   T23]  smpboot_thread_fn+0x562/0xa60
[   44.396804][   T23]  ? smpboot_thread_fn+0x4d/0xa60
[   44.397290][   T23]  kthread+0x38b/0x480
[   44.397666][   T23]  ? __pfx_smpboot_thread_fn+0x10/0x10
[   44.398164][   T23]  ? __pfx_kthread+0x10/0x10
[   44.398595][   T23]  ret_from_fork+0x514/0xb70
[   44.399021][   T23]  ? __pfx_ret_from_fork+0x10/0x10
[   44.399490][   T23]  ? __switch_to+0xc79/0x1410
[   44.399923][   T23]  ? __pfx_kthread+0x10/0x10
[   44.400349][   T23]  ret_from_fork_asm+0x1a/0x30
[   44.400789][   T23]  </TASK>
[   45.465785][   T23] Shutting down cpus with NMI
[   45.466540][   T23] Kernel Offset: disabled
[   45.467086][   T23] Rebooting in 86400 seconds..

[-- Attachment #3: reproducer.c --]
[-- Type: application/octet-stream, Size: 5903 bytes --]

/*
 * Reproducer for 164-kasan-slab-use-after-free-read-in-irq-migrate-all-off-this-cpu
 */
#define _GNU_SOURCE
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/usb/ch9.h>
#include <linux/usb/raw_gadget.h>

#define EP0_MAX 4096

/* i2c-tiny-usb command ids */
#define CMD_ECHO	0
#define CMD_GET_FUNC	1
#define CMD_SET_DELAY	2
#define CMD_GET_STATUS	3
#define CMD_I2C_IO	4

static int raw_gadget_fd = -1;

static const uint8_t device_descriptor[18] = {
	18, USB_DT_DEVICE,
	0x00, 0x02,		/* bcdUSB 2.00 */
	0x00, 0x00, 0x00,	/* class/subclass/protocol */
	64,			/* bMaxPacketSize0 */
	0x03, 0x04,		/* idVendor  0x0403 */
	0x31, 0xc6,		/* idProduct 0xc631 (i2c-tiny-usb, FTDI ids) */
	0x00, 0x01,		/* bcdDevice */
	0, 0, 0,		/* iManufacturer/iProduct/iSerial */
	1,			/* bNumConfigurations */
};

static const uint8_t config_descriptor[18] = {
	9, USB_DT_CONFIG,
	18, 0,			/* wTotalLength */
	1, 1, 0,		/* bNumInterfaces, bConfigurationValue, iConfiguration */
	0xa0, 0x32,		/* bmAttributes, bMaxPower */

	9, USB_DT_INTERFACE,
	0, 0,			/* bInterfaceNumber, bAlternateSetting */
	0,			/* bNumEndpoints -- i2c-tiny-usb uses ep0 only */
	0xff, 0x00, 0x00,	/* vendor specific */
	0,			/* iInterface */
};

static void write_sysfs(const char *path, const char *value)
{
	int fd = open(path, O_WRONLY);

	if (fd < 0) {
		printf("open %s: %s\n", path, strerror(errno));
		return;
	}
	if (write(fd, value, strlen(value)) < 0)
		printf("write %s <- %s: %s\n", path, value, strerror(errno));
	close(fd);
}

/* An IN transfer with a data stage is completed with EP0_WRITE; everything
 * else (including a zero-length IN) leaves ep0_out_pending set and must be
 * acknowledged with EP0_READ. */
static void ep0_transfer(const void *data, uint32_t len)
{
	uint8_t buf[sizeof(struct usb_raw_ep_io) + EP0_MAX];
	struct usb_raw_ep_io *io = (void *)buf;

	io->ep = 0;
	io->flags = 0;
	io->length = len > EP0_MAX ? EP0_MAX : len;
	if (data)
		memcpy(io->data, data, io->length);
	ioctl(raw_gadget_fd, data ? USB_RAW_IOCTL_EP0_WRITE : USB_RAW_IOCTL_EP0_READ, io);
}

static void handle_control_request(const struct usb_ctrlrequest *ctrl)
{
	uint8_t reply[EP0_MAX];
	int len = -1;

	memset(reply, 0, sizeof(reply));

	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
		if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR &&
		    (ctrl->wValue >> 8) == USB_DT_DEVICE) {
			len = sizeof(device_descriptor);
			memcpy(reply, device_descriptor, len);
		} else if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR &&
			   (ctrl->wValue >> 8) == USB_DT_CONFIG) {
			len = sizeof(config_descriptor);
			memcpy(reply, config_descriptor, len);
		} else if (ctrl->bRequest == USB_REQ_SET_CONFIGURATION) {
			ioctl(raw_gadget_fd, USB_RAW_IOCTL_CONFIGURE, 0);
			len = 0;
		}
	} else if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) {
		switch (ctrl->bRequest) {
		case CMD_GET_FUNC:
			memset(reply, 0xff, 4);	/* claim every I2C_FUNC_* bit */
			len = 4;
			break;
		case CMD_GET_STATUS:
			reply[0] = 1;		/* STATUS_ADDRESS_ACK */
			len = 1;
			break;
		case CMD_SET_DELAY:
			len = ctrl->wLength;
			break;
		default:
			/* CMD_I2C_IO with any BEGIN/END combination */
			if ((ctrl->bRequest & ~3) == CMD_I2C_IO)
				len = ctrl->wLength;
			break;
		}
	}

	if (len < 0) {
		ioctl(raw_gadget_fd, USB_RAW_IOCTL_EP0_STALL, 0);
		return;
	}
	if ((ctrl->bRequestType & USB_DIR_IN) && ctrl->wLength) {
		if (len > (int)ctrl->wLength)
			len = ctrl->wLength;
		ep0_transfer(reply, (uint32_t)len);
	} else {
		ep0_transfer(NULL, ctrl->wLength);
	}
}

static void *gadget_event_loop(void *unused)
{
	uint8_t buf[sizeof(struct usb_raw_event) + EP0_MAX];
	struct usb_raw_event *event = (void *)buf;

	for (;;) {
		event->type = 0;
		event->length = EP0_MAX;
		if (ioctl(raw_gadget_fd, USB_RAW_IOCTL_EVENT_FETCH, event) < 0) {
			if (errno == EINTR)
				continue;
			return unused;
		}
		if (event->type == USB_RAW_EVENT_CONTROL)
			handle_control_request((struct usb_ctrlrequest *)event->data);
	}
	return unused;
}

/* the i2c bus number whose adapter name is the emulated tiny-usb dongle */
static int find_tiny_usb_i2c_bus(void)
{
	char path[64], name[128];
	int bus, fd, n;

	for (bus = 0; bus < 32; bus++) {
		snprintf(path, sizeof(path),
			 "/sys/bus/i2c/devices/i2c-%d/name", bus);
		fd = open(path, O_RDONLY);
		if (fd < 0)
			continue;
		n = read(fd, name, sizeof(name) - 1);
		close(fd);
		if (n <= 0)
			continue;
		name[n] = 0;
		if (strstr(name, "tiny-usb"))
			return bus;
	}
	return -1;
}

int main(void)
{
	struct usb_raw_init init = { .speed = USB_SPEED_HIGH };
	char new_device_path[64];
	pthread_t gadget_thread;
	struct dirent *udc_ent;
	char *udc_index;
	DIR *udc_dir;
	int bus = -1, i;

	udc_dir = opendir("/sys/class/udc");
	while ((udc_ent = readdir(udc_dir)) && udc_ent->d_name[0] == '.')
		;
	if (!udc_ent) {
		printf("no UDC in /sys/class/udc\n");
		return 1;
	}
	strcpy((char *)init.device_name, udc_ent->d_name);
	strcpy((char *)init.driver_name, udc_ent->d_name);
	closedir(udc_dir);
	udc_index = strrchr((char *)init.driver_name, '.');
	if (udc_index)
		*udc_index = 0;

	raw_gadget_fd = open("/dev/raw-gadget", O_RDWR);
	ioctl(raw_gadget_fd, USB_RAW_IOCTL_INIT, &init);

	ioctl(raw_gadget_fd, USB_RAW_IOCTL_RUN, 0);
	pthread_create(&gadget_thread, NULL, gadget_event_loop, NULL);

	for (i = 0; i < 300 && bus < 0; i++) {
		usleep(50000);
		bus = find_tiny_usb_i2c_bus();
	}
	if (bus < 0) {
		printf("i2c-tiny-usb adapter never appeared\n");
		return 1;
	}

	snprintf(new_device_path, sizeof(new_device_path),
		 "/sys/bus/i2c/devices/i2c-%d/new_device", bus);
	write_sysfs(new_device_path, "retu 0x01\n");
	write_sysfs(new_device_path, "tahvo 0x02\n");

	write_sysfs("/sys/devices/system/cpu/cpu1/online", "0\n");
	return 0;
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-09-09 17:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-28  5:41 [BUG] KASAN: slab-use-after-free Read in irq_migrate_all_off_this_cpu Farhad Alemi
2026-08-29 20:34 ` Radu Rendec
2026-08-30 18:30   ` Thomas Gleixner
2026-08-30 18:48     ` Radu Rendec
2026-09-09 17:56       ` Farhad Alemi
2026-08-30  6:24 ` Thomas Gleixner
2026-08-30 14:16   ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®