A new Linux kernel vulnerability, CVE-2024-56548, has been identified and patched in the hfsplus filesystem driver. This bug may let local attackers trigger a kernel memory out-of-bounds write simply by mounting specially prepared HFS+ images via loopbacks with custom block sizes. In this post, we’ll break down what this bug is, how it could be weaponized, show relevant code snippets, and provide practical mitigation recommendations.
What's the Vulnerability?
The HFS+ filesystem driver inside the Linux kernel didn’t handle changing device blocksize correctly. In some scenarios, like when using a loopback device (virtual block device backing files), the blocksize can be changed at runtime via the LOOP_SET_BLOCK_SIZE ioctl. The issue was with the hfsplus code querying the current block size multiple times, not saving or synchronizing it. This could cause the driver to do math or memory allocations based on a stale (now incorrect) block size, leading to an out-of-bounds (OOB) write:
Blocksize is changed to B.
- Now, perform I/O as if allocation was for blocksize B, overrunning the end of the buffer.
If exploited, this could crash the kernel or – potentially – let attackers run code in kernel space.
Before the fix, mounting a crafted image could immediately trip KASAN (Kernel Address SANitizer)
[ 419.944641] ==================================================================
[ 419.945655] BUG: KASAN: slab-use-after-free in hfsplus_read_wrapper+x659/xaa
[ 419.946703] Read of size 2 at addr ffff88800721fc00 by task repro/10678
...
[ 419.955367] hfsplus_read_wrapper+x659/xaa
...
[ 419.965381] ? sb_set_blocksize+x6d/xae
...
The driver attempted to read/write beyond the end of its buffer, causing a safe kernel to panic, but on non-hardened builds, this may allow memory corruption.
In the affected code of fs/hfsplus you find code similar to
unsigned int io_size = bdev_logical_block_size(sb->s_bdev);
buffer = kmalloc(io_size * count, GFP_KERNEL);
/* ... */
io_size = bdev_logical_block_size(sb->s_bdev); // Oops, might be different now!
ret = submit_bio_io(buffer, len, io_size);
Imagine the blocksize changed between kmalloc and the later call, so now you can read/write out of bounds!
Patch:
The fixed logic caches the minimal reasonable blocksize at mount/init time, instead of querying it again and again.
Proof-of-Concept: How Could This Be Exploited?
Let’s see how an attacker could *trigger* the bug.
1. Create a small HFS+ image
dd if=/dev/zero of=hfs.img bs=1M count=10
mkfs.hfsplus hfs.img
2. Set up a loop device with a non-default blocksize
losetup --show -b 512 /dev/loop10 ./hfs.img # Block size 512
3. Mount the filesystem, then change the block size
mount -t hfsplus /dev/loop10 /mnt/test
# Now, with the device still mounted:
ioctl /dev/loop10 LOOP_SET_BLOCK_SIZE 4096 # Switch block size to 4096 (using e.g. Python or C small program)
### 4. Trigger file system I/O, which could now cause OOB writes
ls /mnt/test # or create/read files, etc.
This could lead to kernel memory corruption or panic.
The Fix: Always Use a Stable Blocksize
The Linux patch sets a lower-bound blocksize at mount time and always uses the maximum of the fixed lower bound or any later detected block size, avoiding the hazard of chasing a moving target.
Relevant upstream fix:
- lkml patch discussion
- Fix commit 9f9a3b5e1adb in fs/hfsplus
Visualization
-static inline unsigned int hfsplus_iosz(struct super_block *sb)
-{
- return max(HFSPLUS_SECTOR_SIZE, bdev_logical_block_size(sb->s_bdev));
-}
+/* Use stable min_io_size captured at mount time */
+unsigned int hfsplus_iosz(struct super_block *sb)
+{
+ struct hfsplus_sb_info *hfs_sb = HFSPLUS_SB(sb);
+ return max(HFSPLUS_SECTOR_SIZE, hfs_sb->min_io_size);
+}
Mitigation & Advice
- Update your kernel: All users running loopback-mounts with hfsplus should upgrade at least to the kernel carrying this patch. Major distros are expected to backport it.
- Limit user mount rights: Don’t let untrusted users mount filesystems, especially with custom block sizes.
References
- CVE Record (NVD)
- Linux commit fixing CVE-2024-56548
- Original LKML Patch Submission
Conclusion
CVE-2024-56548 is a classic example of why device and buffer sizes should be carefully coordinated in kernel drivers. If you run Linux systems that may interact with HFS+ disks, especially over loop devices, apply the latest patches. Even if this bug requires local access and some trickery, privilege escalation exploits often chain simple bugs like this. Always keep production servers up to date!
If you want a sample exploit PoC or guidance on checking your kernels, feel free to ask. Stay patched, stay safe!
Timeline
Published on: 12/27/2024 14:15:34 UTC
Last modified on: 03/06/2025 12:42:52 UTC