A Linux kernel vulnerability has been identified and resolved in the video/aperture module. This vulnerability could potentially allow an attacker to cause a NULL pointer dereference in certain situations, leading to a system crash or other unexpected behavior. This article will provide you with the details of the vulnerability, explain the code changes introduced to fix the issue, and include links to relevant references.

Exploit Details

The vulnerability lies in the aperture_remove_conflicting_pci_devices() function within the Linux kernel. The function is designed to deal with the situation where a PCI device with a non-VGA class is the boot display.

Originally, the aperture_remove_conflicting_pci_devices() function only called the sysfb_disable() function on VGA class devices. Due to this, when the primary device is not VGA compatible, the following problem occurs:

A PCI device with a non-VGA class is the boot display.

2. That device is probed first, and it is not a VGA device. Thus, sysfb_disable() is not called, but the device resources are freed by aperture_detach_platform_device().

Non-primary GPU has a VGA class and ultimately ends up calling sysfb_disable().

4. NULL pointer dereference occurs via sysfb_disable() since the resources have already been freed by aperture_detach_platform_device() when it was called by the other device.

To fix this vulnerability, a device pointer is passed to the sysfb_disable() function and a check is added to determine if the sysfb_disable() function should actually be executed or not.

The following code changes were introduced to fix this vulnerability

// Changed function signature to include device pointer
void __ref sysfb_disable(const struct pci_dev *dev) {

    mutex_lock(&x86_sysfb_lock);
    
    // New device check added
    if (x86_sysfb_device != dev)
        return;

    if (x86_sysfb_entry) {
         platform_device_unregister(x86_sysfb_device);
         x86_sysfb_entry = NULL;
         x86_sysfb_device = NULL;
         mutex_unlock(&x86_sysfb_lock);
    }
}

Additionally, the changes made in the aperture_remove_conflicting_pci_devices() function include

// Calling sysfb_disable() function with the device pointer.
aperture_remove_conflicting_pci_devices(const struct pci_dev *dev) {
    ...
    if (sysfb_pci_dev_is_enabled(dev))
    sysfb_disable(dev);
    ...
}

The original commit for this vulnerability fix can be found on the Linux kernel Git repository here

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e4d

The discussion and analysis of the vulnerability and its fix are available in the Linux Kernel Mailing List archives:
https://lkml.org/lkml/2021/6/28/1112

Conclusion

CVE-2024-46698 is a Linux kernel vulnerability that has been resolved by introducing a device pointer checks in the video/aperture module. This fix prevents NULL pointer dereference issues and ensures the stability and security of the Linux kernel. The code changes and the original discussion provide an excellent resource for understanding the vulnerability and the steps taken to address it, ultimately leading to a more robust and secure Linux environment.

Timeline

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