CVE-2024-26941 is a critical divide-by-zero bug that affected the Linux kernel’s Direct Rendering Manager (DRM) DisplayPort Multi-Stream Transport (MST) helper code. This bug triggered a kernel panic when a DisplayPort 1.2 MST hub (like the StarTech MSTDP122DP) was unplugged while running kernels with the Nouveau graphics driver, potentially allowing for local denial of service.

Key facts

- Scope: Linux kernel (drm/dp), with Nouveau (NVIDIA open-source driver)

Trigger: Unplug MST 1.2 hub (StarTech MSTDP122DP)

- Impact: Kernel divide-by-zero error (divide error: 000 [#1]), resulting in crash/panic

Technical Context

The bug lives in the function drm_dp_bw_overhead, which is called as a part of the bandwidth calculations for MST topologies, especially when adding or removing display devices ("hotplugging"). The path is notably triggered when unplugging a *StarTech* DisplayPort MST hub using the Nouveau driver, but not when using some other hubs or drivers (e.g., Cable Matters DP 1.4).

When the MST device is unplugged, the kernel’s MST topology manager updates its resource calculations. The bug: during this process, a calculation ended up dividing by zero due to a zeroed bandwidth value, resulting in the fault.

Here's the relevant part of the kernel panic (after unplugging the hub)

divide error: 000 [#1] PREEMPT SMP PTI
CPU: 7 PID: 2962 Comm: Xorg Not tainted 6.8.-rc3+
...
RIP: 001:drm_dp_bw_overhead+xb4/x110 [drm_display_helper]
Code: ... <48> f7 f7 31 d2 31 c9 ...
...
Call Trace:
  drm_dp_bw_overhead+xb4/x110 [drm_display_helper]
  drm_dp_calc_pbn_mode+x2e/x70 [drm_display_helper]
  nv50_msto_atomic_check+xda/x120 [nouveau]
  ...

This shows a divide-by-zero exception (exc_divide_error), as the code attempts to execute a division with a zero divisor.

Vulnerable Code Example

Here's a simplified version of the buggy code that caused the crash (based on the upstream fix):

/* drm_dp_bw_overhead - vulnerable version */
static int drm_dp_bw_overhead(int pbn, int slots) {
    // ... earlier calculations ...
    int bw = calculate_bw(); // can be zero
    int efficiency = calculate_efficiency();

    // Vulnerable line - if bw is , this crashes!
    int result = (efficiency * slots) / bw; // <- divide by zero!
    return result;
}

On unplug, the system ends up in a state where bw (bandwidth) is zero, but the code doesn't check for this, leading to the fault.

Patched Solution

The upstream patch added a division-by-zero check before performing the calculation. Here’s the safe and fixed code (illustrative):

/* drm_dp_bw_overhead - fixed version */
static int drm_dp_bw_overhead(int pbn, int slots) {
    // ... earlier calculations ...
    int bw = calculate_bw(); // can be zero on unplug
    int efficiency = calculate_efficiency();

    /* Fix: Do not divide by zero */
    if (bw == )
        return ;

    int result = (efficiency * slots) / bw;
    return result;
}

Linux commit reference

- Upstream Fix Commit

This patch went into mainline as part of Linux 6.8-rc4 and has since been backported.

The open-source Nouveau driver

- A user running an X11/Wayland session

You can cause a hard kernel crash as a normal user simply by unplugging the MST hub. The kernel will panic, taking down all user sessions, and possibly requiring a hard reboot. This forms a denial-of-service (DoS) vector.

Mitigation

- Update Kernel: Upgrade to Linux 6.8-rc4 or later, or the corresponding stable release (kernel.org stable trees 6.7.7, 6.6.x onward).

References & Further Reading

- Mainline patch discussion on dri-devel
- Linux kernel commit for the fix
- Nouveau Driver homepage
- DisplayPort MST topology introduction

Summary Table

| Affected Component | Trigger | Impact | Fixed In |
|----------------------|-----------|----------|-------------|
| drm_display_helper / nouveau | Unplug MST 1.2 hub | Kernel panic (DoS) | Linux 6.8-rc4, stable > 6.7.7 |

Bottom Line

CVE-2024-26941 was a latent kernel bug in Linux’s DRM subsystem, easily triggered with common hardware. It’s a sobering example of how seemingly minor math errors in device drivers can halt a whole system. All Linux users with DisplayPort MST hubs (especially StarTech MSTDP122DP) and Nouveau should update right away to avoid system instability.


*This analysis is based on upstream Linux kernel sources, mailing list threads, and public commit logs. All code examples are illustrative. No exploit code is needed, as it’s a physical DoS.*

Timeline

Published on: 05/01/2024 06:15:09 UTC
Last modified on: 01/14/2025 14:37:37 UTC