CVE-2026-64567 in Linux
要約
〜によって VulDB • 2026年08月05日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
btrfs: ページ数より多くのエントリを持つ空き領域キャッシュを拒否する
v1の空き領域キャッシュを読み込む際、__load_free_space_cache()関数はnum_entriesおよびnum_bitmapsフィールドをディスク上のbtrfs_free_space_headerから直接取得します。このヘッダーはtree_root内のタイプ0のキーの下に格納されており、ツリーチェッカーには該当ケースがないため、読み込み処理がこれを信頼する前にこれらのカウント値は検証されません。
読み込み処理ではnum_entries回ループし、現在のページを使い果たすたびに次のページをマップします。この過程でio_ctl_check_crc() -> io_ctl_map_page()を経由しますが、後者はio_ctl->pages[io_ctl->index++]を実行します。しかし、pages[]配列はnum_entriesではなくキャッシュinodeのi_sizeに基づいてio_ctl_init()内で割り当てられています:
num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
したがって、num_entriesがページが保持できるレコード数よりも多いと主張する場合、io_ctl->indexはpages[]配列の末尾を超えてしまいます。書き込み側ではこの問題が発生しません。なぜなら、io_ctl_add_entry()およびio_ctl_add_bitmap()はいずれもio_ctl->index >= io_ctl->num_pagesとなった時点で停止するためです。読み込み側には同様のチェックが存在しませんでした。
これをトリガーするには、クリーンなキャッシュ(ここでnum_entries = <N>)を用意し、ヘッダー内のnum_entriesを0x10000に設定し、ツリーチェッカーが依然として合格するようリーフのチェックサムを修正します。キャッシュinodeはi_size = 65536であるため、num_pagesは16となり、pages[]は16要素(kmalloc-128)の配列となります。読み込み処理は今や65536エントリを読み込もうとし、io_ctl->indexが16まで増加すると、配列外にあるpages[16]が読み込まれます:
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) Read of size 8 at addr ffff88800c833a80 by task kworker/u8:3/58 io_ctl_check_crc (fs/btrfs/free-space-cache.c:420 fs/btrfs/free-space-cache.c:565) __load_free_space_cache (fs/btrfs/free-space-cache.c:655 fs/btrfs/free-space-cache.c:820) load_free_space_cache (fs/btrfs/free-space-cache.c:1017) caching_thread (fs/btrfs/block-group.c:880) btrfs_work_helper (fs/btrfs/async-thread.c:312) process_one_work worker_thread kthread ret_from_fork
free-space-cache.cの420行目はio_ctl_map_page()であり、565行目のio_ctl_check_crc()にインライン展開されています。これがKASANによって特定されるフレームである理由です。その後、配列外のスロットはstruct pageとして扱われcrc32c()に渡されるため、不正な読み込みがGP(一般保護)フォルトに変換されます。
io_ctl_check_crc()に必要なチェックを追加します。これはエントリループおよびビットマップループの両方が終端する箇所です。num_entriesが大きすぎる場合、読み込み処理は他の壊れたキャッシュと同様に失敗し、__load_free_space_cache()はそのキャッシュを破棄してextentsツリーから空き領域を再構築するため、有効なキャッシュが拒否されることはありません。
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.