On June 2024, a subtle yet important bug was patched in the Linux kernel—specifically in the drivers/gpu/drm/sti subsystem. The Common Vulnerabilities and Exposures project assigned this issue CVE-2024-56776. The problem? Forgetting to verify if a returned pointer was, in fact, pointing to valid data instead of to an encoded error. Such mistakes can crash the kernel—and sometimes open the doors for more damaging exploits.

Let’s dig in: what caused the bug, why it mattered, and what the fix means for Linux users.

The Technical Background

### What is drm/sti?

drm/sti is a subdriver in the Direct Rendering Manager (DRM) graphics subsystem. It's used for managing display and graphics on platforms from STMicroelectronics—a tech you’ll find in TVs, car dashboards, and embedded devices.

The Problem: Not Checking Error Pointers

In kernel code, it’s common for functions to return pointers that might, in case of an error, be *special* pointers—these are *error pointers* where the pointer value encodes an error code.

The function that got us in trouble is drm_atomic_get_crtc_state(). This is called to fetch details about the CRTC (part of the graphics pipeline). If things go wrong, it doesn’t return NULL—it could return a pointer like ERR_PTR(-EINVAL). If you treat this error pointer like a regular pointer and dereference it, two things may happen:

Here’s the code *before* the patch

struct drm_crtc_state *crtc_state;
crtc_state = drm_atomic_get_crtc_state(state, crtc);
crtc_state->some_field = value; // Uh-oh! No error check here

The Patch: The Right Way to Handle Error Pointers

To fix CVE-2024-56776, the maintainers added a check using the kernel helper IS_ERR_OR_NULL(), which safely detects if the pointer is NULL or an error pointer.

Here’s how the correct, patched version looks

struct drm_crtc_state *crtc_state;
crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR_OR_NULL(crtc_state)) {
    // Handle the error—log it, abort, or clean up
    return PTR_ERR(crtc_state);
}
// Safe to use crtc_state now!
crtc_state->some_field = value;

Proof-of-Concept: Demonstrating the Bug

Suppose you’re writing code using the vulnerable pattern. You force drm_atomic_get_crtc_state() to fail, causing it to return an error pointer. The subsequent dereference triggers a kernel panic:

struct drm_crtc_state *crtc_state;
crtc_state = drm_atomic_get_crtc_state(state, crtc); // Fails, returns ERR_PTR(-22)
int bogus = crtc_state->some_field; // Touches an invalid memory address (-22 or xFFFFFFEA)

If you were a malicious user and could make this code execute (for example, via an ioctl), you could crash the kernel—a classic Denial of Service (DoS) attack. In some cases, a smart attacker might even build a more complex attack for privilege escalation, but there's no public proof of that for this bug.

DoS: Attackers could reliably panic the kernel and crash any device with the affected driver.

- Potential info leaks/other exploits: Dereferencing error pointers could, in rare cases, leak info or be used as part of a chain—but this specific CVE is just a crash in practice.

How to Fix and Protect

- Upgrade your kernel: Make sure you’re running a Linux kernel with commit 623c6f719c133bd2d5d3887b1acfa8ffe063ae09 or later.

References

- Linux Kernel Patch Commit
- drm_atomic_get_crtc_state() (Linux DRM API)
- CVE-2024-56776 on MITRE
- Linux Kernel Documentation: Error Pointers

Conclusion

CVE-2024-56776 is a perfect example of how small oversights in error handling can have big side effects—even in world-class open source projects like Linux. If you code for the kernel—or just care about secure devices—always check your pointers!

Timeline

Published on: 01/08/2025 18:15:18 UTC
Last modified on: 01/09/2025 21:41:40 UTC