CVE-2026-64567

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
05/08/2026
Last modified:
19/08/2026

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> btrfs: reject free space cache with more entries than pages<br /> <br /> When loading a v1 free space cache, __load_free_space_cache() takes<br /> num_entries and num_bitmaps straight from the on-disk<br /> btrfs_free_space_header. That header is stored in the tree_root under a key<br /> with type 0, which the tree-checker has no case for, so neither count is<br /> validated before the load trusts it.<br /> <br /> The load loops num_entries times and maps the next page whenever the current<br /> one runs out, going through io_ctl_check_crc() -&gt; io_ctl_map_page(), which<br /> does io_ctl-&gt;pages[io_ctl-&gt;index++]. But pages[] is allocated in<br /> io_ctl_init() from the cache inode&amp;#39;s i_size, not from num_entries:<br /> <br /> num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);<br /> io_ctl-&gt;pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);<br /> <br /> So if num_entries claims more records than the pages can hold, io_ctl-&gt;index<br /> runs off the end of pages[]. The write side never hits this because<br /> io_ctl_add_entry() and io_ctl_add_bitmap() both stop once<br /> io_ctl-&gt;index &gt;= io_ctl-&gt;num_pages; the read side just never had the same<br /> check.<br /> <br /> To trigger it, take a clean cache (num_entries = here), set num_entries<br /> in the header to 0x10000, and fix up the leaf checksum so it still passes<br /> the tree-checker. The cache inode has i_size = 65536, so num_pages is 16 and<br /> pages[] is a 16-pointer (kmalloc-128) array. The load now tries to read<br /> 65536 entries, io_ctl-&gt;index walks up to 16, and pages[16] is read past the<br /> array:<br /> <br /> BUG: KASAN: slab-out-of-bounds in io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)<br /> Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58<br /> io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565)<br /> __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820)<br /> load_free_space_cache (fs/btrfs/free-space-cache.c:1017)<br /> caching_thread (fs/btrfs/block-group.c:880)<br /> btrfs_work_helper (fs/btrfs/async-thread.c:312)<br /> process_one_work<br /> worker_thread<br /> kthread<br /> ret_from_fork<br /> <br /> free-space-cache.c:420 is io_ctl_map_page(), inlined into io_ctl_check_crc()<br /> at line 565, which is why that is the frame KASAN names. The out-of-bounds<br /> slot is then treated as a struct page and handed to crc32c(), so the bad<br /> read turns into a GP fault.<br /> <br /> Add the missing check to io_ctl_check_crc(), which is where both the entry<br /> loop and the bitmap loop end up. When num_entries is too large the load now<br /> fails like any corrupt cache: __load_free_space_cache() drops it and rebuilds<br /> the free space from the extent tree, so a valid cache is never rejected.