🇰🇷 한글 설명
Linux 커널의 hid-sony 드라이버에서 GHL(Guitar Hero Live) 동글 해제 시 발생하는 Use-After-Free(UAF) 취약점입니다. 드라이버 언바인드 과정에서 타이머와 URB(USB Request Block)의 해제 순서가 적절하지 않아, 이미 해제된 메모리 영역에 타이머가 다시 접근하여 시스템 오류를 유발할 수 있습니다.
💡 쉬운 설명
USB 장치를 컴퓨터에서 분리할 때, 프로그램이 이미 사라진 메모리 주소를 다시 사용하려고 시도하면서 발생하는 오류입니다. 이로 인해 시스템이 멈추거나 예기치 않은 동작을 할 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
HID: sony: fix UAF of ghl_poke_timer / ghl_urb at driver unbind
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.
📍 영향받는 시스템
Linux kernel (hid-sony driver using GHL dongles)
⚔️ 공격 벡터
물리적 USB 장치(GHL 동글)의 연결 해제 또는 드라이버 언바인드 시 발생하는 레이스 컨디션(Race Condition)
🛡️ 대응 방법
커널 패치를 통해 usb_poison_urb()를 사용하여 실행 중인 URB를 무효화하고, timer_shutdown_sync()를 사용하여 타이머 재등록을 방지하도록 수정해야 합니다.
🔧 검증 코드
현재 실행 중인 커널 버전을 확인하여 해당 취약점이 수정된 패치 버전인지 확인합니다.