• Dominique Martinet's avatar
    9p: add missing locking around taking dentry fid list · c898afdc
    Dominique Martinet authored
    Fix a use-after-free on dentry's d_fsdata fid list when a thread
    looks up a fid through dentry while another thread unlinks it:
    
    UAF thread:
    refcount_t: addition on 0; use-after-free.
     p9_fid_get linux/./include/net/9p/client.h:262
     v9fs_fid_find+0x236/0x280 linux/fs/9p/fid.c:129
     v9fs_fid_lookup_with_uid linux/fs/9p/fid.c:181
     v9fs_fid_lookup+0xbf/0xc20 linux/fs/9p/fid.c:314
     v9fs_vfs_getattr_dotl+0xf9/0x360 linux/fs/9p/vfs_inode_dotl.c:400
     vfs_statx+0xdd/0x4d0 linux/fs/stat.c:248
    
    Freed by:
     p9_fid_destroy (inlined)
     p9_client_clunk+0xb0/0xe0 linux/net/9p/client.c:1456
     p9_fid_put linux/./include/net/9p/client.h:278
     v9fs_dentry_release+0xb5/0x140 linux/fs/9p/vfs_dentry.c:55
     v9fs_remove+0x38f/0x620 linux/fs/9p/vfs_inode.c:518
     vfs_unlink+0x29a/0x810 linux/fs/namei.c:4335
    
    The problem is that d_fsdata was not accessed under d_lock, because
    d_release() normally is only called once the dentry is otherwise no
    longer accessible but since we also call it explicitly in v9fs_remove
    that lock is required:
    move the hlist out of the dentry under lock then unref its fids once
    they are no longer accessible.
    
    Fixes: 154372e6 ("fs/9p: fix create-unlink-getattr idiom")
    Cc: stable@vger.kernel.org
    Reported-by: Meysam Firouzi
    Reported-by: Amirmohammad Eftekhar
    Reviewed-by: default avatarChristian Schoenebeck <linux_oss@crudebyte.com>
    Message-ID: <20240521122947.1080227-1-asmadeus@codewreck.org>
    Signed-off-by: default avatarDominique Martinet <asmadeus@codewreck.org>
    c898afdc
vfs_dentry.c 2.5 KB