Linux Kernel
CVE-2024-36894
HIGH
Severity by source
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Race condition timing dependency raises AC to H; PR:L confirmed by local FFS application access; no scope change, full kernel-space impact if exploited.
Primary rating from Vendor (416baaa9-dc9f-4396-8d5f-8c081fb06d67).
CVSS VectorVendor: 416baaa9-dc9f-4396-8d5f-8c081fb06d67
Lifecycle Timeline
6DescriptionCVE.org
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")
AnalysisAI
Race condition in the Linux kernel's USB gadget Function File System (f_fs) driver allows a local low-privileged user to trigger a use-after-free by simultaneously issuing an AIO cancel call while the USB Device Controller handles a soft disconnect event. The flaw arises because usb_ep_free_request() and usb_ep_dequeue() can race on the same io_data->req pointer without synchronization, leading to potential privilege escalation. No public exploit code or CISA KEV listing exists at time of analysis, and the 0.01% EPSS score reflects the narrow attack surface requiring USB gadget hardware and a specific FFS-based application.
Technical ContextAI
The vulnerability resides in drivers/usb/gadget/function/f_fs.c within the Linux kernel's USB gadget subsystem (CWE-362: Race Condition). The Function File System (f_fs) interface allows userspace applications to implement USB gadget functions via AIO operations. The root cause is the absence of locking between ffs_epfile_async_io_complete() and ffs_aio_cancel(): a prior commit (b566d38857fc) relocated usb_ep_free_request() into the completion handler, and adding a spinlock there is impossible because usb_ep_dequeue() calls the same completion handler synchronously, creating a deadlock. Affected CPE entries confirm this spans multiple Linux kernel stable branches up to 6.9-rc3, as evidenced by eight separate backport commits across stable trees.
RemediationAI
Apply the upstream kernel patches provided across eight stable-branch commits referenced from git.kernel.org/stable, including commits 24729b307eef, 3613e5023f09, 73c05ad46bb4, 9e72ef59cbe6, a0fdccb1c9e0, d746183082324, e500b1c4e29a, and f71a53148ce3. The fix moves usb_ep_free_request() back to ffs_user_copy_worker() and nullifies io_data->req within ffs->eps_lock after freeing, eliminating the race. Downstream distributions (Debian, Ubuntu, RHEL, embedded BSPs) should be checked for backported fixes. As a compensating control where patching is not immediately possible, disabling or restricting access to FFS-based USB gadget applications eliminates the vulnerable code path entirely, with the trade-off of losing USB gadget functionality. Kernel live-patching (kpatch/livepatch) may be available for distributions that support it.
Same weakness CWE-362 – Race Condition
View allSame technique Information Disclosure
View allShare
External POC / Exploit Code
Leaving vuln.today