In the world of kernel development, even subtle mistakes can have significant security and stability consequences. CVE-2021-46941 highlights one such issue in the Linux kernel's USB DWC3 (DesignWare Core SuperSpeed USB 3.) controller driver, where incomplete adherence to the mode switching programming guide led to platform lockups and potential instability.
In this article, we'll break down what went wrong, how it was patched, and what you need to know to stay secure. We'll provide relevant code snippets and reference original sources for further reading.
Background: Dual-Role Device (DRD) USB Controllers
Many modern platforms use Dual-Role Device (DRD) USB controllers, which can act as either a USB host (e.g., for connecting a keyboard) or device (e.g., acting as storage when plugged into another PC). The DWC3 core, found in many ARM SoCs, manages this.
Switching Modes between host and device is not a trivial operation. The controller must be carefully reset and registers reconfigured per the programming guide from Synopsys. If not done right, the system can become unstable or even lock up.
The Vulnerability
The flaw in the Linux kernel driver (prior to the fix) was simple: some required reset steps were missing when changing DRD (host/device) modes. The code failed to:
Why does this matter?
Without the proper resets, the controller's state could become inconsistent, resulting in lock-ups, failures to switch modes, or undefined behavior. This was experienced on systems like the HiKey960 board and others.
Real-world breakages
* John Stultz’s report
* Ferry's test case
## Exploit/Attack Details
This is predominantly a stability and reliability issue, not a direct remote code execution vector. However, an attacker with physical access or the ability to cause mode switches (from device to host or vice versa) could trigger a DoS (Denial of Service) condition:
Denial of Service: The system may lock up during mode switch, requiring a manual restart.
- Potential for Escalation: In environments where USB mode changes are exposed to untrusted peripherals, an attacker could repeatedly trigger the bug to degrade system availability.
There’s no published remote exploit for this vulnerability, but the risk is real for embedded systems and development boards.
Patch and Technical Solution
The fix, as submitted upstream, strictly follows the recommended sequence from the Synopsys programming guide:
Below is a simplified version of the fixed logic in C, extracted and reworded for clarity
// When switching modes (host <-> device)
static int dwc3_core_soft_reset(struct dwc3 *dwc)
{
u32 reg;
// Step 1: Assert core softreset
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
reg |= DWC3_GCTL_CORESOFTRESET;
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
// Step 2: Wait for clocks to synchronize
msleep(100); // required wait
// Step 3: De-assert core softreset
reg &= ~DWC3_GCTL_CORESOFTRESET;
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
}
static void dwc3_set_mode(struct dwc3 *dwc, enum usb_dr_mode mode)
{
dwc3_core_soft_reset(dwc);
// ... set mode-specific registers ...
if (mode == DRD_DEVICE) {
// Step: Device soft reset as per the guide
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
reg |= DWC3_DCTL_CSFTRST;
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
// Wait for reset to complete...
}
}
Note: The real patch includes checks, error handling, and register definitions not shown above.
Patch References
- Kernel mailing list patch
- Upstream commit
How to Detect If You Are Affected
- Kernel versions: Check if your kernel is older than v5.11 and you use a platform with a dual-role DWC3 USB device.
Upgrade your kernel: Ensure your kernel includes the above patch or is newer than Linux 5.11.
2. Use LTS releases: Prioritize long term support kernels, which generally have such stability fixes backported promptly.
3. Limit exposure: Restrict DRD mode switching to trusted users and avoid hot-plugging in untrusted environments.
4. Monitor for unusual lockups: Keep an eye on kernel logs for DWC3-related errors or mode-switch failures.
Conclusion
CVE-2021-46941 serves as a reminder that close adherence to hardware programming guidelines is essential—especially in low-level, security-critical components like kernel drivers. If you maintain systems with DWC3 USB controllers, audit your kernel and apply all relevant updates.
Further Reading
- Original bug report
- Upstream commit diff
- DRD controller programming guide (Synopsys) (registration/login required)
Timeline
Published on: 02/27/2024 19:04:05 UTC
Last modified on: 04/10/2024 19:42:17 UTC