[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <2a13ea1c-08df-4807-83d4-241831b7a2ec@squashfs.org.uk>
Date: Mon, 7 Apr 2025 06:30:35 +0100
From: Phillip Lougher <phillip@...ashfs.org.uk>
To: syzbot+65761fc25a137b9c8c6e@...kaller.appspotmail.com
Cc: linux-kernel@...r.kernel.org, phillip@...ashfs.org.uk,
squashfs-devel-owner@...ts.sourceforge.net,
squashfs-devel@...ts.sourceforge.net, syzkaller-bugs@...glegroups.com,
phillip.lougher@...il.com
Subject: Re: [syzbot] [squashfs?] UBSAN: shift-out-of-bounds in
squashfs_bio_read
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
Powered by blists - more mailing lists