---
Overview
In 2021, a vulnerability was found and patched in the Linux kernel, tracked as CVE-2021-46985. The security issue lay in the Advanced Configuration and Power Interface (ACPI) subsystem, specifically during the device scan process. The vulnerability was a potential memory leak that could be triggered on certain error paths. Although this may not seem severe, memory leaks can slowly drain system resources if exploited repeatedly by malicious or buggy code.
In this post, I'll break down what CVE-2021-46985 is, how it works, how to exploit it, and how it was fixed, all using simple language and direct code examples.
What is CVE-2021-46985?
CVE-2021-46985 refers to a bug in the Linux kernel that occurs when setting the name of an ACPI device fails. If this naming function (acpi_device_set_name()) fails, the code path forgets to free a previously allocated memory, leading to a memory leak.
This was present in a function called during the ACPI device scan process
bus_id = kcalloc(1, sizeof(*bus_id), GFP_KERNEL);
if (!bus_id)
return NULL;
bus_id->bus_id = kstrdup(str, GFP_KERNEL);
if (!bus_id->bus_id)
goto err_alloc;
if (acpi_device_set_name(device, bus_id->bus_id)) {
// Memory leak: bus_id->bus_id is not freed here!
goto err_alloc;
}
If acpi_device_set_name() fails, bus_id->bus_id (the actual memory allocated for the device's name) is left dangling, never freed.
Impact
Although this bug won't let an attacker compromise system security directly, repeated exploitation (malicious code continuously triggering the leak) can:
Exploit Details
Pre-requisite: You need to trigger a failure in the acpi_device_set_name() function, causing its error path to activate.
Here's a step-by-step example of how this could be tested or exploited (for demonstration in a controlled environment only):
1. Forced Failure Path
You'd require a way to call acpi_device_set_name() with data that will make it fail. This is tricky without writing kernel modules or exploiting specific conditions, but a proof-of-concept module could look like this (don't run on production systems):
#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/slab.h>
static int __init vuln_test_init(void) {
struct acpi_device *device = ...; // Get/allocate a dummy device
size_t len = 1024;
char *name = kmalloc(len, GFP_KERNEL);
memset(name, 'X', len - 1);
name[len - 1] = '\';
// Passing an absurdly long device name to trigger possible failure
if (acpi_device_set_name(device, name)) {
pr_info("acpi_device_set_name failed, would have leaked name buffer before fix!\n");
}
kfree(name);
return ;
}
module_init(vuln_test_init);
MODULE_LICENSE("GPL");
In this contrived example, we try to make acpi_device_set_name() fail by overloading it with an extremely long name. On pre-patched kernels, this would leak the memory allocated for name.
The fix simply frees the allocated memory if the error path is entered
if (acpi_device_set_name(device, bus_id->bus_id)) {
kfree(bus_id->bus_id); // <-- The crucial addition!
goto err_alloc;
}
Reference:
- Kernel Patch Commit
Full commit message
> If acpi_device_set_name() fails, we must free the memory allocated for bus_id->bus_id or there is a potential memory leak.
Recommendations
- Upgrade your kernel: Ensure you're running a kernel with this fix merged (check your distro's advisories for details).
- Monitor for suspicious kernel memory usage: Unusual leaks may still be possible from other bugs; keep an eye on system health.
Learn More
- CVE-2021-46985 on NVD
- Linux Kernel ACPI Subsystem
- Memory Leak Detection in the Linux Kernel
Conclusion
CVE-2021-46985 is a classic example of how a small oversight in error handling can cause memory management issues in critical software like the Linux kernel. While not remotely exploitable without special privileges, it is a reminder of the need for careful resource handling, especially in C code at the heart of the system. Always patch your systems, and be mindful of error handling in your own code.
*Exclusive deep dive by User Request. For educational use only. Do not attempt unauthorized testing on production systems.*
Timeline
Published on: 02/28/2024 09:15:37 UTC
Last modified on: 12/06/2024 15:02:17 UTC