CVE-2025-39801: Add .vulnerable file
The root cause commit is 72246da40f3719af3bfd104a2365b32537c27d83:
Author: Felipe Balbi <balbi@ti.com>
Date: Fri Aug 19 18:10:58 2011 +0300
Subject: usb: Introduce DesignWare USB3 DRD Driver
The fix (commit 45eae113dccaf8e502090ecf5b3d9e9b805add6f) removes
WARN_ON and WARN_ON_ONCE calls from six locations in the dwc3 USB driver
where device endpoint commands are sent:
| File | Function | Original WARN | Origin Commit |
|---------------|------------------------------|--------------------|-----------------|
| ep0.c:291 | dwc3_ep0_out_start | WARN_ON(ret < 0) | 72246da40f37 |
| ep0.c:1064 | __dwc3_ep0_do_control_data | WARN_ON(ret < 0) |
c7fcdeb2627c4 |
| ep0.c:1081 | __dwc3_ep0_do_control_status | WARN_ON(...) |
f0f2b2a2db85f |
| ep0.c:1124 | dwc3_ep0_end_control_data | WARN_ON_ONCE(ret) |
2e3db064855a6 |
| gadget.c:1775 | __dwc3_stop_active_transfer | WARN_ON_ONCE(ret) |
72246da40f37 |
| gadget.c:4051 | dwc3_clear_stall_all_ep | WARN_ON_ONCE(ret) |
72246da40f37 |
The Bug Mechanism:
1. The core function dwc3_send_gadget_ep_cmd() sends commands to the
USB controller hardware and polls for completion. If the hardware
doesn't respond within the timeout period (~5000 iterations), it
returns
-ETIMEDOUT.
2. The original driver introduced WARN_ON on the return value, assuming
endpoint command failures should never happen:
From commit 72246da40f37 (drivers/usb/dwc3/gadget.c):
ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms);
WARN_ON_ONCE(ret);
From commit 72246da40f37 (drivers/usb/dwc3/ep0.c):
ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8);
WARN_ON(ret < 0);
3. This assumption is incorrect. During fast software-controlled
connect/disconnect cycles, endpoint command timeouts can legitimately
occur:
- Control transfers from the previous connection may not have
completed
- The controller may still be processing endpoint commands from the
previous connect
- End transfer commands and USB_ENDPOINT_HALT feature requests can
timeout
4. The consequence: When panic_on_warn is enabled (common in production
systems for catching bugs), these legitimate timeouts cause kernel
panics. When disabled, they cause unnecessary call trace dumps that
pollute logs.
Why 72246da40f37 is the Root Cause:
This commit introduced the DesignWare USB3 DRD Driver on August 19,
2011, and established the flawed design pattern:
1. It introduced the assumption that endpoint command failures are
always bugs worthy of a WARN_ON
2. It set the precedent that subsequent developers followed (commits
c7fcdeb2627c4, f0f2b2a2db85f, 2e3db064855a6 all added more WARN_ONs
following this pattern)
3. Three of the six WARN_ONs removed in the fix directly trace back to
this original commit
The original code from 72246da40f37:
// In gadget.c - disconnect handler (now in __dwc3_stop_active_transfer)
ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms);
WARN_ON_ONCE(ret);
// In gadget.c - dwc3_clear_stall_all_ep
ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, DWC3_DEPCMD_CLEARSTALL, ¶ms);
WARN_ON_ONCE(ret);
// In ep0.c - dwc3_ep0_out_start
ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8);
WARN_ON(ret < 0);
All three locations assumed that dwc3_send_gadget_ep_cmd() (or
functions that call it like dwc3_ep0_start_trans()) should never fail,
but this is not true during legitimate fast connect/disconnect scenarios
on certain platforms (like Samsung Exynos).
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 file changed