• Baokun Li's avatar
    ext4: fix use-after-free in ext4_xattr_set_entry · 67d7d8ad
    Baokun Li authored
    Hulk Robot reported a issue:
    ==================================================================
    BUG: KASAN: use-after-free in ext4_xattr_set_entry+0x18ab/0x3500
    Write of size 4105 at addr ffff8881675ef5f4 by task syz-executor.0/7092
    
    CPU: 1 PID: 7092 Comm: syz-executor.0 Not tainted 4.19.90-dirty #17
    Call Trace:
    [...]
     memcpy+0x34/0x50 mm/kasan/kasan.c:303
     ext4_xattr_set_entry+0x18ab/0x3500 fs/ext4/xattr.c:1747
     ext4_xattr_ibody_inline_set+0x86/0x2a0 fs/ext4/xattr.c:2205
     ext4_xattr_set_handle+0x940/0x1300 fs/ext4/xattr.c:2386
     ext4_xattr_set+0x1da/0x300 fs/ext4/xattr.c:2498
     __vfs_setxattr+0x112/0x170 fs/xattr.c:149
     __vfs_setxattr_noperm+0x11b/0x2a0 fs/xattr.c:180
     __vfs_setxattr_locked+0x17b/0x250 fs/xattr.c:238
     vfs_setxattr+0xed/0x270 fs/xattr.c:255
     setxattr+0x235/0x330 fs/xattr.c:520
     path_setxattr+0x176/0x190 fs/xattr.c:539
     __do_sys_lsetxattr fs/xattr.c:561 [inline]
     __se_sys_lsetxattr fs/xattr.c:557 [inline]
     __x64_sys_lsetxattr+0xc2/0x160 fs/xattr.c:557
     do_syscall_64+0xdf/0x530 arch/x86/entry/common.c:298
     entry_SYSCALL_64_after_hwframe+0x44/0xa9
    RIP: 0033:0x459fe9
    RSP: 002b:00007fa5e54b4c08 EFLAGS: 00000246 ORIG_RAX: 00000000000000bd
    RAX: ffffffffffffffda RBX: 000000000051bf60 RCX: 0000000000459fe9
    RDX: 00000000200003c0 RSI: 0000000020000180 RDI: 0000000020000140
    RBP: 000000000051bf60 R08: 0000000000000001 R09: 0000000000000000
    R10: 0000000000001009 R11: 0000000000000246 R12: 0000000000000000
    R13: 00007ffc73c93fc0 R14: 000000000051bf60 R15: 00007fa5e54b4d80
    [...]
    ==================================================================
    
    Above issue may happen as follows:
    -------------------------------------
    ext4_xattr_set
      ext4_xattr_set_handle
        ext4_xattr_ibody_find
          >> s->end < s->base
          >> no EXT4_STATE_XATTR
          >> xattr_check_inode is not executed
        ext4_xattr_ibody_set
          ext4_xattr_set_entry
           >> size_t min_offs = s->end - s->base
           >> UAF in memcpy
    
    we can easily reproduce this problem with the following commands:
        mkfs.ext4 -F /dev/sda
        mount -o debug_want_extra_isize=128 /dev/sda /mnt
        touch /mnt/file
        setfattr -n user.cat -v `seq -s z 4096|tr -d '[:digit:]'` /mnt/file
    
    In ext4_xattr_ibody_find, we have the following assignment logic:
      header = IHDR(inode, raw_inode)
             = raw_inode + EXT4_GOOD_OLD_INODE_SIZE + i_extra_isize
      is->s.base = IFIRST(header)
                 = header + sizeof(struct ext4_xattr_ibody_header)
      is->s.end = raw_inode + s_inode_size
    
    In ext4_xattr_set_entry
      min_offs = s->end - s->base
               = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
    	     sizeof(struct ext4_xattr_ibody_header)
      last = s->first
      free = min_offs - ((void *)last - s->base) - sizeof(__u32)
           = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
             sizeof(struct ext4_xattr_ibody_header) - sizeof(__u32)
    
    In the calculation formula, all values except s_inode_size and
    i_extra_size are fixed values. When i_extra_size is the maximum value
    s_inode_size - EXT4_GOOD_OLD_INODE_SIZE, min_offs is -4 and free is -8.
    The value overflows. As a result, the preceding issue is triggered when
    memcpy is executed.
    
    Therefore, when finding xattr or setting xattr, check whether
    there is space for storing xattr in the inode to resolve this issue.
    
    Cc: stable@kernel.org
    Reported-by: default avatarHulk Robot <hulkci@huawei.com>
    Signed-off-by: default avatarBaokun Li <libaokun1@huawei.com>
    Reviewed-by: default avatarRitesh Harjani (IBM) <ritesh.list@gmail.com>
    Reviewed-by: default avatarJan Kara <jack@suse.cz>
    Link: https://lore.kernel.org/r/20220616021358.2504451-3-libaokun1@huawei.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    67d7d8ad
xattr.c 81.7 KB