mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/1] media: rc: fix igorplugusb disconnect UAF
@ 2026-09-24  2:53 Yuanzhe Liu
  2026-09-24  2:53 ` [PATCH 1/1] media: rc: igorplugusb: quiesce callbacks before unregister Yuanzhe Liu
  0 siblings, 1 reply; 3+ messages in thread
From: Yuanzhe Liu @ 2026-09-24  2:53 UTC (permalink / raw)
  To: sean; +Cc: mchehab, oneukum, linux-media, linux-kernel, Yuanzhe Liu

Hi,

this single-patch series fixes a task_struct use-after-free in the
igorplugusb disconnect path. The crash was observed during USB reset
stress testing of an emulated IgorPlug-USB receiver (03eb:0002) behind
xHCI on a KASAN-enabled 7.1.2 kernel. Real hardware has not been tested.

Root-cause walkthrough
----------------------

1. A control URB completion enters igorplugusb_callback().
2. USBDEVFS_RESET concurrently unbinds the interface and enters
   igorplugusb_disconnect().
3. The disconnect path calls rc_unregister_device() first, which stops
   the raw-IR kthread through ir_raw_event_unregister().
4. The pending callback reaches ir_raw_event_handle() and passes the
   stale raw->thread pointer to wake_up_process(). try_to_wake_up() then
   accesses the freed task_struct while acquiring p->pi_lock.

Patch summary
-------------

Patch 1 poisons and drains the URB, then synchronously deletes the timer,
before unregistering the rc device. This removes both URB producers while
the raw-IR thread is still alive.

Crash report addressed
----------------------

  Report 1: KASAN slab-use-after-free write in try_to_wake_up(), reached
            from igorplugusb_callback() through ir_raw_event_handle().
            A condensed splat is appended below the diffstat.

Test status
-----------

The patch passes git's whitespace check. It has not been build-tested or
runtime-tested, and no Tested-by tag is claimed.

Yuanzhe Liu (1):
  media: rc: igorplugusb: quiesce callbacks before unregister

 drivers/media/rc/igorplugusb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--
Crash excerpt:

  BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave+0x63/0xb0
  Write of size 4 at addr ffff888004b0732c by task ksoftirqd/0/14

  Call Trace:
   try_to_wake_up+0x80/0x1030 kernel/sched/core.c:4190
   ir_raw_event_handle+0x6a/0x80 drivers/media/rc/rc-ir-raw.c:232
   igorplugusb_irdata drivers/media/rc/igorplugusb.c:70 [inline]
   igorplugusb_callback+0x7c4/0x920 drivers/media/rc/igorplugusb.c:105
   __usb_hcd_giveback_urb+0x236/0x540 drivers/usb/core/hcd.c:1655
   usb_giveback_urb_bh+0x20b/0x530 drivers/usb/core/hcd.c:1689

  Second to last potentially related work creation:
   kthread_stop+0x120/0x240 kernel/kthread.c:760
   ir_raw_event_unregister+0x85/0x2f0 drivers/media/rc/rc-ir-raw.c:662
   rc_unregister_device+0x2e5/0x380 drivers/media/rc/rc-main.c:2022
   igorplugusb_disconnect+0x5e/0x1d0 drivers/media/rc/igorplugusb.c:244
   usb_unbind_interface+0x188/0x770 drivers/usb/core/driver.c:458
   usb_forced_unbind_intf+0xf1/0x1a0 drivers/usb/core/driver.c:1133
   usb_reset_device+0x4c4/0x1db0 drivers/usb/core/hub.c:6404

  The buggy address belongs to the cache task_struct of size 3328.
  It is located 1836 bytes inside a freed 3328-byte region.


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

* [PATCH 1/1] media: rc: igorplugusb: quiesce callbacks before unregister
  2026-09-24  2:53 [PATCH 0/1] media: rc: fix igorplugusb disconnect UAF Yuanzhe Liu
@ 2026-09-24  2:53 ` Yuanzhe Liu
  2026-09-24  8:25   ` Sean Young
  0 siblings, 1 reply; 3+ messages in thread
From: Yuanzhe Liu @ 2026-09-24  2:53 UTC (permalink / raw)
  To: sean; +Cc: mchehab, oneukum, linux-media, linux-kernel, Yuanzhe Liu, stable

igorplugusb_disconnect() unregisters the rc device before poisoning its
URB. rc_unregister_device() stops the raw-IR kthread, but a completion
callback that is already running can still call ir_raw_event_handle().
This makes wake_up_process() dereference the kthread's freed task_struct
and triggers a KASAN use-after-free in try_to_wake_up().

Poison the URB and delete the timer before unregistering the rc device.
Poisoning drains any active callback and prevents resubmission, while
deleting the timer stops the other URB producer. No callback can then
reach rc-core after its raw-IR kthread has been stopped.

Fixes: b1c97193c643 ("[media] rc: port IgorPlug-USB to rc-core")
Cc: stable@vger.kernel.org
Signed-off-by: Yuanzhe Liu <25031212351@stu.xidian.edu.cn>
---
 drivers/media/rc/igorplugusb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
index b5117ee..42e05b9 100644
--- a/drivers/media/rc/igorplugusb.c
+++ b/drivers/media/rc/igorplugusb.c
@@ -241,9 +241,9 @@ static void igorplugusb_disconnect(struct usb_interface *intf)
 {
 	struct igorplugusb *ir = usb_get_intfdata(intf);
 
-	rc_unregister_device(ir->rc);
 	usb_poison_urb(ir->urb);
 	timer_delete_sync(&ir->timer);
+	rc_unregister_device(ir->rc);
 	usb_set_intfdata(intf, NULL);
 	usb_unpoison_urb(ir->urb);
 	usb_free_urb(ir->urb);
-- 
2.45.1.windows.1


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

* Re: [PATCH 1/1] media: rc: igorplugusb: quiesce callbacks before unregister
  2026-09-24  2:53 ` [PATCH 1/1] media: rc: igorplugusb: quiesce callbacks before unregister Yuanzhe Liu
@ 2026-09-24  8:25   ` Sean Young
  0 siblings, 0 replies; 3+ messages in thread
From: Sean Young @ 2026-09-24  8:25 UTC (permalink / raw)
  To: Yuanzhe Liu; +Cc: mchehab, oneukum, linux-media, linux-kernel, stable

On Thu, Sep 24, 2026 at 10:53:51AM +0800, Yuanzhe Liu wrote:
> igorplugusb_disconnect() unregisters the rc device before poisoning its
> URB. rc_unregister_device() stops the raw-IR kthread, but a completion
> callback that is already running can still call ir_raw_event_handle().
> This makes wake_up_process() dereference the kthread's freed task_struct
> and triggers a KASAN use-after-free in try_to_wake_up().

This is problem with the framework rather than the driver. The
media-committers tree already contains a fix for this issue:

https://gitlab.freedesktop.org/linux-media/media-committers/-/commit/3ae19773168104fa57d2a2ec57731e89df54175f

> Poison the URB and delete the timer before unregistering the rc device.
> Poisoning drains any active callback and prevents resubmission, while
> deleting the timer stops the other URB producer. No callback can then
> reach rc-core after its raw-IR kthread has been stopped.

Stopping all the urbs before calling rc_unregister_device() isn't really an
option for all drivers. Users can still do various ioctl/write on the lirc
chardev which could bring various URBs back into flight. For receive-only IR
devices like igorplugusb this might not be an problem.

Thanks,

Sean

> 
> Fixes: b1c97193c643 ("[media] rc: port IgorPlug-USB to rc-core")
> Cc: stable@vger.kernel.org
> Signed-off-by: Yuanzhe Liu <25031212351@stu.xidian.edu.cn>
> ---
>  drivers/media/rc/igorplugusb.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c
> index b5117ee..42e05b9 100644
> --- a/drivers/media/rc/igorplugusb.c
> +++ b/drivers/media/rc/igorplugusb.c
> @@ -241,9 +241,9 @@ static void igorplugusb_disconnect(struct usb_interface *intf)
>  {
>  	struct igorplugusb *ir = usb_get_intfdata(intf);
>  
> -	rc_unregister_device(ir->rc);
>  	usb_poison_urb(ir->urb);
>  	timer_delete_sync(&ir->timer);
> +	rc_unregister_device(ir->rc);
>  	usb_set_intfdata(intf, NULL);
>  	usb_unpoison_urb(ir->urb);
>  	usb_free_urb(ir->urb);
> -- 
> 2.45.1.windows.1
> 

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

end of thread, other threads:[~2026-09-24  8:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-24  2:53 [PATCH 0/1] media: rc: fix igorplugusb disconnect UAF Yuanzhe Liu
2026-09-24  2:53 ` [PATCH 1/1] media: rc: igorplugusb: quiesce callbacks before unregister Yuanzhe Liu
2026-09-24  8:25   ` Sean Young

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®