[Cluster-devel] [syzbot] UBSAN: shift-out-of-bounds in init_sb (3)
Hello, syzbot found the following issue on: HEAD commit:200e340f2196 Merge tag 'pull-work.dcache' of git://git.ker.. git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=150cbda908 kernel config: https://syzkaller.appspot.com/x/.config?x=1b664fba5e66c4bf dashboard link: https://syzkaller.appspot.com/bug?extid=dcf33a7aae997956fe06 compiler: Debian clang version 13.0.1-++20220126092033+75e33f71c2da-1~exp1~20220126212112.63, GNU ld (GNU Binutils for Debian) 2.35.2 Unfortunately, I don't have any reproducer for this issue yet. IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+dcf33a7aae997956f...@syzkaller.appspotmail.com loop1: detected capacity change from 0 to 37440 gfs2: fsid=syz:syz: Trying to join cluster "lock_nolock", "syz:syz" gfs2: fsid=syz:syz: Now mounting FS (format 1801)... UBSAN: shift-out-of-bounds in fs/gfs2/ops_fstype.c:297:19 shift exponent 50331651 is too large for 64-bit type 'unsigned long' CPU: 0 PID: 30381 Comm: syz-executor.1 Not tainted 5.19.0-syzkaller-02972-g200e340f2196 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e3/0x2cb lib/dump_stack.c:106 ubsan_epilogue lib/ubsan.c:151 [inline] __ubsan_handle_shift_out_of_bounds+0x3a6/0x420 lib/ubsan.c:322 gfs2_read_sb fs/gfs2/ops_fstype.c:297 [inline] init_sb+0x11d6/0x12c0 fs/gfs2/ops_fstype.c:487 gfs2_fill_super+0x1a3c/0x2750 fs/gfs2/ops_fstype.c:1209 get_tree_bdev+0x400/0x620 fs/super.c:1292 gfs2_get_tree+0x50/0x210 fs/gfs2/ops_fstype.c:1325 vfs_get_tree+0x88/0x270 fs/super.c:1497 do_new_mount+0x289/0xad0 fs/namespace.c:3040 do_mount fs/namespace.c:3383 [inline] __do_sys_mount fs/namespace.c:3591 [inline] __se_sys_mount+0x2e3/0x3d0 fs/namespace.c:3568 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x2b/0x70 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7fc20ac8a7aa Code: 48 c7 c2 b8 ff ff ff f7 d8 64 89 02 b8 ff ff ff ff eb d2 e8 b8 04 00 00 0f 1f 84 00 00 00 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:7fc20be95f88 EFLAGS: 0202 ORIG_RAX: 00a5 RAX: ffda RBX: 2200 RCX: 7fc20ac8a7aa RDX: 2000 RSI: 2100 RDI: 7fc20be95fe0 RBP: 7fc20be96020 R08: 7fc20be96020 R09: 2000 R10: R11: 0202 R12: 2000 R13: 2100 R14: 7fc20be95fe0 R15: 20047a20 --- This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkal...@googlegroups.com. syzbot will keep track of this issue. See: https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
[Cluster-devel] [PATCH] gfs2: Check sb_bsize_shift after reading superblock
Fuzzers like to scribble over sb_bsize_shift but in reality it's very unlikely that this field would be corrupted on its own. Nevertheless it should be checked to avoid the possibility of messy mount errors due to bad calculations. It's always a fixed value based on the block size so we can just check that it's the expected value. Tested with: mkfs.gfs2 -O -p lock_nolock /dev/vdb for i in 0 -1 64 65 32 33; do gfs2_edit -p sb field sb_bsize_shift $i /dev/vdb mount /dev/vdb /mnt/test && umount /mnt/test done Before this patch we get a withdraw after [ 76.413681] gfs2: fsid=loop0.0: fatal: invalid metadata block [ 76.413681] bh = 19 (type: exp=5, found=4) [ 76.413681] function = gfs2_meta_buffer, file = fs/gfs2/meta_io.c, line = 492 and with UBSAN configured we also get complaints like [ 76.373395] UBSAN: shift-out-of-bounds in fs/gfs2/ops_fstype.c:295:19 [ 76.373815] shift exponent 4294967287 is too large for 64-bit type 'long unsigned int' After the patch, these complaints don't appear, mount fails immediately and we get an explanation in dmesg. Reported-by: syzbot+dcf33a7aae997956f...@syzkaller.appspotmail.com Signed-off-by: Andrew Price --- fs/gfs2/ops_fstype.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 549879929c84..692e27f8f563 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -178,7 +178,10 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent) pr_warn("Invalid block size\n"); return -EINVAL; } - + if (sb->sb_bsize_shift != ffs(sb->sb_bsize) - 1) { + pr_warn("Invalid block size shift\n"); + return -EINVAL; + } return 0; } -- 2.37.1