• Thomas Gleixner's avatar
    x86/irq: Clear move_in_progress before sending cleanup IPI · c1684f50
    Thomas Gleixner authored
    send_cleanup_vector() fiddles with the old_domain mask unprotected because it
    relies on the protection by the move_in_progress flag. But this is fatal, as
    the flag is reset after the IPI has been sent. So a cpu which receives the IPI
    can still see the flag set and therefor ignores the cleanup request. If no
    other cleanup request happens then the vector stays stale on that cpu and in
    case of an irq removal the vector still persists. That can lead to use after
    free when the next cleanup IPI happens.
    
    Protect the code with vector_lock and clear move_in_progress before sending
    the IPI.
    
    This does not plug the race which Joe reported because:
    
    CPU0                          CPU1                      CPU2
    lock_vector()
    data->move_in_progress=0
    sendIPI()                       
    unlock_vector()
                                  set_affinity()
                                  assign_irq_vector()
                                  lock_vector()             handle_IPI
                                  move_in_progress = 1      lock_vector()
                                  unlock_vector()
                                                            move_in_progress == 1
    
    The full fix comes with a later patch.
    Reported-and-tested-by: default avatarJoe Lawrence <joe.lawrence@stratus.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Tested-by: default avatarBorislav Petkov <bp@alien8.de>
    Cc: Jiang Liu <jiang.liu@linux.intel.com>
    Cc: Jeremiah Mahler <jmmahler@gmail.com>
    Cc: andy.shevchenko@gmail.com
    Cc: Guenter Roeck <linux@roeck-us.net>
    Cc: stable@vger.kernel.org #4.3+
    Link: http://lkml.kernel.org/r/20151231160106.892412198@linutronix.deSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    c1684f50
vector.c 20.6 KB