[syzbot] [squashfs?] UBSAN: shift-out-of-bounds in squashfs_bio_read

4 views
Skip to first unread message

syzbot

unread,
Apr 5, 2025, 3:36:28 AM4/5/25
to linux-...@vger.kernel.org, phi...@squashfs.org.uk, squashf...@lists.sourceforge.net, syzkall...@googlegroups.com
Hello,

syzbot found the following issue on:

HEAD commit: 609706855d90 Merge tag 'trace-latency-v6.15-3' of git://gi..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=12a88fb0580000
kernel config: https://syzkaller.appspot.com/x/.config?x=f8721be6a767792
dashboard link: https://syzkaller.appspot.com/bug?extid=65761fc25a137b9c8c6e
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40

Unfortunately, I don't have any reproducer for this issue yet.

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/48bd65025d89/disk-60970685.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/332202d68035/vmlinux-60970685.xz
kernel image: https://storage.googleapis.com/syzbot-assets/1c4aa49d3e14/bzImage-60970685.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+65761f...@syzkaller.appspotmail.com

loop0: detected capacity change from 0 to 8
------------[ cut here ]------------
UBSAN: shift-out-of-bounds in fs/squashfs/block.c:195:36
shift exponent 64 is too large for 64-bit type 'u64' (aka 'unsigned long long')
CPU: 0 UID: 0 PID: 6373 Comm: syz.0.109 Not tainted 6.14.0-syzkaller-11125-g609706855d90 #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
ubsan_epilogue lib/ubsan.c:231 [inline]
__ubsan_handle_shift_out_of_bounds+0x3c8/0x420 lib/ubsan.c:492
squashfs_bio_read+0x1050/0x1180 fs/squashfs/block.c:195
squashfs_read_data+0x2e7/0xba0 fs/squashfs/block.c:333
squashfs_read_table+0x338/0x390 fs/squashfs/cache.c:436
squashfs_fill_super+0x238/0x21e0 fs/squashfs/super.c:216
get_tree_bdev_flags+0x492/0x5c0 fs/super.c:1636
vfs_get_tree+0x92/0x2b0 fs/super.c:1759
do_new_mount+0x2cf/0xb70 fs/namespace.c:3878
do_mount fs/namespace.c:4218 [inline]
__do_sys_mount fs/namespace.c:4429 [inline]
__se_sys_mount+0x38c/0x400 fs/namespace.c:4406
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f229398e90a
Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb a6 e8 de 1a 00 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f2294866e68 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 00007f2294866ef0 RCX: 00007f229398e90a
RDX: 0000200000000040 RSI: 0000200000000240 RDI: 00007f2294866eb0
RBP: 0000200000000040 R08: 00007f2294866ef0 R09: 0000000000210c00
R10: 0000000000210c00 R11: 0000000000000246 R12: 0000200000000240
R13: 00007f2294866eb0 R14: 00000000000001ad R15: 0000200000001480
</TASK>
---[ end trace ]---


---
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 syzk...@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

syzbot

unread,
Apr 5, 2025, 11:37:28 PM4/5/25
to linux-...@vger.kernel.org, phi...@squashfs.org.uk, squashfs-d...@lists.sourceforge.net, squashf...@lists.sourceforge.net, syzkall...@googlegroups.com
syzbot has found a reproducer for the following issue on:

HEAD commit: 56f944529ec2 Merge tag 'input-for-v6.15-rc0' of git://git...
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=167eab4c580000
kernel config: https://syzkaller.appspot.com/x/.config?x=f2054704dd53fb80
dashboard link: https://syzkaller.appspot.com/bug?extid=65761fc25a137b9c8c6e
compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1775dd98580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=113787e4580000

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/7feb34a89c2a/non_bootable_disk-56f94452.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/c6da83e5191b/vmlinux-56f94452.xz
kernel image: https://storage.googleapis.com/syzbot-assets/5c060438ea13/bzImage-56f94452.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/f9d150e929ed/mount_0.gz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+65761f...@syzkaller.appspotmail.com

loop0: detected capacity change from 0 to 8
------------[ cut here ]------------
UBSAN: shift-out-of-bounds in fs/squashfs/block.c:195:36
shift exponent 64 is too large for 64-bit type 'u64' (aka 'unsigned long long')
CPU: 0 UID: 0 PID: 5472 Comm: syz-executor224 Not tainted 6.14.0-syzkaller-13443-g56f944529ec2 #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
ubsan_epilogue lib/ubsan.c:231 [inline]
__ubsan_handle_shift_out_of_bounds+0x3c8/0x420 lib/ubsan.c:492
squashfs_bio_read+0xf7e/0x10b0 fs/squashfs/block.c:195
squashfs_read_data+0x2e7/0xba0 fs/squashfs/block.c:333
squashfs_read_table+0x338/0x390 fs/squashfs/cache.c:436
squashfs_fill_super+0x238/0x21e0 fs/squashfs/super.c:216
get_tree_bdev_flags+0x490/0x5c0 fs/super.c:1636
vfs_get_tree+0x90/0x2b0 fs/super.c:1759
do_new_mount+0x2cf/0xb70 fs/namespace.c:3879
do_mount fs/namespace.c:4219 [inline]
__do_sys_mount fs/namespace.c:4430 [inline]
__se_sys_mount+0x38c/0x400 fs/namespace.c:4407
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fbefca8001a
Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb a6 e8 5e 04 00 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 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:00007ffcb4b512c8 EFLAGS: 00000282 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 00007ffcb4b512e0 RCX: 00007fbefca8001a
RDX: 0000200000000240 RSI: 0000200000000280 RDI: 00007ffcb4b512e0
RBP: 0000200000000280 R08: 00007ffcb4b51320 R09: 0000000000000220
R10: 0000000000000000 R11: 0000000000000282 R12: 0000200000000240
R13: 00007ffcb4b51320 R14: 0000000000000003 R15: 0000000000000000
</TASK>
---[ end trace ]---


---
If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

Phillip Lougher

unread,
Apr 7, 2025, 1:31:37 AM4/7/25
to syzbot+65761f...@syzkaller.appspotmail.com, linux-...@vger.kernel.org, phi...@squashfs.org.uk, squashfs-d...@lists.sourceforge.net, squashf...@lists.sourceforge.net, syzkall...@googlegroups.com, phillip...@gmail.com
I have spent most of Sunday on this syzbot issue, because it is one of
those PITAs, which are difficult to reproduce, and are full of red
herrings.

Firstly, this issue has nothing to do with corrupted Squashfs
filesystems. This is the because the failure occurs before the Squashfs
filesystem superblock has been read, and thus filesystem corruption
doesn't come into it. Thus the source of the failure is elsewhere in
the obfusticated auto-generated C reproducer.

Digging deeper into the reproducer, it turns out the reproducer is
forking multiple processes which after mounting the Squashfs filesystem,
issues a LOOP_SET_BLOCK_SIZE(r0, 0x4c09, 0x8000) ioctl on loopback
device /dev/loop0. Now, if this ioctl occurs at the same time another
process is in the process of mounting a Squashfs filesystem on
/dev/loop0, the failure occurs. The ioctl has to be issued in the
early part of squashfs_fill_super() before the superblock has been read.
When this happens, the following code in squashfs_fill_super() fails.

----
msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
msblk->devblksize_log2 = ffz(~msblk->devblksize);
----

sb_min_blocksize() returns 0, which means msblk->devblksize is set to 0.

As a result, ffz(~msblk->devblksize) returns 64, and
msblk->devblksize_log2 is set to 64.

This subsequently causes the

UBSAN: shift-out-of-bounds in fs/squashfs/block.c:195:36
shift exponent 64 is too large for 64-bit type 'u64' (aka 'unsigned long long')

The fix is to check for a 0 return by sb_min_blocksize().

I'll send a patch tomorrow.

Phillip

Phillip Lougher

unread,
Apr 8, 2025, 12:19:09 AM4/8/25
to syzbot+65761f...@syzkaller.appspotmail.com, linux-...@vger.kernel.org, squashfs-d...@lists.sourceforge.net, squashf...@lists.sourceforge.net, syzkall...@googlegroups.com, phillip...@gmail.com, Luis Chamberlain
On 07/04/2025 06:30, Phillip Lougher wrote:

> Digging deeper into the reproducer, it turns out the reproducer is
> forking multiple processes which after mounting the Squashfs filesystem,
> issues a LOOP_SET_BLOCK_SIZE(r0, 0x4c09, 0x8000) ioctl on loopback
> device /dev/loop0.  Now, if this ioctl occurs at the same time another
> process is in the process of mounting a Squashfs filesystem on
> /dev/loop0, the failure occurs.   The ioctl has to be issued in the
> early part of squashfs_fill_super() before the superblock has been read.
> When this happens, the following code in squashfs_fill_super() fails.
>
> ----
> msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
> msblk->devblksize_log2 = ffz(~msblk->devblksize);
> ----
>
> sb_min_blocksize() returns 0, which means msblk->devblksize is set to 0.

CC'ing Luis Chamberlain <mcg...@kernel.org>

Doing some more digging, what has changed to cause this failure, is a
post 6.14 change in the behaviour of the LOOP_SET_BLOCK_SIZE ioctl.

Doing a git bisect, prior to commit 47dd67532303803a87f43195e088b3b4bcf0454d
Author: Luis Chamberlain <mcg...@kernel.org>
block/bdev: lift block size restrictions to 64k

Attempts to set the loopback device block size to 0x8000 (32768) failed.
After the above commit, such attempts succeed. Having done so, this
causes the above sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE) to fail.

This may be an unanticipated side effect of the change.

Checking the kernel code six filesystems fail to check the return
result of sb_min_blocksize (isofs, gfs2, exfat, fat, squashfs and xfs),
and so will be affected by this change.

But notwithstanding the above, the failure to check the return result of
sb_min_blocksize() in Squashfs is a bug, and I will send a patch that
fixes this and the syzbot exploit. Hopefully this will be tomorrow.

Phillip
Reply all
Reply to author
Forward
0 new messages