• Konrad Rzeszutek Wilk's avatar
    xen/pciback: Do not install an IRQ handler for MSI interrupts. · b5f917bf
    Konrad Rzeszutek Wilk authored
    commit a396f3a2 upstream.
    
    Otherwise an guest can subvert the generic MSI code to trigger
    an BUG_ON condition during MSI interrupt freeing:
    
     for (i = 0; i < entry->nvec_used; i++)
            BUG_ON(irq_has_action(entry->irq + i));
    
    Xen PCI backed installs an IRQ handler (request_irq) for
    the dev->irq whenever the guest writes PCI_COMMAND_MEMORY
    (or PCI_COMMAND_IO) to the PCI_COMMAND register. This is
    done in case the device has legacy interrupts the GSI line
    is shared by the backend devices.
    
    To subvert the backend the guest needs to make the backend
    to change the dev->irq from the GSI to the MSI interrupt line,
    make the backend allocate an interrupt handler, and then command
    the backend to free the MSI interrupt and hit the BUG_ON.
    
    Since the backend only calls 'request_irq' when the guest
    writes to the PCI_COMMAND register the guest needs to call
    XEN_PCI_OP_enable_msi before any other operation. This will
    cause the generic MSI code to setup an MSI entry and
    populate dev->irq with the new PIRQ value.
    
    Then the guest can write to PCI_COMMAND PCI_COMMAND_MEMORY
    and cause the backend to setup an IRQ handler for dev->irq
    (which instead of the GSI value has the MSI pirq). See
    'xen_pcibk_control_isr'.
    
    Then the guest disables the MSI: XEN_PCI_OP_disable_msi
    which ends up triggering the BUG_ON condition in 'free_msi_irqs'
    as there is an IRQ handler for the entry->irq (dev->irq).
    
    Note that this cannot be done using MSI-X as the generic
    code does not over-write dev->irq with the MSI-X PIRQ values.
    
    The patch inhibits setting up the IRQ handler if MSI or
    MSI-X (for symmetry reasons) code had been called successfully.
    
    P.S.
    Xen PCIBack when it sets up the device for the guest consumption
    ends up writting 0 to the PCI_COMMAND (see xen_pcibk_reset_device).
    XSA-120 addendum patch removed that - however when upstreaming said
    addendum we found that it caused issues with qemu upstream. That
    has now been fixed in qemu upstream.
    
    This is part of XSA-157
    Reviewed-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
    Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    b5f917bf
pciback_ops.c 11.2 KB