In early 2024, a critical double-free vulnerability (CVE-2024-26932) was identified and promptly patched in the Linux kernel’s USB Type-C Port Manager (tcpm). This bug could potentially cause denial of service or even allow more severe memory corruption and exploitation on affected systems. In this post, we'll break down what happened, what the root cause was, and show you exclusive, easy-to-understand details—including code snippets and the exact fix.
What is CVE-2024-26932?
CVE-2024-26932 refers to a double-free bug in the Linux kernel's Type-C Port Manager (tcpm) subsystem. A double-free occurs when a program tries to free (deallocate) the same block of memory more than once, leading to unpredictable behavior, application crashes, or exploitable security vulnerabilities.
Vulnerable component:
- File: drivers/usb/typec/tcpm/tcpm.c
How Was It Found?
The bug was identified by the Kernel Address Sanitizer (KASAN), which flagged a double-free during device unregister operations. Here’s what the report looked like:
[ 3.988059] BUG: KASAN: double-free in tcpm_port_unregister_pd+x1a4/x3dc
[ 3.995001] Free of addr ffff0008164d300 by task kworker/u16:/10
...
[ 4.052069] tcpm_port_unregister_pd+x1a4/x3dc
Root Cause: A Closer Look
The main cause of the bug is that the same memory—representing Power Delivery (PD) capability data—was being freed twice:
A second time by an explicit kfree() call in tcpm_port_unregister_pd().
This could lead to kernel panic or even open doors for kernel-level exploitation.
Here’s a simplified version of the problematic code (actual locations might differ slightly)
static void tcpm_port_unregister_pd(struct tcpm_port *port)
{
// ...
pd_capabilities_release(port->pd_capabilities);
// Vulnerable: calling kfree again on already-freed memory
kfree(port->pd_capabilities);
// ...
}
pd_capabilities_release() already handles freeing port->pd_capabilities, so the extra kfree is unnecessary—and dangerous.
The Fix: Simple but Effective
The fix is straightforward: Remove the redundant kfree() call. After pd_capabilities_release() has run, you must NOT free the same memory block again.
Patch Diff
Here’s the crucial line from the upstream patch:
- kfree(port->pd_capabilities); // <-- This line removed
So the function now looks like
static void tcpm_port_unregister_pd(struct tcpm_port *port)
{
...
pd_capabilities_release(port->pd_capabilities);
// kfree removed, double-free eliminated
...
}
Exploit Details
Impact:
*Denial of Service*: Kernel crash (panic) upon device unregistration.
- *Memory Corruption*: Under the right conditions, could be used as a stepping stone for kernel privilege escalation.
Reproduction
A local user or code running with suitable rights could trigger this by repeatedly registering and unregistering Type-C ports, eventually causing a double-free.
Proof of Concept (PoC)
WARNING
Never run this unless you are testing in a safe, virtualized, or isolated environment!
// Pseudo-code to reproduce the bug
struct tcpm_port *port = create_and_register_tcpm_port();
unregister_and_release_tcpm_port(port); // Triggers tcpm_port_unregister_pd
With KASAN enabled, you’ll see double-free reports as above.
Are you affected?
- Kernel versions before 6.8.-rc5 (February 2024) with Type-C/PD enabled could be vulnerable.
Mitigation
- Upgrade your kernel to the version containing the fix (see the patch, included in 6.8 and later).
References & Further Reading
- Commit on kernel.org
- Upstream patch on lore.kernel.org
- KASAN Documentation
- Linux USB Type-C subsystem
In Summary
CVE-2024-26932 is a textbook example of a double-free bug, caught thanks to modern kernel debugging tools and swiftly patched by the Linux community. If you maintain devices or products with USB Type-C (PD) support, make sure you’re patched—double-frees are never harmless, especially in the kernel!
Stay tuned for more plain-English breakdowns of important Linux security updates.
If you want more information on this or latest security patches, let us know!
Timeline
Published on: 05/01/2024 06:15:07 UTC
Last modified on: 07/03/2024 01:50:02 UTC