Skip to content

Commit

Permalink
vfio/pci: Fix ordering of eventfd vs virqfd shutdown
Browse files Browse the repository at this point in the history
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 <alex.williamson@redhat.com>
  • Loading branch information
Alex Williamson committed May 30, 2016
1 parent 1a695a9 commit 956b56a
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions drivers/vfio/pci/vfio_pci_intrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 956b56a

Please sign in to comment.