• Chao Yu's avatar
    f2fs: fix to do sanity check on direct node in truncate_dnode() · a6ec8378
    Chao Yu authored
    syzbot reports below bug:
    
    BUG: KASAN: slab-use-after-free in f2fs_truncate_data_blocks_range+0x122a/0x14c0 fs/f2fs/file.c:574
    Read of size 4 at addr ffff88802a25c000 by task syz-executor148/5000
    
    CPU: 1 PID: 5000 Comm: syz-executor148 Not tainted 6.4.0-rc7-syzkaller-00041-ge660abd5 #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023
    Call Trace:
     <TASK>
     __dump_stack lib/dump_stack.c:88 [inline]
     dump_stack_lvl+0xd9/0x150 lib/dump_stack.c:106
     print_address_description.constprop.0+0x2c/0x3c0 mm/kasan/report.c:351
     print_report mm/kasan/report.c:462 [inline]
     kasan_report+0x11c/0x130 mm/kasan/report.c:572
     f2fs_truncate_data_blocks_range+0x122a/0x14c0 fs/f2fs/file.c:574
     truncate_dnode+0x229/0x2e0 fs/f2fs/node.c:944
     f2fs_truncate_inode_blocks+0x64b/0xde0 fs/f2fs/node.c:1154
     f2fs_do_truncate_blocks+0x4ac/0xf30 fs/f2fs/file.c:721
     f2fs_truncate_blocks+0x7b/0x300 fs/f2fs/file.c:749
     f2fs_truncate.part.0+0x4a5/0x630 fs/f2fs/file.c:799
     f2fs_truncate include/linux/fs.h:825 [inline]
     f2fs_setattr+0x1738/0x2090 fs/f2fs/file.c:1006
     notify_change+0xb2c/0x1180 fs/attr.c:483
     do_truncate+0x143/0x200 fs/open.c:66
     handle_truncate fs/namei.c:3295 [inline]
     do_open fs/namei.c:3640 [inline]
     path_openat+0x2083/0x2750 fs/namei.c:3791
     do_filp_open+0x1ba/0x410 fs/namei.c:3818
     do_sys_openat2+0x16d/0x4c0 fs/open.c:1356
     do_sys_open fs/open.c:1372 [inline]
     __do_sys_creat fs/open.c:1448 [inline]
     __se_sys_creat fs/open.c:1442 [inline]
     __x64_sys_creat+0xcd/0x120 fs/open.c:1442
     do_syscall_x64 arch/x86/entry/common.c:50 [inline]
     do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
     entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
    The root cause is, inodeA references inodeB via inodeB's ino, once inodeA
    is truncated, it calls truncate_dnode() to truncate data blocks in inodeB's
    node page, it traverse mapping data from node->i.i_addr[0] to
    node->i.i_addr[ADDRS_PER_BLOCK() - 1], result in out-of-boundary access.
    
    This patch fixes to add sanity check on dnode page in truncate_dnode(),
    so that, it can help to avoid triggering such issue, and once it encounters
    such issue, it will record newly introduced ERROR_INVALID_NODE_REFERENCE
    error into superblock, later fsck can detect such issue and try repairing.
    
    Also, it removes f2fs_truncate_data_blocks() for cleanup due to the
    function has only one caller, and uses f2fs_truncate_data_blocks_range()
    instead.
    
    Reported-and-tested-by: syzbot+12cb4425b22169b52036@syzkaller.appspotmail.com
    Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000f3038a05fef867f8@google.comSigned-off-by: default avatarChao Yu <chao@kernel.org>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
    a6ec8378
node.c 82.3 KB