A recent Linux kernel vulnerability, identified as CVE-2024-39472, was found in the XFS filesystem. This bug, rooted deep in the way XFS manages log recovery buffers, allowed for a risky out-of-bounds memory access. Below, I’ll break down what caused it, exactly what was vulnerable, and how the new patch fixes things. We’ll also walk through hypothetical exploit details and reference the original sources.

What is XFS and Log Recovery?

XFS is a high-performance journaling filesystem. To recover after a crash, it keeps logs of changes (like a black box for your files). These logs use internal records—structures with sizes tracked by header fields like h_size. Messing this up can crash your system or, in rare cases, let a user run code they shouldn’t be able to.

Where did things go wrong?

Older tools (mkfs.xfs from xfsprogs) could generate slightly wrong header sizes (h_size) for unmount (umount) log records. To patch this up, a fixup was introduced to handle incorrect h_size during log recovery. Later, a code refactor stopped using the "fixed" h_size when calculating buffer sizes for log recovery. Normally, this is fine… unless the header is maliciously corrupted, such as by a fuzzer.

Result: The system might allocate a buffer that’s too small and read/write past its end—a classic out-of-bounds access.

Vulnerable Code (Simplified)

// Old, incorrect calculation:
int nblocks = xlog_logrec_hblks(log_record_h_size);  // Used possibly wrong h_size
logrec_buf = kmalloc(nblocks * blocksize, GFP_KERNEL);

If log_record_h_size is larger than expected (either due to an old mkfs tool, or a malicious fuzzer), the buffer size may not match the actual needs.

Patched Code (Commit a70f9fe52daa & Fix)

// Now, directly use the 'fixed-up' h_size for buffer calculations:
int nblocks = how_many(fixed_h_size, blocksize);  // Use the corrected value
logrec_buf = kmalloc(nblocks * blocksize, GFP_KERNEL);

how_many() ensures enough blocks are allocated for the full, corrected size.

> Source:
- Commit a70f9fe52daa on kernel.org
- Further log recovery fix in commit c771b99d6c9

Exploit Scenario

If a fuzzer or attacker creates a specially crafted XFS log segment with a deliberately malformed h_size field, an unpatched kernel will use this size to process a log recovery event—possibly reading or writing past the end of the allocated buffer.

Create a crafted file: Generates an XFS log with an invalid h_size.

2. Trigger log recovery: Mount and force recovery (or unmount/mount cycle).
3. Kernel Oops/crash: Out-of-bounds buffer access, potentially leading to DoS or further compromise.

# Not real exploit code, but a demonstration
with open('corrupt-log', 'wb') as f:
    f.write(make_xfs_log_with_large_h_size())
# Now mount with kernel <fix> on a test VM
# Kernel crashes, dmesg shows OOB access in xfs_log_recover()

Note: No public RCE exploit exists, but the impact depends on related memory protections.

How to Fix

1. Patch your kernel to include the commit with the fix.

Conclusion

CVE-2024-39472 highlights how small miscalculations with legacy code can cascade into modern security problems—classic out-of-bounds access via a mismatched header (h_size) in XFS log recovery. The patched code now checks and uses the corrected size, squashing this bug.


> Further Reading & References:
> - Linux kernel commit a70f9fe52daa
> - xfsprogs mkfs historic bug
> - CVE-2024-39472 NVD entry (pending update)

Timeline

Published on: 07/05/2024 07:15:10 UTC
Last modified on: 07/15/2024 06:50:06 UTC