Table of Contents:
Introduction
In early 2024, Linux kernel developers found and fixed a vulnerability in the Mediatek DRM (Direct Rendering Manager) subsystem that could easily lead to a kernel crash. This post gives you everything you need to know, in plain language—what happened, why it can crash your system, what could've happened if it was exploited, and how the developers fixed it.
What is CVE-2024-26874?
CVE-2024-26874 is a vulnerability affecting the Mediatek display driver subsystem in the Linux kernel. It’s caused by a race condition and a missing NULL pointer check in the function mtk_drm_crtc_finish_page_flip().
Component: Linux kernel, Mediatek DRM subsystem
- Vulnerability Type: NULL pointer Dereference / Race Condition
Exploitability: Needs access to the graphics subsystem
- Fixed in: 6f5ad610baeb (mainline kernel)
Deep Dive: Where’s the Bug?
The Linux kernel’s DRM subsystem handles graphics output. The Mediatek variant keeps track of rendering events with a data member, mtk_crtc->event. When a page flip (the operation that changes the display to show a new image) is done, the driver needs to notify the rest of the system by accessing this event.
If, for any reason, mtk_crtc->event is NULL and the code tries to access it, the kernel crashes (NULL pointer dereference). This is especially bad inside kernel code, as it will panic and halt the whole system.
Explaining the Race Condition
A race condition occurs when several threads (or CPUs) interact with the same data without proper synchronization. That’s the heart of CVE-2024-26874.
CPU 1 is updating the page flip and is about to clear the event.
2. CPU 2 is processing the display flush and checks if the event is set, but right after this, CPU 1 clears the event.
Here’s a simplified table of the race
| CPU 1 | CPU 2 |
|-----------------------------------------------|-------------------------------------------------|
| Enters atomic begin | |
| event is not NULL | |
| | Calls atomic flush |
| | Reads event is non-NULL |
| Process IRQ: | |
| Locks data | |
| Sets mtk_crtc->event to NULL | |
| Sets pending_needs_vblank to false | |
| Unlocks data | |
| | Sets pending_needs_vblank to true (stale value) |
| | IRQ triggers again |
| | Calls finish_page_flip, event is now NULL, crash|
Here’s a simplified representation from the originally vulnerable code, where the check is missing
void mtk_drm_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc) {
// ...other code...
// Assume mtk_crtc->event is not NULL, but it's actually possible
drm_send_event_locked(mtk_crtc->base.dev, mtk_crtc->event, &data);
mtk_crtc->event = NULL; // Later set to NULL
}
In the race, mtk_crtc->event could already be NULL at this point, causing the function to operate on an invalid pointer.
This bug is a local denial-of-service (DoS) opportunity. To exploit it
1. User has access to graphics/display API.
2. Create load on the system that triggers concurrent page flips and display flushes—like heavy video or graphical operations, or maybe running specially crafted Xorg/GPU test tools.
3. If the correct timing is hit (hitting the race 'window'), mtk_crtc->event could be NULL in the wrong place, causing the kernel to crash.
No code execution is achieved, but persistent DoS is possible. In embedded devices (phones, TVs, single board computers), this leads to full lockup and possible data loss.
The Fix: Simple But Robust
Instead of locking the whole function (which would be more expensive), the kernel developers made the fix simple: just check if mtk_crtc->event is NULL before using it.
Fixed Code Snippet
void mtk_drm_crtc_finish_page_flip(struct mtk_crtc *mtk_crtc) {
// ...other code...
if (mtk_crtc->event) {
drm_send_event_locked(mtk_crtc->base.dev, mtk_crtc->event, &data);
mtk_crtc->event = NULL;
}
}
By adding the if (mtk_crtc->event) guard, any attempt to dereference a NULL pointer is prevented, and the system stays stable even in the face of concurrent updates.
Commit (with official patch):
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6f5ad610baeb
References and Further Reading
- Upstream patch + explanation
- CVE-2024-26874 at NVD
- Linux kernel security tracker
- Linux DRM subsystem docs
Conclusion
CVE-2024-26874 is a great example of a subtle kernel bug with big consequences. While it's not a remote or privilege escalation vulnerability, it demonstrates why tight checks and awareness of concurrency in kernel space are so crucial.
If your device uses the Mediatek DRM driver (especially in embedded/Android hardware), make sure you’ve got a kernel with this fix applied!
Timeline
Published on: 04/17/2024 11:15:09 UTC
Last modified on: 03/03/2025 17:47:59 UTC