In the Linux kernel, the following vulnerability has been resolved:
ext4: fix slab-out-of-bounds in ext4mbfindgoodgroupavgfrag_lists()
We can trigger a slab-out-of-bounds with the following commands:
mkfs.ext4 -F /dev/$disk 10G
mount /dev/$disk /tmp/test
echo 2147483647 > /sys/fs/ext4/$disk/mb_group_prealloc
echo test > /tmp/test/file && sync
================================================================== BUG: KASAN: slab-out-of-bounds in ext4mbfindgoodgroupavgfraglists+0x8a/0x200 [ext4] Read of size 8 at addr ffff888121b9d0f0 by task kworker/u2:0/11 CPU: 0 PID: 11 Comm: kworker/u2:0 Tainted: GL 6.7.0-next-20240118 #521 Call Trace: dumpstacklvl+0x2c/0x50 kasanreport+0xb6/0xf0 ext4mbfindgoodgroupavgfraglists+0x8a/0x200 [ext4] ext4mbregularallocator+0x19e9/0x2370 [ext4] ext4mbnewblocks+0x88a/0x1370 [ext4] ext4extmapblocks+0x14f7/0x2390 [ext4] ext4mapblocks+0x569/0xea0 [ext4] ext4dowritepages+0x10f6/0x1bc0 [ext4]
The flow of issue triggering is as follows:
// Set smbgroupprealloc to 2147483647 via sysfs ext4mbnewblocks ext4mbnormalizerequest ext4mbnormalizegrouprequest ac->acgex.felen = EXT4SB(sb)->smbgroupprealloc ext4mbregularallocator ext4mbchoosenextgroup ext4mbchoosenextgroupbestavail mbavgfragmentsizeorder order = fls(len) - 2 = 29 ext4mbfindgoodgroupavgfraglists fraglist = &sbi->smbavgfragmentsize[order] if (listempty(frag_list)) // Trigger SOOB!
At 4k block size, the length of the smbavgfragmentsize list is 14, but an oversized smbgroup_prealloc is set, causing slab-out-of-bounds to be triggered by an attempt to access an element at index 29.
Add a new attrid attrclustersingroup with values in the range [0, sbi->sclusterspergroup] and declare mbgroupprealloc as that type to fix the issue. In addition avoid returning an order from mbavgfragmentsizeorder() greater than MBNUM_ORDERS(sb) and reduce some useless loops.