Summary:
A subtle but dangerous bug was discovered in the Linux kernel within AMD’s Display Core (DC) driver code, specifically dealing with HDCP (High-bandwidth Digital Content Protection) messages over HDMI. Known officially as CVE-2021-47046, the issue was an “off by one” array read, potentially exposing kernel memory and possibly making way for further exploitation.
Let’s break down what this means in simpler terms, look at the code that was affected, and talk about how it was fixed.
What Exactly Was the Bug?
In computer programming, when you access outside the intended size of an array, it’s called an out-of-bounds or off-by-one error. These errors can lead to security weaknesses because they allow attackers to read or write memory that should be protected.
Here, the bug existed in the AMD Display driver’s code that processes HDCP messages sent over HDMI connections. A particular array, called hdcp_i2c_offsets, was missing an entry for a message type called HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE. When this type of message was encountered, the code would read past the end of the array—a classic off-by-one bug.
Let’s focus on the key snippet
static uint8_t hdcp_i2c_offsets[] = {
/* offsets for different message types */
[HDCP_MESSAGE_ID_AKE_INIT] = x00,
[HDCP_MESSAGE_ID_AKE_SEND_CERT] = x00,
// ...
// [HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] -- MISSING!
// ...
};
Somewhere else in the code, when HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE arrived, the code expected that hdcp_i2c_offsets would have a value for it. Since it didn’t, it would access one byte past the end of the array.
Why it matters:
Accessing memory out-of-bounds can leak kernel data or potentially escalate into more severe vulnerabilities with crafty exploitation.
How Was It Fixed?
The fix was straightforward: the missing entry was added to the array, with a value (x) consistent with similar message types. Additionally, the arrays were changed to explicitly use the size HDCP_MESSAGE_ID_MAX, to “future-proof” things against similar mistakes later:
static uint8_t hdcp_i2c_offsets[HDCP_MESSAGE_ID_MAX] = {
[HDCP_MESSAGE_ID_AKE_INIT] = x00,
[HDCP_MESSAGE_ID_AKE_SEND_CERT] = x00,
// ...
[HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = x00, // Fixed!
};
By declaring the size with HDCP_MESSAGE_ID_MAX, any new message types would also be within bounds.
Exploitability: Should I Worry?
This vulnerability enables an out-of-bounds *read* (not write). That means an attacker could, in theory, trick the kernel into reading a byte past the end of the offsets array. In practice:
- Direct code execution: Unlikely from just a single OOB read, unless the read leaks sensitive kernel memory or aids in a more complex attack, such as info-leak used in kernel exploitation chains.
- Impact: Limited to scenarios where untrusted software or hardware can send arbitrarily crafted HDCP messages via HDMI to a vulnerable AMD graphics device.
However, any kernel OOB bug is *always* taken seriously due to the risk potential, even if an exploit is tricky.
## Proof-of-Concept / Demonstration
Here’s a minimal demonstration to explain the vulnerability in pseudocode
#define MAX_MESSAGES 5
uint8_t offsets[MAX_MESSAGES] = { , 1, 2, 3, 4 }; // Only 5 entries
void process_message(int msg_id) {
uint8_t offset = offsets[msg_id]; // No bounds check!
printf("Offset: %d\n", offset);
}
// Now if we call: process_message(5); --> will read outside the array!
In real life, this would correspond to the missing HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE which had a value of 5 (for example), but there were only 5 entries (indices -4) in the array.
References & Links
- CVE Details Page
- The Linux Kernel Patch Commit
- AMD’s Display Driver Directory
Even the tiniest off-by-one mistake in kernel code can introduce vulnerabilities.
- Declaring array sizes with symbolic constants (HDCP_MESSAGE_ID_MAX) not only improves code clarity but helps prevent subtle bugs.
If you work with kernel drivers, always make sure array sizes and bounds checks are rock solid.
If you manage systems with AMD graphics and the Linux kernel, make sure you’re running a version with this fix applied!
*Exclusive writeup by AI – referencing primary sources only. Always check with your operating system distributor for kernel security updates.*
Timeline
Published on: 02/28/2024 09:15:40 UTC
Last modified on: 12/09/2024 19:02:52 UTC