Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-31756

CVE-2026-31756: Linux Kernel Race Condition Vulnerability

CVE-2026-31756 is a race condition flaw in the Linux kernel's USB DWC2 gadget driver that causes spin lock mismatches and potential deadlocks. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-31756 Overview

CVE-2026-31756 is a locking defect in the Linux kernel's DesignWare USB 2.0 (dwc2) gadget driver. The flaw resides in dwc2_hsotg_udc_stop(), which invokes dwc2_gadget_exit_clock_gating() without first acquiring hsotg->lock. Because the called function internally uses the call_gadget() macro, which expects the lock to already be held and performs spin_unlock/spin_lock around the gadget driver callback, the mismatch produces undefined behavior and a subsequent deadlock when spin_lock_irqsave() is later called in the same function. The Linux kernel maintainers have resolved the issue across multiple stable branches.

Critical Impact

A spinlock state mismatch in the dwc2 USB gadget driver can deadlock the kernel during USB device controller stop operations, leading to denial of service on affected systems.

Affected Products

  • Linux kernel versions containing the dwc2 USB gadget driver prior to the fix commits
  • Stable kernel branches receiving backports referenced in the kernel.org commit set
  • Embedded and SoC platforms using the DesignWare HS OTG USB controller in gadget mode

Discovery Timeline

  • 2026-05-01 - CVE-2026-31756 published to NVD
  • 2026-05-01 - Last updated in NVD database

Technical Details for CVE-2026-31756

Vulnerability Analysis

The vulnerability is a synchronization defect [CWE-667] in drivers/usb/dwc2/gadget.c. When the USB Device Controller (UDC) is stopped through dwc2_hsotg_udc_stop(), the function calls dwc2_gadget_exit_clock_gating() to disable clock gating during shutdown. The exit-clock-gating path internally invokes the call_gadget() macro, which assumes the caller already holds hsotg->lock because it temporarily releases the lock with spin_unlock to invoke the gadget driver callback before reacquiring it with spin_lock.

Because dwc2_hsotg_udc_stop() did not hold hsotg->lock prior to the call, two consequences follow. First, spin_unlock executes against a lock that is not held, which is undefined behavior in the kernel locking model. Second, after the callback returns, call_gadget() reacquires the lock, leaving it held when control returns to dwc2_hsotg_udc_stop(). The function then calls spin_lock_irqsave() on the same lock, producing a self-deadlock.

Root Cause

The root cause is an unmet locking precondition. The call_gadget() macro requires hsotg->lock to be held by the caller, but dwc2_hsotg_udc_stop() violated that contract. The fix acquires hsotg->lock before calling dwc2_gadget_exit_clock_gating() and releases it afterward, satisfying the macro's locking requirement.

Attack Vector

The defect is reached through normal USB gadget controller shutdown paths, such as unbinding a gadget driver or removing the dwc2 module. Triggering the deadlock requires local interaction with the USB subsystem on a system where the dwc2 driver is active. No remote exploitation vector is described in the kernel changelog. The practical impact is a kernel hang or system stall affecting availability.

No public proof-of-concept code is referenced in the advisory. The vulnerability is described in prose by the upstream commit message; readers should consult the Linux Kernel Commit for the patch diff.

Detection Methods for CVE-2026-31756

Indicators of Compromise

  • Kernel soft lockup or hung task warnings referencing dwc2_hsotg_udc_stop or dwc2_gadget_exit_clock_gating in dmesg.
  • Lockdep splats reporting spin_unlock on an unlocked lock within the dwc2 gadget driver call stack.
  • System stalls or unresponsive USB gadget operations during driver unbind or module removal.

Detection Strategies

  • Enable CONFIG_PROVE_LOCKING and CONFIG_DEBUG_SPINLOCK on test kernels to surface the lock state mismatch at runtime.
  • Audit running kernel versions across fleets and compare against the patched commit hashes published on kernel.org stable trees.
  • Correlate kernel log telemetry with USB gadget lifecycle events such as driver bind, unbind, and module unload.

Monitoring Recommendations

  • Forward kernel ring buffer messages to a centralized logging or SIEM platform to flag BUG:, WARNING:, and hung task entries originating from the dwc2 driver.
  • Monitor uptime and watchdog reset counters on embedded devices that rely on the dwc2 controller in gadget mode.
  • Track package and kernel version inventory to confirm patched builds are deployed on devices that load dwc2.ko.

How to Mitigate CVE-2026-31756

Immediate Actions Required

  • Update affected systems to a Linux kernel build that includes the upstream fix commits referenced on kernel.org.
  • For distribution kernels, apply the vendor-supplied stable backport as soon as it becomes available.
  • On embedded platforms, rebuild and flash kernel images that incorporate the patch before redeploying devices.

Patch Information

The fix was merged to mainline and backported to multiple stable branches. The relevant commits are 4ed9d2dd9f29, 51b62286fc66, 61937f686290, 8ffe31acb3b7, 9bb4b5ed7f8c, beab10429439, and e9fcca3e8746. The patch acquires hsotg->lock with spin_lock_irqsave() before calling dwc2_gadget_exit_clock_gating() and releases it with spin_unlock_irqrestore() afterward, fulfilling the locking contract expected by call_gadget().

Workarounds

  • Avoid unbinding the dwc2 gadget driver or unloading the dwc2 module on production systems running unpatched kernels.
  • Where the USB gadget functionality is not required, disable CONFIG_USB_DWC2_PERIPHERAL or build the controller in host-only mode to avoid the affected code path.
  • Restrict local access to systems where USB gadget reconfiguration could be performed by unprivileged automation.
bash
# Verify whether the running kernel includes one of the fix commits
uname -r
zcat /proc/config.gz | grep -E 'CONFIG_USB_DWC2|CONFIG_PROVE_LOCKING'
# Confirm the dwc2 module status
lsmod | grep dwc2

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.