• Thomas Gleixner's avatar
    x86/apic/vector: Force interupt handler invocation to irq context · 008f1d60
    Thomas Gleixner authored
    Sathyanarayanan reported that the PCI-E AER error injection mechanism
    can result in a NULL pointer dereference in apic_ack_edge():
    
     BUG: unable to handle kernel NULL pointer dereference at 0000000000000078
     RIP: 0010:apic_ack_edge+0x1e/0x40
     Call Trace:
       handle_edge_irq+0x7d/0x1e0
       generic_handle_irq+0x27/0x30
       aer_inject_write+0x53a/0x720
    
    It crashes in irq_complete_move() which dereferences get_irq_regs() which
    is obviously NULL when this is called from non interrupt context.
    
    Of course the pointer could be checked, but that just papers over the real
    issue. Invoking the low level interrupt handling mechanism from random code
    can wreckage the fragile interrupt affinity mechanism of x86 as interrupts
    can only be moved in interrupt context or with special care when a CPU goes
    offline and the move has to be enforced.
    
    In the best case this triggers the warning in the MSI affinity setter, but
    if the call happens on the correct CPU it just corrupts state and might
    prevent further interrupt delivery for the affected device.
    
    Mark the APIC interrupts as unsuitable for being invoked in random contexts.
    
    This prevents the AER injection from proliferating the wreckage, but that's
    less broken than the current state of affairs and more correct than just
    papering over the problem by sprinkling random checks all over the place
    and silently corrupting state.
    
    Reported-by: sathyanarayanan.kuppuswamy@linux.intel.com
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Link: https://lkml.kernel.org/r/20200306130623.684591280@linutronix.de
    008f1d60
vector.c 33.2 KB