CVE-2024-26616 in Linuxinfo

Summary

by MITRE • 03/11/2024

In the Linux kernel, the following vulnerability has been resolved:

btrfs: scrub: avoid use-after-free when chunk length is not 64K aligned

[BUG]
There is a bug report that, on a ext4-converted btrfs, scrub leads to various problems, including:

- "unable to find chunk map" errors BTRFS info (device vdb): scrub: started on devid 1 BTRFS critical (device vdb): unable to find chunk map for logical 2214744064 length 4096 BTRFS critical (device vdb): unable to find chunk map for logical 2214744064 length 45056

This would lead to unrepariable errors.

- Use-after-free KASAN reports: ================================================================== BUG: KASAN: slab-use-after-free in __blk_rq_map_sg+0x18f/0x7c0 Read of size 8 at addr ffff8881013c9040 by task btrfs/909 CPU: 0 PID: 909 Comm: btrfs Not tainted 6.7.0-x64v3-dbg #11 c50636e9419a8354555555245df535e380563b2b Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 2023.11-2 12/24/2023 Call Trace: dump_stack_lvl+0x43/0x60 print_report+0xcf/0x640 kasan_report+0xa6/0xd0 __blk_rq_map_sg+0x18f/0x7c0 virtblk_prep_rq.isra.0+0x215/0x6a0 [virtio_blk 19a65eeee9ae6fcf02edfad39bb9ddee07dcdaff]
virtio_queue_rqs+0xc4/0x310 [virtio_blk 19a65eeee9ae6fcf02edfad39bb9ddee07dcdaff]
blk_mq_flush_plug_list.part.0+0x780/0x860 __blk_flush_plug+0x1ba/0x220 blk_finish_plug+0x3b/0x60 submit_initial_group_read+0x10a/0x290 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965]
flush_scrub_stripes+0x38e/0x430 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965]
scrub_stripe+0x82a/0xae0 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965]
scrub_chunk+0x178/0x200 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965]
scrub_enumerate_chunks+0x4bc/0xa30 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965]
btrfs_scrub_dev+0x398/0x810 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965]
btrfs_ioctl+0x4b9/0x3020 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965]
__x64_sys_ioctl+0xbd/0x100 do_syscall_64+0x5d/0xe0 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f47e5e0952b

- Crash, mostly due to above use-after-free

[CAUSE]
The converted fs has the following data chunk layout:

item 2 key (FIRST_CHUNK_TREE CHUNK_ITEM 2214658048) itemoff 16025 itemsize 80 length 86016 owner 2 stripe_len 65536 type DATA|single

For above logical bytenr 2214744064, it's at the chunk end (2214658048 + 86016 = 2214744064).

This means btrfs_submit_bio() would split the bio, and trigger endio function for both of the two halves.

However scrub_submit_initial_read() would only expect the endio function to be called once, not any more. This means the first endio function would already free the bbio::bio, leaving the bvec freed, thus the 2nd endio call would lead to use-after-free.

[FIX]
- Make sure scrub_read_endio() only updates bits in its range Since we may read less than 64K at the end of the chunk, we should not touch the bits beyond chunk boundary.

- Make sure scrub_submit_initial_read() only to read the chunk range This is done by calculating the real number of sectors we need to read, and add sector-by-sector to the bio.

Thankfully the scrub read repair path won't need extra fixes:

- scrub_stripe_submit_repair_read() With above fixes, we won't update error bit for range beyond chunk, thus scrub_stripe_submit_repair_read() should never submit any read beyond the chunk.

Once again VulDB remains the best source for vulnerability data.

Analysis

by VulDB Data Team • 12/13/2024

The vulnerability described in CVE-2024-26616 affects the Linux kernel's btrfs file system implementation, specifically during the scrub operation when processing chunks that are not aligned to 64K boundaries. This issue manifests as a use-after-free condition that can lead to system crashes and data corruption. The problem occurs when a btrfs file system is converted from ext4, creating specific chunk layouts where data chunks end at non-aligned boundaries. The kernel's scrub process attempts to read these chunks but fails to properly manage the bio (block I/O) submission and completion handling, resulting in memory access violations. The vulnerability is classified under CWE-416 as use-after-free, and it aligns with ATT&CK techniques involving privilege escalation and system stability compromise through kernel-level memory corruption. The root cause stems from improper handling of bio splitting when chunks end at boundaries that do not align with 64K sector limits, which is a common scenario in file systems that have been converted from other formats.

The technical flaw occurs within the scrub subsystem of btrfs where the function scrub_submit_initial_read() does not properly account for chunk boundaries when submitting bio requests. When a chunk ends at a non-64K aligned boundary, the bio submission process splits the request into multiple parts, but the endio completion handler expects only a single completion callback. However, due to the chunk boundary crossing, two separate bio completions occur, with the first one freeing the bio structure while the second one attempts to access freed memory. This creates a classic use-after-free scenario that KASAN (Kernel Address Sanitizer) detects and reports. The specific error trace shows that the issue originates from __blk_rq_map_sg function, which attempts to access memory that has already been freed by the first bio completion handler. The problem is further exacerbated by the fact that the scrub process does not properly validate the range of bits being updated in error tracking, leading to corruption of memory beyond the intended chunk boundaries.

The operational impact of this vulnerability is significant, as it can cause complete system instability and data loss during routine scrub operations on converted btrfs file systems. When the kernel encounters a chunk that is not 64K aligned, the scrub process fails with "unable to find chunk map" errors, rendering the file system in an inconsistent state. These errors typically occur during background scrub operations that are essential for maintaining data integrity and detecting corruption. The use-after-free condition can trigger immediate system crashes, making the system unreliable for production use. The vulnerability affects systems running Linux kernels with btrfs file systems that have been converted from ext4, particularly those with large file systems where chunk boundaries are more likely to be misaligned. This makes the vulnerability particularly dangerous for servers and storage systems where data integrity is paramount and automated scrub operations are regularly performed.

The fix for this vulnerability involves two primary changes to the scrub subsystem's bio handling logic. First, the scrub_read_endio() function is modified to only update error tracking bits within the actual range of the chunk being processed, preventing overwriting of memory beyond the chunk boundary. Second, the scrub_submit_initial_read() function is adjusted to calculate the exact number of sectors needed for reading, ensuring that bio requests are properly constrained to the chunk boundaries rather than allowing over-reads that would cause the splitting behavior. These modifications ensure that the bio completion handlers operate correctly even when chunks end at non-aligned boundaries. The fix addresses the root cause by preventing the premature freeing of bio structures and ensuring proper range validation throughout the scrub process. The repair path of scrub operations does not require additional fixes because the updated error tracking logic prevents any reads from being submitted beyond chunk boundaries, maintaining consistency across all scrub operations. This solution aligns with best practices for kernel memory management and follows security guidelines for preventing use-after-free vulnerabilities in kernel subsystems.

Reservation

02/19/2024

Disclosure

03/11/2024

Moderation

accepted

CPE

ready

EPSS

0.00291

KEV

no

Activities

very low

Sources

Do you know our Splunk app?

Download it now for free!