In the Linux kernel, the following vulnerability has been resolved:
btrfs: lzo: reject inline extents without valid headers
[BUG] For a crafted btrfs image, the following KASAN can be triggered when reading an inline lzo compressed file extent:
BUG: KASAN: slab-out-of-bounds in lzodecompress+0x57d/0x700 Read of size 4 at addr ffff888006f2e644 by task btrfslzo_inlin/77
Call Trace: <TASK> dumpstacklvl+0x5b/0x70 printreport+0xd1/0x610 kasanreport+0xe0/0x110 __asanreportloadnnoabort+0x13/0x20 lzodecompress+0x57d/0x700 btrfsdecompress+0x140/0x1c0 uncompressinline+0x147/0x1b0 btrfsgetextent+0xb23/0x10a0 btrfsdoreadpage.constprop.0+0x538/0x1ac0 btrfsreadahead+0x32f/0x5f0 readpages+0x16f/0x850 pagecacheraunbounded+0x296/0x490 dopagecachera+0xd9/0x130 pagecachesyncra+0x3ee/0x6f0 filemapgetpages+0x306/0x15c0 filemapread+0x329/0xd00 btrfsfilereaditer+0x1f8/0x2b0 vfsread+0x4ef/0x720 ksysread+0xf8/0x1d0 __x64sysread+0x71/0xb0 x64syscall+0x1ab0/0x1b70 dosyscall64+0x61/0x470 entrySYSCALL64afterhwframe+0x4b/0x53 </TASK>
[CAUSE] For an inline lzo compressed file extent, there should always be one lzo header, recording the total length of the compressed data, followed by one segment header, recording the compressed lzo payload.
But if a crafted inline lzo compressed file extent contains only an lzo header, without the segment header or payload, lzo_decompress() will still try to read the segment header, causing a read beyond the item boundary.
Furthermore if the inline lzo compressed file extent is the first item of the leaf, it will be at the extent buffer boundary. The above out-of-boundary read will go beyond the extent buffer boundary, triggering the above KASAN report.
[FIX] Validate the total length of the inlined lzo compressed file extent, to make sure there is at least one LZO header and one segment header, and a non-zero payload.
[ Rework the commit message to remove slop ]