• David Howells's avatar
    afs: Fix use-after-free due to get/remove race in volume tree · 9a6b294a
    David Howells authored
    When an afs_volume struct is put, its refcount is reduced to 0 before
    the cell->volume_lock is taken and the volume removed from the
    cell->volumes tree.
    
    Unfortunately, this means that the lookup code can race and see a volume
    with a zero ref in the tree, resulting in a use-after-free:
    
        refcount_t: addition on 0; use-after-free.
        WARNING: CPU: 3 PID: 130782 at lib/refcount.c:25 refcount_warn_saturate+0x7a/0xda
        ...
        RIP: 0010:refcount_warn_saturate+0x7a/0xda
        ...
        Call Trace:
         afs_get_volume+0x3d/0x55
         afs_create_volume+0x126/0x1de
         afs_validate_fc+0xfe/0x130
         afs_get_tree+0x20/0x2e5
         vfs_get_tree+0x1d/0xc9
         do_new_mount+0x13b/0x22e
         do_mount+0x5d/0x8a
         __do_sys_mount+0x100/0x12a
         do_syscall_64+0x3a/0x94
         entry_SYSCALL_64_after_hwframe+0x62/0x6a
    
    Fix this by:
    
     (1) When putting, use a flag to indicate if the volume has been removed
         from the tree and skip the rb_erase if it has.
    
     (2) When looking up, use a conditional ref increment and if it fails
         because the refcount is 0, replace the node in the tree and set the
         removal flag.
    
    Fixes: 20325960 ("afs: Reorganise volume and server trees to be rooted on the cell")
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    Reviewed-by: default avatarJeffrey Altman <jaltman@auristor.com>
    cc: Marc Dionne <marc.dionne@auristor.com>
    cc: linux-afs@lists.infradead.org
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    9a6b294a
volume.c 10.9 KB