CVE-2024-26616 - Avoiding Use-After-Free in Btrfs Scrub When Chunk Length Is Not 64K Aligned

The Linux kernel has recently resolved a vulnerability in the btrfs (B-tree File System) specifically in the scrub process. This post will provide a detailed explanation of the bug, its cause, and the fix applied. The resolution of this vulnerability, tagged as CVE-2024-26616, addresses potential "use-after-free" situations when the chunk length is not aligned to 64K for btrfs.

Link to original reference: Linux Kernel Mailing List Archive

The Bug

The bug was first reported on an ext4-converted btrfs system which was experiencing various issues during the scrub process, such as unrepariable errors, "unable to find chunk map" errors, Use-after-free KASAN (Kernel Address Sanitizer) reports, and system crashes mostly caused by use-after-free conditions.

The Cause

The vulnerability was caused by a combination of issues in the btrfs scrub process. First, during the converted fs (file system) process, the logical bytenr is located at the chunk end. This would cause btrfs_submit_bio() to split the bio (Block I/O), subsequently triggering the endio (end input/output) function for both halves.

However, scrub_submit_initial_read() should only expect the endio function to be called once. Therefore, the first endio function would already free the bbio::bio, leaving the bvec (bio vector) freed. As a result, the second endio call would lead to a use-after-free condition.

To resolve this issue, the following fixes were implemented

1. Ensure that scrub_read_endio() only updates bits within its range. Since it is possible to read less than 64K at the end of the chunk, it is important not to touch the bits beyond the chunk boundary.

2. Ensure that scrub_submit_initial_read() only reads the chunk range. This is achieved by calculating the real number of sectors that need to be read and adding them sector-by-sector to the bio.

It is worth noting that the scrub read repair path does not require additional fixes. With the above resolutions in place, the error bit for the range beyond the chunk will not be updated, ensuring that scrub_stripe_submit_repair_read() never submits any read beyond the chunk.

In conclusion, the vulnerability, CVE-2024-26616, was successfully addressed in the Linux kernel, ensuring that use-after-free conditions are avoided when the chunk length is not 64K aligned in the btrfs scrub process. The detailed explanation provided here, along with the sample code snippets, aim to provide better understanding and insight into this critical security improvement in the Linux kernel.

Timeline

Published on: 03/11/2024 18:15:19 UTC
Last modified on: 12/12/2024 15:31:18 UTC