| From 5ea5880764cbb164afb17a62e76ca75dc371409d Mon Sep 17 00:00:00 2001 |
| From: Prasanna Kumar T S M <ptsm@linux.microsoft.com> |
| Date: Fri, 17 Apr 2026 14:27:56 -0600 |
| Subject: vfio/cdx: Fix NULL pointer dereference in interrupt trigger path |
| |
| From: Prasanna Kumar T S M <ptsm@linux.microsoft.com> |
| |
| commit 5ea5880764cbb164afb17a62e76ca75dc371409d upstream. |
| |
| Add validation to ensure MSI is configured before accessing cdx_irqs |
| array in vfio_cdx_set_msi_trigger(). Without this check, userspace |
| can trigger a NULL pointer dereference by calling VFIO_DEVICE_SET_IRQS |
| with VFIO_IRQ_SET_DATA_BOOL or VFIO_IRQ_SET_DATA_NONE flags before |
| ever setting up interrupts via VFIO_IRQ_SET_DATA_EVENTFD. |
| |
| The vfio_cdx_msi_enable() function allocates the cdx_irqs array and |
| sets config_msi to 1 only when called through the EVENTFD path. The |
| trigger loop (for DATA_BOOL/DATA_NONE) assumed this had already been |
| done, but there was no enforcement of this call ordering. |
| |
| This matches the protection used in the PCI VFIO driver where |
| vfio_pci_set_msi_trigger() checks irq_is() before the trigger loop. |
| |
| Fixes: 848e447e000c ("vfio/cdx: add interrupt support") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Prasanna Kumar T S M <ptsm@linux.microsoft.com> |
| Acked-by: Nipun Gupta <nipun.gupta@amd.com> |
| Signed-off-by: Alex Williamson <alex.williamson@nvidia.com> |
| Acked-by: Nikhil Agarwal <nikhil.agarwal@amd.com> |
| Link: https://lore.kernel.org/r/20260417202800.88287-2-alex.williamson@nvidia.com |
| Signed-off-by: Alex Williamson <alex@shazbot.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/vfio/cdx/intr.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/drivers/vfio/cdx/intr.c |
| +++ b/drivers/vfio/cdx/intr.c |
| @@ -177,6 +177,10 @@ static int vfio_cdx_set_msi_trigger(stru |
| return ret; |
| } |
| |
| + /* Ensure MSI is configured before accessing cdx_irqs */ |
| + if (!vdev->config_msi) |
| + return -EINVAL; |
| + |
| for (i = start; i < start + count; i++) { |
| if (!vdev->cdx_irqs[i].trigger) |
| continue; |