On June 2024, a new security vulnerability was uncovered and patched in the Linux kernel's USB subsystem. Tagged as CVE-2024-53070, this issue could cause a system crash (kernel oops or panic) when the device is improperly accessed during system suspend, especially if the device was already runtime suspended. In this article, let’s break down what went wrong, the technical details, and how it was fixed—with easy-to-understand language and real code snippets.

What Is dwc3 in Linux?

The dwc3 driver supports the DesignWare USB 3. controllers, a widely used USB controller IP in many ARM-based SoCs. It’s responsible for initializing, suspending, and resetting the USB hardware.

What Happened? (The Bug)

When the operating system is preparing to enter *system suspend* (like sleep or hibernate), it must also save or stop hardware safely. But, if the dwc3 device had already been 'runtime suspended' (a low-power state), forcing a register access crashes the system—because the hardware is no longer reachable.

This meant:

Linux kernel could crash at system suspend if the device was already runtime suspended.

- The crash (a NULL pointer dereference or similar) could be triggered just by having the driver enabled and the system suspending.

Summary: Accessing controller registers after they’ve gone offline isn't safe!

The problematic code was in the dwc3 USB core driver's suspend handler

static int dwc3_suspend(struct device *dev)
{
    struct dwc3 *dwc = dev_get_drvdata(dev);

    /* Dangerous: Accessing registers after they're off */
    dwc3_enable_susphy(dwc);

    dwc3_core_exit(dwc);

    /* It's not safe to touch registers below this point on some platforms! */
    /* ... */
}

During system suspend:
- If the device is runtime suspended, its memory/registers are not accessible.

The Patch (How It Was Fixed)

You can see the official fix here.

The call to dwc3_enable_susphy() was moved to *before* any registers could become unsafe.

- Additional checks were added so that code wouldn’t touch registers if the device was already suspended.

Patched Code

static int dwc3_suspend(struct device *dev)
{
    struct dwc3 *dwc = dev_get_drvdata(dev);

    /* SUSPHY must be enabled while registers are still accessible */
    dwc3_enable_susphy(dwc);

    /* Now it's safe to exit core, which could make registers inaccessible */
    dwc3_core_exit(dwc);

    /* Avoid register access beyond this point */
    /* ... */
}

Full diff here (git.kernel.org)

Exploit Details

While this is not a classic remote or privilege escalation vulnerability, it can be exploited for a Denial of Service (DoS):
- Any user or process with echo mem > /sys/power/state (i.e., system suspend/hibernate permission) can *reliably* crash the host system if the driver is loaded and the device is already runtime suspended.

This could be used in virtualized or embedded devices to take systems offline.

No special hardware is required—just kernel/driver config, and the conditions above.

How To Patch

1. Update your Linux kernel to the latest version including commit 1533bf41f45.

References

- Official Kernel Patch
- CVE-2024-53070 at CVE.org *(may take time to populate)*
- Linux dwc3 driver source tree

Summary

CVE-2024-53070 is a classic “suspend resume” bug: the kernel code assumed hardware registers (memory-mapped I/O) were always available, but after runtime suspend or hardware core exit, this isn’t true. Abuse or accidents could crash Linux systems through USB subsystem, creating an “easy DoS.”

If you run Linux and USB matters to you, update soon!


*Feel free to share or discuss further. Stay safe!*

Timeline

Published on: 11/19/2024 18:15:26 UTC
Last modified on: 12/19/2024 09:38:25 UTC