CVE-2026-80734 in Linux
Tóm tắt
Bởi VulDB • 03/09/2026
Trong kernel Linux, lỗ hổng sau đây đã được khắc phục:
btrfs: khởi tạo các cờ ánh xạ inode cho các inode trong bộ nhớ đệm (cached inodes)
[BUG]
Khi chạy generic/795 với kích thước khối 8K và kích thước trang 4K, bài kiểm tra luôn thất bại, kích hoạt một số lệnh ASSERT() liên quan đến kích thước folio:
795 (241074): drop_caches: 3 assertion failed: IS_ALIGNED(start, blocksize) && IS_ALIGNED(end + 1, blocksize), in extent_io.c:1404 (blocksize=8192 root=262 ino=258 start=16826368 end=16830463 mapping min order=0) ------------[ cut here ]------------
kernel BUG at extent_io.c:1404! Oops: invalid opcode: 0000 [#1] SMP
CPU: 8 UID: 0 PID: 241105 Comm: fsstress Tainted: G OE 7.2.0-rc5-custom+ #442 PREEMPT(full) f4bfb352566f3949f29c233ce6f735050a03b245 Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022 RIP: 0010:assert_folio_range.cold+0x3d/0x3f [btrfs]
Call Trace: <TASK> btrfs_read_folio+0x9e/0x170 [btrfs 4cd1dd93b341b8ef766643f9512f4a86259567a3]
prepare_one_folio.constprop.0+0x104/0x2a0 [btrfs 4cd1dd93b341b8ef766643f9512f4a86259567a3]
btrfs_buffered_write+0x285/0xa50 [btrfs 4cd1dd93b341b8ef766643f9512f4a86259567a3]
btrfs_do_write_iter+0x1aa/0x210 [btrfs 4cd1dd93b341b8ef766643f9512f4a86259567a3]
iter_file_splice_write+0x31a/0x540 direct_splice_actor+0x53/0x170 splice_direct_to_actor+0xe9/0x240 do_splice_direct+0x76/0xb0 vfs_copy_file_range+0x1fd/0x630 __x64_sys_copy_file_range+0xf9/0x220 do_syscall_64+0xe1/0x790 entry_SYSCALL_64_after_hwframe+0x4b/0x53 </TASK> ---[ end trace 0000000000000000 ]---
Lệnh ASSERT() này được thêm vào bởi một bản vá sau đó. Sự cố crash xảy ra với bản vá debug mới này, và không có sự sửa lỗi này.
[CAUSE]
Trong trường hợp trên, giá trị start 16826368 đã được căn chỉnh đúng theo khối 8K, nhưng end (16830463 + 1) thì không được căn chỉnh theo khối 8K. Hơn nữa, thứ tự folio tối thiểu của mapping là 0, chứ không phải là 1 như mong đợi đối với kích thước khối 8K và kích thước trang 4K.
Điều này có nghĩa là một số inode chưa gọi hàm btrfs_set_inode_mapping_order().
Việc thiếu lệnh gọi btrfs_set_inode_mapping_order() xảy ra đối với các inode trong bộ nhớ đệm (cached inodes), thông qua chuỗi sự kiện sau:
- btrfs_create_new_inode() được gọi cho inode X Hàm này thiết lập đúng thứ tự folio tối thiểu cho VFS inode.
- btrfs_update_inode() được gọi cho inode X Hàm này gọi btrfs_delayed_update_inode() để tạo một delayed_node vào xarray root->delayed_nodes.
- Drop cache/áp lực bộ nhớ, làm mất (evict) inode X trong bộ nhớ Điều này đã loại bỏ inode X khỏi bộ nhớ, nhưng delayed_node vẫn còn nằm trong root->delayed_nodes để tái sử dụng sau này.
- btrfs_iget() được gọi lại cho inode X
btrfs_iget() |- btrfs_iget_locked() | |- iget5_locked_rcu() | Hàm này tạo một vfs_inode mới cho btrfs, trong đó mapping vẫn giữ thứ tự folio tối thiểu là 0. | |- btrfs_read_locked_inode() |- btrfs_fill_inode() | |- btrfs_get_delayed_node() | Hàm này tìm thấy node trước đó và sử dụng delayed_node đó để khởi tạo inode mới. | |- filled = true; |- if (filled) goto cache_index; Điều này bỏ qua các lệnh gọi btrfs_update_inode_mapping_flags() và btrfs_set_inode_mapping_order(). Do đó, inode vẫn có thứ tự folio tối thiểu được đặt là 0, thay vì yêu cầu là 1.
Vì vậy, việc đọc bộ nhớ đệm trang (page cache) sau đó sẽ nhận được một folio có kích thước nhỏ hơn kích thước khối, do mapping của nó có thứ tự folio tối thiểu được đặt là 0 chứ không phải 1, từ đó kích hoạt lệnh ASSERT().
[FIX]
Di chuyển các lệnh gọi btrfs_update_inode_mapping_flags() và btrfs_set_inode_mapping_order() xuống nhãn cache_index, để đảm bảo rằng các cờ mapping và thứ tự folio tối thiểu luôn được thiết lập dù chúng ta có inode trong bộ nhớ đệm hay không.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.