Re: [PATCH v2] HID: sony: fix UAF of ghl_poke_timer / ghl_urb at driver unbind

Jiri Kosina <[email protected]>
Newsgroups org.kernel.vger.linux-input,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
On Fri, 24 Jul 2026, Doruk Tan Ozturk wrote:

> For GHL (Guitar Hero Live) dongles, sony_probe() arms a periodic timer:
> ghl_magic_poke() (the timer callback) submits sc->ghl_urb, and the URB
> completion ghl_magic_poke_cb() re-arms the timer with mod_timer().
> 
> sony_remove() drained the timer with timer_delete_sync() and then freed
> the URB with usb_free_urb():
> 
> 	timer_delete_sync(&sc->ghl_poke_timer);
> 	usb_free_urb(sc->ghl_urb);
> 
> timer_delete_sync() does not block re-arming, and while the URB is in
> flight the timer is not pending, so the sync delete is a no-op. A URB
> completion that runs after the delete re-arms the timer, and usb_free_urb()
> only drops a reference -- it does not kill an in-flight URB. sc is
> allocated with devm_kzalloc() and freed once sony_remove() returns, so the
> re-armed ghl_poke_timer (embedded in sc) then fires on freed memory, a
> use-after-free from timer softirq. This is a disconnect/rmmod race.
> 
> Poison the URB first, then shut the timer down, before freeing the URB.
> usb_poison_urb() kills any in-flight URB and permanently rejects further
> submissions, so a poke timer that is still pending cannot re-submit the
> URB from ghl_magic_poke() in the window before timer_shutdown_sync() runs.
> usb_kill_urb() would not suffice: it only cancels the in-flight URB and
> leaves it submittable once it returns, so the pending timer could
> re-submit it and put a fresh URB in flight over the freed sc.
> timer_shutdown_sync() then drains any last callback and blocks re-arming.
> The probe error path is unaffected: it is only reached before the timer
> is armed.
> 
> Reproduced under KASAN on next-20260710 via dummy_hcd + raw-gadget
> emulation of the GHL PS4 dongle (VID 0x1430 / PID 0x07bb): hid-sony binds
> and arms the poke timer, the poke URB is held in flight, the driver is
> unbound (freeing sc), then the URB is released. The completion re-arms the
> timer on the freed sc, and the re-armed timer fires ~8 s later:
> 
>   BUG: KASAN: slab-use-after-free in ghl_magic_poke+0x98/0xb0
>   Read of size 8 at addr ffff88810b02fd50 by task swapper/0/0
>    ghl_magic_poke+0x98/0xb0
>    call_timer_fn+0x35/0x2b0
>    __run_timers+0x69c/0x9a0
>    run_timer_softirq+0x173/0x2a0
>   Allocated by task 169:  sony_probe
>   Freed by task 338:      devres_release_group <- hid_device_remove (sony_remove)
> 
> Found by 0sec (https://0sec.ai) using automated source analysis.
> 
> Fixes: cc894ac55360 ("HID: sony: support for ghlive ps3/wii u dongles")
> Cc: [email protected]
> Assisted-by: 0sec:multi-model
> Signed-off-by: Doruk Tan Ozturk <[email protected]>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.