• Alistair Popple's avatar
    mm/mmu_notifier.c: fix race in mmu_interval_notifier_remove() · 31956166
    Alistair Popple authored
    In some cases it is possible for mmu_interval_notifier_remove() to race
    with mn_tree_inv_end() allowing it to return while the notifier data
    structure is still in use.  Consider the following sequence:
    
      CPU0 - mn_tree_inv_end()            CPU1 - mmu_interval_notifier_remove()
      ----------------------------------- ------------------------------------
                                          spin_lock(subscriptions->lock);
                                          seq = subscriptions->invalidate_seq;
      spin_lock(subscriptions->lock);     spin_unlock(subscriptions->lock);
      subscriptions->invalidate_seq++;
                                          wait_event(invalidate_seq != seq);
                                          return;
      interval_tree_remove(interval_sub); kfree(interval_sub);
      spin_unlock(subscriptions->lock);
      wake_up_all();
    
    As the wait_event() condition is true it will return immediately.  This
    can lead to use-after-free type errors if the caller frees the data
    structure containing the interval notifier subscription while it is
    still on a deferred list.  Fix this by taking the appropriate lock when
    reading invalidate_seq to ensure proper synchronisation.
    
    I observed this whilst running stress testing during some development.
    You do have to be pretty unlucky, but it leads to the usual problems of
    use-after-free (memory corruption, kernel crash, difficult to diagnose
    WARN_ON, etc).
    
    Link: https://lkml.kernel.org/r/20220420043734.476348-1-apopple@nvidia.com
    Fixes: 99cb252f ("mm/mmu_notifier: add an interval tree notifier")
    Signed-off-by: default avatarAlistair Popple <apopple@nvidia.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
    Cc: Christian König <christian.koenig@amd.com>
    Cc: John Hubbard <jhubbard@nvidia.com>
    Cc: Ralph Campbell <rcampbell@nvidia.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    31956166
mmu_notifier.c 35.3 KB