From: Alex Williamson Date: Mon, 30 May 2016 13:50:10 +0000 (-0600) Subject: vfio/pci: Fix ordering of eventfd vs virqfd shutdown X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=956b56a984ddf10aa69b25318dc04430101beed6;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git vfio/pci: Fix ordering of eventfd vs virqfd shutdown Both the INTx and MSI/X disable paths do an eventfd_ctx_put() for the trigger eventfd before calling vfio_virqfd_disable() any potential mask and unmask eventfds. This opens a use-after-free race where an inopportune irqfd can reference the freed signalling eventfd. Reorder to avoid this possibility. Signed-off-by: Alex Williamson --- diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index e9ea3fef144a..15ecfc9c5f6c 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c @@ -228,9 +228,9 @@ static int vfio_intx_set_signal(struct vfio_pci_device *vdev, int fd) static void vfio_intx_disable(struct vfio_pci_device *vdev) { - vfio_intx_set_signal(vdev, -1); vfio_virqfd_disable(&vdev->ctx[0].unmask); vfio_virqfd_disable(&vdev->ctx[0].mask); + vfio_intx_set_signal(vdev, -1); vdev->irq_type = VFIO_PCI_NUM_IRQS; vdev->num_ctx = 0; kfree(vdev->ctx); @@ -401,13 +401,13 @@ static void vfio_msi_disable(struct vfio_pci_device *vdev, bool msix) struct pci_dev *pdev = vdev->pdev; int i; - vfio_msi_set_block(vdev, 0, vdev->num_ctx, NULL, msix); - for (i = 0; i < vdev->num_ctx; i++) { vfio_virqfd_disable(&vdev->ctx[i].unmask); vfio_virqfd_disable(&vdev->ctx[i].mask); } + vfio_msi_set_block(vdev, 0, vdev->num_ctx, NULL, msix); + if (msix) { pci_disable_msix(vdev->pdev); kfree(vdev->msix);