🔍 CVE-2024-36894

7.8
CVSS Score
HIGH
2024-05-30
2026-10-15 01:18
✅ 완료

🇰🇷 한글 설명

Linux 커널의 USB gadget f_fs 구성 요소에서 aio_cancel() 호출과 AIO 요청 완료 처리 간의 레이스 컨디션(경쟁 상태) 취약점이 발견되었습니다. 소프트 디스커넥트 상황에서 두 프로세스가 동시에 실행될 경우, 이미 해제된 USB 요청 객체에 접근하여 잘못된 포인터를 참조할 수 있습니다.

💡 쉬운 설명

USB 장치 연결이 끊기는 순간에 데이터 요청을 취소하려는 동작이 동시에 일어나면서 컴퓨터 메모리 관리 오류가 발생하는 문제입니다. 이로 인해 시스템이 불안정해지거나 예상치 못한 동작이 발생할 수 있습니다.

🇺🇸 원문 (English)

In the Linux kernel, the following vulnerability has been resolved: usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete FFS based applications can utilize the aio_cancel() callback to dequeue pending USB requests submitted to the UDC. There is a scenario where the FFS application issues an AIO cancel call, while the UDC is handling a soft disconnect. For a DWC3 based implementation, the callstack looks like the following: DWC3 Gadget FFS Application dwc3_gadget_soft_disconnect() ... --> dwc3_stop_active_transfers() --> dwc3_gadget_giveback(-ESHUTDOWN) --> ffs_epfile_async_io_complete() ffs_aio_cancel() --> usb_ep_free_request() --> usb_ep_dequeue() There is currently no locking implemented between the AIO completion handler and AIO cancel, so the issue occurs if the completion routine is running in parallel to an AIO cancel call coming from the FFS application. As the completion call frees the USB request (io_data->req) the FFS application is also referencing it for the usb_ep_dequeue() call. This can lead to accessing a stale/hanging pointer. commit b566d38857fc ("usb: gadget: f_fs: use io_data->status consistently") relocated the usb_ep_free_request() into ffs_epfile_async_io_complete(). However, in order to properly implement locking to mitigate this issue, the spinlock can't be added to ffs_epfile_async_io_complete(), as usb_ep_dequeue() (if successfully dequeuing a USB request) will call the function driver's completion handler in the same context. Hence, leading into a deadlock. Fix this issue by moving the usb_ep_free_request() back to ffs_user_copy_worker(), and ensuring that it explicitly sets io_data->req to NULL after freeing it within the ffs->eps_lock. This resolves the race condition above, as the ffs_aio_cancel() routine will not continue attempting to dequeue a request that has already been freed, or the ffs_user_copy_work() not freeing the USB request until the AIO cancel is done referencing it. This fix depends on commit b566d38857fc ("usb: gadget: f_fs: use io_data->status consistently")

📍 영향받는 시스템

Linux kernel (USB gadget f_fs 및 DWC3 기반 구현 사용 시스템)

⚔️ 공격 벡터

FFS 기반 애플리케이션을 통해 특정 타이밍에 AIO 취소 요청을 보내 레이스 컨디션을 유도

🛡️ 대응 방법

커널 패치(commit b566d38857fc 관련 수정 사항 포함)를 적용하여 usb_ep_free_request() 호출 위치를 변경하고 락(lock)을 통해 동기화 수행

🔧 검증 코드

현재 실행 중인 커널 버전을 확인하여 취약점이 해결된 패치 버전이 적용되었는지 확인

Shell / Script
uname -r

📊 CVSS Vector String

CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

💻 영향받는 소프트웨어

Linux Kernel