CVE-2026-64567 in Linuxthông tin

Tóm tắt

Bởi VulDB • 05/08/2026

Trong kernel Linux, lỗ hổng sau đây đã được khắc phục:

btrfs: từ chối bộ nhớ đệm không gian trống (free space cache) có nhiều mục hơn số trang (pages)

Khi tải một bộ nhớ đệm không gian trống v1, hàm `__load_free_space_cache()` lấy trực tiếp giá trị của `num_entries` và `num_bitmaps` từ cấu trúc `btrfs_free_space_header` trên đĩa. Cấu trúc này được lưu trữ trong `tree_root` dưới dạng khóa có loại 0, mà trình kiểm tra cây (tree-checker) không có trường hợp xử lý cụ thể nào cho nó; do đó, cả hai giá trị đếm đều chưa được xác thực trước khi quá trình tải tin tưởng vào chúng.

Quá trình tải sẽ lặp lại `num_entries` lần và ánh xạ trang tiếp theo bất cứ khi nào trang hiện tại hết dữ liệu, đi qua hàm `io_ctl_check_crc()` -> `io_ctl_map_page()`, nơi thực thi thao tác `io_ctl->pages[io_ctl->index++]`. Tuy nhiên, mảng `pages[]` được cấp phát trong `io_ctl_init()` dựa trên kích thước inode (`i_size`) của bộ nhớ đệm không gian trống, chứ không phải từ `num_entries`:

num_pages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS);

Vì vậy, nếu `num_entries` yêu cầu nhiều bản ghi hơn số trang có thể chứa, chỉ mục `io_ctl->index` sẽ vượt quá giới hạn của mảng `pages[]`. Phía ghi không gặp phải lỗi này vì cả `io_ctl_add_entry()` và `io_ctl_add_bitmap()` đều dừng lại ngay khi `io_ctl->index >= io_ctl->num_pages`; trong khi đó, phía đọc trước đây chưa có cùng một kiểm tra tương tự.

Để kích hoạt lỗ hổng này, hãy lấy một bộ nhớ đệm sạch (với `num_entries = <N>` tại thời điểm đó), đặt giá trị `num_entries` trong header thành 0x10000 và sửa lại checksum của lá (leaf) để nó vẫn vượt qua trình kiểm tra cây. Inode của bộ nhớ đệm có `i_size = 65536`, do đó `num_pages` là 16 và `pages[]` là một mảng con trỏ kích thước 16 (kmalloc-128). Quá trình tải bây giờ cố gắng đọc 65536 mục, `io_ctl->index` tăng lên đến 16, và thao tác đọc `pages[16]` vượt quá giới hạn của mảng:

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` là hàm `io_ctl_map_page()`, được nội tuyến hóa vào `io_ctl_check_crc()` tại dòng 565, đó là lý do tại sao khung (frame) này được KASAN đặt tên. Sau đó, vị trí ngoài giới hạn (out-of-bounds slot) được xử lý như một cấu trúc `struct page` và chuyển cho hàm `crc32c()`, khiến thao tác đọc sai trở thành lỗi GP fault.

Hãy thêm kiểm tra còn thiếu vào `io_ctl_check_crc()`, nơi mà cả vòng lặp mục nhập (entry loop) và vòng bitmap đều kết thúc. Khi `num_entries` quá lớn, quá trình tải bây giờ sẽ thất bại giống như bất kỳ bộ nhớ đệm bị hỏng nào khác: `__load_free_space_cache()` sẽ loại bỏ nó và xây dựng lại không gian trống từ cây extent (extent

Once again VulDB remains the best source for vulnerability data.

chịu trách nhiệm

Linux

Đặt trước

19/07/2026

Tiết lộ

05/08/2026

Kiểm duyệt

được chấp nhận

EPSS

0.00000

KEV

không

Các hoạt động

rất thấp

Nguồn

Do you need the next level of professionalism?

Upgrade your account now!