🇰🇷 한글 설명
Linux 커널의 Broadcom BDC UDC 드라이버에서 리소스 해제 순서 문제로 인해 발생하는 취약점입니다. 드라이버 제거 과정에서 인터럽트 핸들러와 지연된 작업이 완전히 종료되기 전에 메모리가 먼저 해제되어 NULL 포인터 역참조 또는 Use-After-Free(UAF)가 발생할 수 있습니다.
💡 쉬운 설명
장치를 끌 때 메모리를 먼저 지워버리고 나서 나중에 신호를 처리하려고 시도하기 때문에 발생하는 오류입니다. 이 과정에서 이미 사라진 메모리 주소를 참조하게 되어 시스템이 충돌하거나 보안 문제가 생길 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: udc: bdc: free IRQ and drain func_wake_notify before teardown
The Broadcom BDC UDC driver registers its IRQ handler with
devm_request_irq() in bdc_udc_init(), so the IRQ is released by devm
only after bdc_remove() returns. devm releases resources in reverse
LIFO order, but bdc_remove() runs bdc_udc_exit() and bdc_hw_exit() ->
bdc_mem_free() manually before returning: bdc_udc_exit() tears down
individual endpoint objects via bdc_free_ep(), while bdc_hw_exit() ->
bdc_mem_free() frees and NULLs the DMA-coherent status-report ring
(bdc->srr.sr_bds) and kfree()s bdc->bdc_ep_array. Both happen while
the IRQ handler (bdc_udc_interrupt, requested with IRQF_SHARED)
remains deliverable in the window up to the post-remove devm
free_irq().
On receipt of a shared interrupt in that window, bdc_udc_interrupt()
dereferences bdc->srr.sr_bds[bdc->srr.dqp_index] (NULL or freed DMA)
and dispatches sr_handler callbacks that index into bdc_ep_array,
causing a NULL-deref or use-after-free.
The same window affects the delayed_work bdc->func_wake_notify, which is
armed from the IRQ handler via bdc_sr_uspc() -> handle_link_state_change()
-> schedule_delayed_work() and may self-rearm from its own callback
bdc_func_wake_timer(). No cancel exists anywhere in the driver, so a
queued work item that fires after bdc_remove() returns and the bdc
structure is devm-freed dereferences freed memory.
Replace devm_request_irq() with request_irq() and add an explicit
free_irq(bdc->irq, bdc) in bdc_remove(). Clear BDC_GIE before
free_irq() to stop the device from asserting interrupts, then
free_irq() drains any in-flight handler, then cancel_delayed_work_sync()
drains the func_wake_notify delayed work. This ordering ensures the
IRQ handler and delayed work cannot interfere with the subsequent
endpoint and DMA teardown in bdc_udc_exit() and bdc_hw_exit(). Wire the
matching free_irq() into the bdc_udc_init() error path so the IRQ is
released on probe failure, and route the bdc_init_ep() failure through
err0 instead of returning directly.
This issue was found by an in-house static analysis tool.
📍 영향받는 시스템
Broadcom BDC UDC 드라이버를 사용하는 Linux 커널 시스템
⚔️ 공격 벡터
장치 제거(Teardown) 과정 중 인터럽트 또는 지연된 작업을 유도하여 메모리 오류 유발
🛡️ 대응 방법
커널 패치를 통해 devm_request_irq를 request_irq로 변경하고, bdc_remove 시 명시적으로 free_irq 및 cancel_delayed_work_sync를 호출하도록 수정
🔧 검증 코드
현재 실행 중인 커널 버전을 확인하여 해당 취약점이 해결된 패치 버전인지 확인합니다.