• Radu Rendec's avatar
    powerpc/msi: Fix NULL pointer access in teardown code · 78e7b15e
    Radu Rendec authored
    The arch_teardown_msi_irqs() function assumes that controller ops
    pointers were already checked in arch_setup_msi_irqs(), but this
    assumption is wrong: arch_teardown_msi_irqs() can be called even when
    arch_setup_msi_irqs() returns an error (-ENOSYS).
    This can happen in the following scenario:
      - msi_capability_init() calls pci_msi_setup_msi_irqs()
      - pci_msi_setup_msi_irqs() returns -ENOSYS
      - msi_capability_init() notices the error and calls free_msi_irqs()
      - free_msi_irqs() calls pci_msi_teardown_msi_irqs()
    This is easier to see when CONFIG_PCI_MSI_IRQ_DOMAIN is not set and
    pci_msi_setup_msi_irqs() and pci_msi_teardown_msi_irqs() are just
    aliases to arch_setup_msi_irqs() and arch_teardown_msi_irqs().
    The call to free_msi_irqs() upon pci_msi_setup_msi_irqs() failure
    seems legit, as it does additional cleanup; e.g.
    list_del(&entry->list) and kfree(entry) inside free_msi_irqs() do
    happen (MSI descriptors are allocated before pci_msi_setup_msi_irqs()
    is called and need to be cleaned up if that fails).
    Fixes: 6b2fd7ef
     ("PCI/MSI/PPC: Remove arch_msi_check_device()")
    Cc: stable@vger.kernel.org # v3.18+
    Signed-off-by: default avatarRadu Rendec <radu.rendec@gmail.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
msi.c 1.17 KB