CVE-2024-26813 - Linux Kernel Vulnerability Resolved: Creating Persistent IRQ Handlers in VFIO/Platform

A recent CVE (Common Vulnerabilities and Exposures) report, CVE-2024-26813, has identified and resolved an issue within the Linux kernel. The vulnerability pertains specifically to the vfio/platform (Virtual Function I/O Platform) subsystem, where a NULL pointer dereference could occur due to loopback triggering of an interrupt before the user has configured a signaling eventfd. To address this issue, persistent IRQ handlers have been implemented within the vfio/platform subsystem.

Exploit Details

The vulnerability in question lies within the vfio/platform SET_IRQS ioctl. This functionality currently allows loopback triggering of an interrupt before the user configures a signaling eventfd, resulting in a NULL pointer dereference. The suggested resolution is to register all IRQs (interrupt requests) as disabled in the device open path. By doing so, it ensures that mask operations on the IRQ can nest within the overall enabled state that is governed by a valid eventfd signal.

The solution in question decouples @masked, which is protected by the @locked spinlock, from @trigger, protected via the @igate mutex. As a result, guaranteeing that changes to @trigger do not race the IRQ handlers, as the IRQ handler is synchronously disabled before modifying the trigger. Furthermore, loopback triggering of the IRQ via ioctl will be safe due to serialization with trigger changes using igate.

Code Snippet

The following code snippet demonstrates how this issue can be resolved by implementing the suggested changes:

/* Register IRQs as disabled during the device open path */
irq_bypass_producer_unregister(hardware->bypass);
if (hardware->irq_trigger[action->index])
       disable_irq(hardware->irq_set[action->index]);
spin_lock_irqsave(&hardware->locked, flags);
hardware->masked[action->index] = true;
spin_unlock_irqrestore(&hardware->locked, flags);
mutex_unlock(&hardware->igate);

Compatibility

It's important to note that the resolution, as demonstrated in the code snippet above, has taken compatibility into account. The request_irq() failures will be maintained as local to the SET_IRQS ioctl rather than a fatal error in the open device path. This ensures that a userspace driver with polling mode support can continue working even as the request_irq() call site is relocated. As a result, all SET_IRQS access to the failed index will be necessarily blocked.

Original References

1. Linux Kernel Git Commit
2. CVE-2024-26813

Conclusion

CVE-2024-26813 addresses a vulnerability within the Linux kernel's vfio/platform subsystem as well as provides an essential fix to ensure reliable functionality within the affected area. By registering IRQs in a disabled state during the device open path, this vulnerability's risk is mitigated, leading to a more robust and secure kernel performance. Make sure to stay up-to-date with the latest kernel releases and security patches to best protect your systems from exploits and vulnerabilities.

Timeline

Published on: 04/05/2024 09:15:09 UTC
Last modified on: 12/19/2024 08:47:58 UTC