In 2021, a vulnerability labeled as CVE-2021-47009 was discovered in the Linux kernel, specifically affecting the way "trusted keys" were handled in the Trusted Platform Module (TPM) subsystem. This issue led to a memory leak, which could degrade a system's performance or cause it to run out of memory if repeatedly triggered. In this long-read post, we'll break down what happened, show you exactly where and why, and explore the details of the fix. This article is written in simple, easy-to-follow language, with clear code examples and references.

What Are Trusted Keys and the Trusted TPM1 Module?

Linux supports *trusted keys*—a way to store encryption keys more securely, often tied to hardware security modules like TPM chips.

The affected code is found in

security/keys/trusted-keys/trusted_tpm1.c

Here, the kernel works with "trusted objects," and uses a structure named td to hold information about a key.

The Memory Leak

Simply put, memory allocated for the structure td was sometimes not freed when an error occurred. This is called a memory leak: memory gets reserved for a program but never used again, which is wasteful and can, over time, weaken or even crash your system.

The issue was caught—and flagged—by the Clang static analyzer, which reported

security/keys/trusted-keys/trusted_tpm1.c:496:10: warning: Potential memory leak [unix.Malloc]

Here's how it happened, using simple pseudo-code to illustrate the relevant function

struct trusted_key_payload *td = kmalloc(sizeof(*td), GFP_KERNEL);
if (!td)
    return -ENOMEM;

// Do some stuff...

if (something_bad_happens) {
    // Oops, no kfree(td) here!
    return -EIO;
}

// All good: use td, then free it later

See the problem? If something_bad_happens, the code just returns, but forgets to call kfree(td). So the memory for td is never returned to the system.

Actual Vulnerable Code Snippet

Here’s a snippet extracted from the original kernel source (commit diff reference):

struct trusted_key_payload *td;

// ...
td = kmalloc(sizeof(*td), GFP_KERNEL);
if (!td)
    return -ENOMEM;
 
// ... do some operations ...

if (wrong_condition1)
    return -EFAULT;  // td not freed!
if (wrong_condition2)
    return -EINVAL;  // td not freed!

// Normal flow uses td and eventually frees it.

The Exploit Scenario

While this bug is not directly exploitable for privilege escalation or code execution, it can be abused by:

- Unprivileged or malicious processes repeatedly triggering the error path (e.g., calling the trusted-key create API with bad parameters),

Each time leaking a bit of kernel memory.

Over time, this consumes enough memory to cause system performance problems or denial-of-service (by exhausting available RAM).

Attackers could write a simple loop in C or Python to call the affected function with bad data until the kernel ran out of memory.

How Was It Fixed?

The fix was to reorganize the error handling—making all error exit points go through a single cleanup path that freed td:

if (error) 
    goto out;

out:
    kfree(td);
    return ret;

Fixed Example

struct trusted_key_payload *td;

td = kmalloc(sizeof(*td), GFP_KERNEL);
if (!td) {
    ret = -ENOMEM;
    goto out;
}

// ...use td...

if (something_wrong) {
    ret = -EFAULT;
    goto out;
}

out:
    kfree(td);
    return ret;

Now, no matter *how* the function ends, the memory is always released. This is a classic way in C programming to prevent resource leaks.

References & Further Reading

- Official kernel patch fixing CVE-2021-47009
- NVD entry for CVE-2021-47009
- Clang Static Analyzer
- Trusted Keys Kernel Documentation
- Linux Key Management

Conclusion

CVE-2021-47009 teaches a valuable lesson—always clean up after yourself in code, especially in systems programming, where a missed free can cause real-world headaches.

This bug was quietly fixed in Linux once discovered, but its simplicity makes it a perfect example of how even small mistakes can have big consequences in the kernel.

If you're a developer: always check your error handling, use tools like static analyzers, and try to use a single "cleanup exit path" to prevent leaks and confusion!


*Thanks for reading! For more deep dives and simple explanations on kernel security, stay tuned!*

Timeline

Published on: 02/28/2024 09:15:38 UTC
Last modified on: 12/09/2024 18:24:16 UTC