In the world of Linux kernel development, small mistakes can lead to big problems. One such issue, tracked as CVE-2022-49365, was discovered in the amdgpu graphics driver. This bug was subtle—a classic off-by-one error—that could let attackers break out of an array's limits, with real potential for causing system instability or possibly even attacks. Let’s break it down, simple and straight.

Background: AMDGPU and Outbox IRQs

AMDGPU is the open-source Linux driver for AMD graphics cards. It manages communication between the system and the GPU. Part of this process involves handling "outbox" interrupts—a way for the GPU to send data or alerts back to the main system.

The outbox buffers involved are arrays of data, and the kernel code must be careful about how it reads or writes to these arrays. Accessing elements past the end can lead to undefined behavior, including memory corruption.

The Vulnerability (CVE-2022-49365)

The bug was found in the dmub_outbox1_low_irq() function. This function handles certain message queues from the GPU. The critical mistake was an *off-by-one* error during array access. Here’s what happened:

Accessing memory out of bounds can crash the kernel (panic).

- In more dangerous cases, a local attacker could exploit this to gain elevated privileges or leak sensitive data.

Let’s look at the relevant code snippet. The risky check was written as

if (i > ARRAY_SIZE(my_array))
    break;

But here’s the problem: ARRAY_SIZE(my_array) returns the number of elements in the array. But valid indices start at and end at (ARRAY_SIZE - 1). So this check didn’t prevent the code from stepping one slot too far.

It should have been

if (i >= ARRAY_SIZE(my_array))
    break;

Why?
Because when i equals ARRAY_SIZE(my_array), that’s already *out of bounds*—time to stop.

Visual Example

Suppose this array has 4 items:
So, ARRAY_SIZE(my_array) == 4.
Valid i values: , 1, 2, 3 (total of 4 items)

With i > 4, we only prevent access when i == 5 and on.
With i >= 4, we stop as soon as i == 4 (which is out of bounds).

Only crash the kernel (denial-of-service)

No known "weaponized" public exploits exist, but the pattern is a textbook kernel bug that attackers always look for.

The Patch: Fixing the Off-By-One

The fix was simple and effective.

Change

if (i > ARRAY_SIZE(my_array))
    break;

to

if (i >= ARRAY_SIZE(my_array))
    break;

Here’s a full snippet highlighting the corrected logic

#define OUTBOX_SIZE 16
uint32_t my_array[OUTBOX_SIZE];

for (i = ; ; i++) {
    if (i >= ARRAY_SIZE(my_array))
        break;
    // Safely access my_array[i]
}

This ensures the loop never reads or writes outside the array.

Official Patch Example:
Linux kernel commit on github

References

- CVE-2022-49365 NVD Entry
- Kernel.org commit log
- Linux DRM AMDGPU driver docs
- ARRAY_SIZE macro definition

Conclusion

CVE-2022-49365 is a classic case that shows how a tiny detail—> versus >=—can have huge consequences in system-level code. The Linux kernel’s AMDGPU driver handled this quickly, so update your kernel or drivers ASAP if you use AMD GPUs. Want to avoid similar bugs in your code? Always be careful with array bounds, and prefer using helper macros like ARRAY_SIZE to keep things safe.

Stay tuned for more deep dives into kernel security—sometimes, it’s the little things that matter most!

Timeline

Published on: 02/26/2025 07:01:13 UTC
Last modified on: 05/04/2025 08:36:08 UTC