Published: June 2024
Affected Component:
Linux Kernel video/aperture subsystem
Severity: Medium

Overview

A new Linux kernel vulnerability, CVE-2024-46698, was discovered and resolved in the video/aperture subsystem. This bug could lead to a kernel NULL pointer dereference when multiple GPUs are present, especially if the primary display device is not VGA compatible. In this post, we will break down what happened, how the bug could be triggered, share the affected code, and explain how the Linux kernel team fixed the problem.

Understanding the Vulnerability

The Linux kernel function aperture_remove_conflicting_pci_devices() is called during boot to remove any leftover framebuffer devices (so-called "conflicting" devices) before attaching a real GPU driver. As part of this cleanup, it sometimes disables the sysfb (system framebuffer), which is a simple framebuffer driver that helps computers display graphics in the early stages of boot.

What Was the Problem?

- When there are multiple GPUs, and the boot display is a non-VGA PCI device, the old logic only called sysfb_disable() for VGA class devices.
- So, the primary GPU (the one attached to the display at boot) didn’t trigger sysfb_disable(), but its resources were still freed by aperture_detach_platform_device().
- Later, a secondary VGA-compatible card *would* call sysfb_disable()—but because the resources had already been freed, this could cause a NULL pointer dereference (leading to a kernel panic).

How Could This Be Exploited?

This is a local denial of service vulnerability: an attacker with control over hardware or certain kernel parameters could trigger this crash during boot or module load, potentially making the system unbootable or unreliable.

Here’s a simplified example of the problematic code

void aperture_remove_conflicting_pci_devices(...) {
    struct pci_dev *pdev;

    list_for_each_entry(pdev, ...) {
        if (is_vga_device(pdev))
            sysfb_disable();
        // Removes sysfb *only* for VGA, and detaches resources anyway
        aperture_detach_platform_device();
    }
}

// Later, sysfb_disable() tries to access these freed resources!

If the primary GPU wasn’t VGA-class, sysfb_disable() would *not* be called right away. Its resources were freed, and later calling sysfb_disable() on another device would crash.

How Was It Fixed?

The solution: pass the current PCI device to sysfb_disable() so it can match the correct GPU/device reliably, avoiding double-free or use-after-free problems.

The Fix

- sysfb_disable() now takes a device pointer and checks if it should actually perform the disable operation for that device.

Relevant patch in pseudo-code

// Old:
if (is_vga_device(pdev))
    sysfb_disable();

// New:
sysfb_disable(pdev);  // Pass the device, inside mutex, check if needed

Snippet from the patch

static void sysfb_disable(struct device *dev)
{
    mutex_lock(&sysfb_lock);

    if (sysfb_device_matches(dev)) {
        // Safe to disable
        platform_device_unregister(sysfb_device);
        sysfb_device = NULL;
    }

    mutex_unlock(&sysfb_lock);
}

Reference:
- Linux Kernel Patch - “video/aperture: optionally match the device in sysfb_disable()”

You use a multi-GPU system where the primary GPU is not VGA-class.

- Your distribution uses a Linux kernel version prior to this fix (look for mainline versions from June 2024 and later for the patch).
- You see boot failures, kernel NULL dereferences, or related messages involving sysfb_disable() or graphics resource allocation.

Mitigation & Patch

Patching is recommended. Kernel maintainers have included this fix in all active branches.

Check your Linux distribution’s security advisories for CVE-2024-46698.

- Upstream commit / patch.
- If you build custom kernels, apply the patch manually or update to a kernel version with the fix.

Resources

- CVE-2024-46698 at NVD (placeholder, NVD may not have details yet)
- Original Kernel Patch Discussion (LKML)
- Aperture subsystem documentation

Summary

CVE-2024-46698 is a subtle bug in the Linux kernel’s video/aperture subsystem. It could cause your system to crash if you have non-VGA primary display hardware and multiple GPUs, because the framebuffer resources could be freed prematurely. The fix is in the latest kernels—make sure you update!


> Have questions or experiences with this bug? Leave a comment below or join the discussion on LKML.


*Stay safe, keep your kernels patched, and watch out for NULL pointers!*

Timeline

Published on: 09/13/2024 06:15:14 UTC
Last modified on: 09/13/2024 16:53:03 UTC