🇰🇷 한글 설명
Linux 커널의 usb gadget f_fs 모듈에서 ep0 읽기 루프 중 데드락이 발생할 수 있는 취약점입니다. 사용자가 ep0를 폴링하는 동안 configfs를 통해 가젯을 해제하면, 뮤텍스 점유 상태로 인해 커널 스레드와 사용자 프로세스가 서로를 기다리며 시스템이 멈출 수 있습니다.
💡 쉬운 설명
USB 장치 기능을 사용하는 소프트웨어가 데이터를 읽으려고 기다리는 동안, 장치 설정을 갑자기 바꾸면 컴퓨터의 핵심 기능이 서로 엉켜서 멈춰버리는 문제입니다. 이로 인해 시스템이 응답하지 않는 상태가 될 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: f_fs: Prevent deadlock during ep0 read loop
Currently, ffs_ep0_read() holds ffs->mutex when it prepares to go to
sleep waiting for an event. When no setup events are pending, it calls
wait_event_interruptible_exclusive_locked_irq() with the mutex still
held. The wait macro deliberately drops the waitqueue spinlock before
sleeping but does not drop the mutex.
If a userspace daemon is polling ep0 via read() and the gadget is
asynchronously torn down via configfs (e.g., echo "" > UDC), a
deadlock can occur:
1. The configfs teardown calls functionfs_unbind(), which queues a
FUNCTIONFS_UNBIND event.
2. The daemon wakes up, consumes the event, and drops the mutex.
3. However, if the daemon loops and immediately issues another read()
before exiting, it reacquires ffs->mutex and again goes into an
interruptible sleep.
4. Meanwhile, functionfs_unbind() continues execution and attempts to
acquire ffs->mutex to tear down ep0req.
5. The kernel deadlocks because the configfs thread is stuck in an
uninterruptible sleep waiting for the mutex, while the userspace
daemon is in an interruptible sleep holding the mutex forever
because no more events will arrive.
To fix this, we drop both the waitqueue spinlock and ffs->mutex before
going to sleep, and use wait_event_interruptible_exclusive() instead.
Upon waking up, we jump back to the `retry` label to safely reacquire
the mutex and re-evaluate the state machine. By not sleeping with
ffs->mutex held, we natively decouple gadget teardowns (which require
the mutex) from userspace polling.
📍 영향받는 시스템
Linux kernel (usb gadget f_fs module 사용 환경)
⚔️ 공격 벡터
사용자 공간의 데몬이 ep0를 폴링하는 상태에서 configfs를 통해 가젯을 비동기적으로 해제(teardown)할 때 발생
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 ffs->mutex를 해제하고 대기하도록 수정된 코드를 적용해야 합니다.
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 패치 버전 이후인지 확인합니다.