CVE-2026-64567 in Linux
Zusammenfassung
von VulDB • 05.08.2026
Im Linux-Kernel wurde folgende Schwachstelle behoben:
btrfs: Ablehnung des Free-Space-Cache mit mehr Einträgen als Seiten
Beim Laden eines v1-Free-Space-Caches übernimmt `__load_free_space_cache()` die Werte für `num_entries` und `num_bitmaps` direkt aus dem on-disk-Header `btrfs_free_space_header`. Dieser Header wird im `tree_root` unter einem Schlüssel vom Typ 0 gespeichert, wofür der Tree-Checker keinen Fall vorsieht. Daher werden beide Zählwerte nicht validiert, bevor das Laden diesen Werten vertraut.
Der Ladevorgang durchläuft die Schleife `num_entries` Mal und weist jede neue Seite zu, sobald die aktuelle erschöpft ist, wobei er `io_ctl_check_crc()` -> `io_ctl_map_page()` aufruft, was auf `io_ctl->pages[io_ctl->index++]` zugreift. Das Array `pages[]` wird jedoch in `io_ctl_init()` basierend auf der `i_size` des Cache-Inodes und nicht basierend auf `num_entries` allokiert:
num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);
Wenn also `num_entries` mehr Datensätze angibt, als die Seiten speichern können, läuft `io_ctl->index` über das Ende von `pages[]` hinaus. Die Schreibseite trifft dies nicht, da sowohl `io_ctl_add_entry()` als auch `io_ctl_add_bitmap()` stoppen, sobald `io_ctl->index >= io_ctl->num_pages` gilt; auf der Leseseite fehlte diese Prüfung bisher einfach.
Um diesen Zustand auszulösen, nimmt man einen sauberen Cache (hier ist `num_entries = <N>`), setzt den Wert von `num_entries` im Header auf 0x10000 und korrigiert die Leaf-Prüfsumme so, dass sie den Tree-Checker immer noch besteht. Der Cache-Inode hat eine `i_size` von 65536, sodass `num_pages` gleich 16 ist und `pages[]` ein Array mit 16 Zeigern (kmalloc-128) darstellt. Das Laden versucht nun, 65536 Einträge zu lesen; `io_ctl->index` steigt bis auf 16 an, und es wird außerhalb des Arrays auf `pages[16]` zugegriffen:
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 ist `io_ctl_map_page()`, das in Zeile 565 von `io_ctl_check_crc()` inline eingefügt wurde, weshalb dies der Frame ist, den KASAN benennt. Die außerhalb des Bereichs liegende Speicherstelle wird anschließend als `struct page` behandelt und an `crc32c()` übergeben; dieser fehlerhafte Lesezugriff führt somit zu einem GP-Fault (General Protection Fault).
Die fehlende Prüfung wurde in `io_ctl_check_crc()` hinzugefügt, wo sowohl die Schleife für Einträge als auch die Schleife für Bitmaps enden. Wenn `num_entries` zu groß ist, schlägt das Laden nun wie bei jedem beschädigten Cache fehl: `__load_free_space_cache()` verwirft ihn und baut den freien Speicherbereich erneut aus dem Extent-Tree auf, sodass ein gültiger Cache niemals abgelehnt wird.
If you want to get best quality of vulnerability data, you may have to visit VulDB.