A recent vulnerability, tracked as CVE-2023-52449, was found and fixed in the Linux kernel’s Memory Technology Device (MTD) subsystem. This bug could potentially cause a kernel crash when both ftl.ko (the Flash Translation Layer) and gluebi.ko (GLUE layer for UBI volumes) modules are loaded together. The problem manifests as a NULL pointer dereference in the gluebi_read() function, leading to system instability and possible denial of service. Let's break down what happened, how it happens, and what was done to fix it, using simple and clear explanations.
What’s the Vulnerability?
When the Linux kernel deals with flash storage, it uses several layered driver modules. Two such modules are:
gluebi.ko: Provides an MTD interface over UBI volumes.
When both these modules are loaded, their interactions via kernel notifiers and device registration can result in one driver (ftl) trying to read MTD data from another driver (gluebi), but the required data pointer (gluebi->desc) hasn't been initialized. This triggers a null pointer dereference (accessing memory that doesn't exist), leading to a crash.
How Does It Happen? (Step by Step)
Below is a breakdown (simplified) of what the kernel does when both modules are loaded. The process flows like this:
ubi_gluebi_init()
└─ ubi_register_volume_notifier()
└─ ubi_enumerate_volumes()
└─ ubi_notify_all()
└─ gluebi_notify() // notifier_call()
└─ gluebi_create()
└─ mtd_device_register()
└─ mtd_device_parse_register()
└─ add_mtd_device()
└─ blktrans_notify_add() // not->add()
└─ ftl_add_mtd() // tr->add_mtd()
└─ scan_header()
└─ mtd_read()
└─ mtd_read_oob()
└─ mtd_read_oob_std()
└─ gluebi_read()
└─ gluebi->desc // NULL! Crash!
Key Problem:
Normally, gluebi_get_device() should set gluebi->desc before it's accessed in gluebi_read(). But in this chain, ftl_add_mtd() skips calling it, so gluebi->desc remains NULL and causes a crash when used.
Try to mount or access a UBI-backed MTD partition:
The kernel tries to set up the various handlers, and the ftl notifier activates before gluebi->desc is ready.
This causes a kernel NULL pointer dereference and the system may crash (kernel panic).
For complete technical reproduction, see [Link 1][1].
Exploit Details
This bug is best described as a denial of service vulnerability. By simply loading the involved modules in a specific order and working with certain UBI-backed MTD partitions, an attacker (or user with module load privileges) can crash the kernel.
Sample Code Snippet Emulating Kernel Trap
// gluebi_read emulated function
int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) {
struct gluebi_desc *desc = ((struct gluebi_dev *)mtd->priv)->desc;
if (!desc) {
// NULL pointer dereference here
printk(KERN_ERR "gluebi->desc is NULL!\n");
return -EFAULT;
}
// ... normal read code ...
}
If desc is NULL, and the function continues, a crash will happen.
Not code execution: No privilege escalation, but causes a denial-of-service.
- Persistence: The bug triggers due to module ordering, so it’s rather a reliability and stability issue than a classic security "exploit."
The Fix
The fixed code prevents gluebi from creating an mtdblock device (block device translation) for any partition of type MTD_UBIVOLUME. The rationale: gluebi is only needed for running JFFS2 on UBI (not FTL or mtdblock!), so these shouldn't co-exist.
By not creating conflicting devices, we avoid the problematic code paths entirely.
Patch Summary:
Refuse to create mtdblock devices in gluebi for UBI-type MTD partitions.
> The solution for the gluebi module is to run jffs2 on the UBI volume without considering working with ftl or mtdblock.
> Therefore, this problem can be avoided by preventing gluebi from creating the mtdblock device after creating mtd partition of the type MTD_UBIVOLUME.
Original Patch and Technical Detail:
[1] lore.kernel.org kernel mailing list
Linux kernel MTD documentation:
[2] https://www.kernel.org/doc/html/latest/
Conclusion
- CVE-2023-52449 exposed a subtle but important reliability hole in the Linux flash storage subsystem.
- Mishandling kernel module interaction and notifier chains can still lead to critical crashes, reminding us of the importance of careful initialization.
- The best way to avoid such issues is clear module separation and properly restricting overlapping use cases.
Advice:
If you're running Linux on embedded devices (routers, IoT) or custom hardware using UBI, JFFS2, FTL, and MTD, ensure your kernel is up-to-date, and review your use of these modules to avoid unexpected crashes.
*This explanation is exclusive and written for clarity. For full technical reproduction, see the [original mailing list post][1].*
[1]: https://lore.kernel.org/all/20231209030228.51294-1-yantrong@loongson.cn/
Timeline
Published on: 02/22/2024 17:15:08 UTC
Last modified on: 03/18/2024 18:38:16 UTC