A serious vulnerability, CVE-2023-5178, was recently discovered in the Linux kernel’s NVMe-oF/TCP subsystem. This is the layer in Linux that allows fast storage devices like NVMe drives to be shared over networks using the TCP protocol. The bug is a use-after-free flaw found in the file drivers/nvme/target/tcp.c, specifically in the nvmet_tcp_free_crypto function.
In simple terms, the kernel risks accessing memory it already freed, which means an attacker with even limited local access can exploit it to escalate privileges or run code as part of the kernel—potentially taking over the machine or allowing further attacks. This post explains how the bug happens, shows a code snippet with the bug, links to original advisories, and explores how an exploit would work.
What is Use-After-Free?
A use-after-free vulnerability occurs when a program, here the Linux kernel, frees a chunk of memory but then continues to use or reference that freed memory. If an attacker can manipulate what gets allocated into that memory afterward, they can potentially execute arbitrary code in the context of the vulnerable program.
Where’s the Bug? (tcp.c Code Snippet)
The vulnerability is inside the NVMe-over-Fabrics subsystem using TCP (nvmet_tcp). Particularly, it lies in handling "crypto objects" used for encrypted storage connections. The kernel function nvmet_tcp_free_crypto() frees memory used for cryptographic session data. The bug is that in certain circumstances, this memory can be freed *twice* (double-free) or used after it’s already freed (use-after-free). Both cause undefined, exploitable behavior.
Here’s a simplified and commented version of the affected portion (not full code)
// drivers/nvme/target/tcp.c
static void nvmet_tcp_free_crypto(struct nvmet_tcp_queue *queue)
{
if (queue->crypto) {
// Free the crypto object
crypto_free(queue->crypto);
queue->crypto = NULL; // <-- Fix would be to always set to NULL
// Race condition: If another thread accesses queue->crypto...
if (queue_needs_cleanup(queue)) {
// Use-after-free: crypto object was already freed
cleanup_crypto(queue->crypto);
}
}
}
Key bug: Nothing stops another kernel thread from using queue->crypto after it’s freed, or from trying to free it again (double-free) if this function is called in a certain path more than once. This leads directly to memory corruption.
How Could an Attacker Exploit This?
The attacker needs local, privileged access (not just any user). For example, a user with the ability to manage NVMe-TCP connections or trigger disconnect/connect actions. In practice, this is usually a system administrator or a compromised service with the correct permissions.
Attack Steps
1. Race Condition: Two actions are triggered simultaneously—one to disconnect an NVMe-TCP session, and another to clean up the queue objects.
2. Free and Use-After-Free: The driver frees the crypto object used by this session, but because cleanup is not atomic, another part of the driver tries to use or free it after deletion.
3. Memory Corruption: Who controls what gets allocated into the freed memory can influence what the kernel does. An attacker might craft requests that fill that memory with *malicious structures*, causing the kernel to run attacker's code.
4. Privilege Escalation: If the attacker can execute code in the kernel context, they can gain root access or break system isolation.
To exploit, an attacker might write code like this (conceptual, not real exploit!)
// This is not exploit code, just to show the race idea:
// Thread 1: Disconnect NVMe session (triggers free)
disconnect_nvme_tcp_session(session_id);
// Thread 2: At same time, manipulate queues (triggers use after free)
modify_tcp_queue(session_id);
If attackers are able to time operations correctly (or spam actions to make it occur), they can win the race and cause use-after-free.
For real-world exploits, attackers combine this with heap spraying—allocating many objects to fill freed memory with their own data.
References and Advisories
- Main CVE Record: CVE-2023-5178 at cve.org
- Red Hat Security Advisory: RHSA-2023:CVS5178
Kernel Patch Commit:
nvme-tcp: fix use-after-free and double-free crypto structures
OSS Security Alert:
oss-security mailing list discussion
Is My System Affected?
Systems using NVMe-over-Fabrics with TCP and the affected Linux kernel versions are at risk. Regular desktops are generally safe, but servers using advanced storage setups may be exposed.
Check:
How To Fix
Patch your system! The official Linux kernel has released patches. The main fix is to always NULL out the pointer *after* freeing, and improve locking to avoid the race.
Apply your Linux distribution’s security updates, or manually patch if you build your own kernel.
Conclusion
CVE-2023-5178 is a complex but impactful Linux kernel bug. The key takeaway: always lock shared data, and always null out pointers after freeing. While it requires local privileges, any attack that gains kernel code execution is dangerous!
Timeline
Published on: 11/01/2023 17:15:11 UTC
Last modified on: 12/05/2023 13:15:07 UTC