• Luis Henriques's avatar
    ceph: fix use-after-free in __ceph_remove_cap() · ea60ed6f
    Luis Henriques authored
    KASAN reports a use-after-free when running xfstest generic/531, with the
    following trace:
    
    [  293.903362]  kasan_report+0xe/0x20
    [  293.903365]  rb_erase+0x1f/0x790
    [  293.903370]  __ceph_remove_cap+0x201/0x370
    [  293.903375]  __ceph_remove_caps+0x4b/0x70
    [  293.903380]  ceph_evict_inode+0x4e/0x360
    [  293.903386]  evict+0x169/0x290
    [  293.903390]  __dentry_kill+0x16f/0x250
    [  293.903394]  dput+0x1c6/0x440
    [  293.903398]  __fput+0x184/0x330
    [  293.903404]  task_work_run+0xb9/0xe0
    [  293.903410]  exit_to_usermode_loop+0xd3/0xe0
    [  293.903413]  do_syscall_64+0x1a0/0x1c0
    [  293.903417]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    This happens because __ceph_remove_cap() may queue a cap release
    (__ceph_queue_cap_release) which can be scheduled before that cap is
    removed from the inode list with
    
    	rb_erase(&cap->ci_node, &ci->i_caps);
    
    And, when this finally happens, the use-after-free will occur.
    
    This can be fixed by removing the cap from the inode list before being
    removed from the session list, and thus eliminating the risk of an UAF.
    
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarLuis Henriques <lhenriques@suse.com>
    Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
    Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
    ea60ed6f
caps.c 115 KB