CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-68233
5.50.04%

The Zombie PID Factory: Bleeding Kernel Memory in NVIDIA Tegra

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 18, 2026·6 min read·3 visits

No Known Exploit

Executive Summary (TL;DR)

The NVIDIA Tegra DRM driver forgot to release PID references after using them. Local attackers with access to the GPU render node can trigger infinite kernel memory leaks, eventually causing a Denial of Service (DoS) by exhausting the slab allocator.

A resource leak vulnerability in the Linux Kernel's `drm/tegra` subsystem allows local users to exhaust kernel memory by creating zombie PID references. The flaw stems from a missing `put_pid()` call in the interaction between `get_task_pid()` and `host1x_memory_context_alloc()`, turning the Tegra driver into a black hole for process structures.

The Hook: Garbage Collection is for cowards

Welcome to the Linux Kernel, where memory management is manual and forgetting to take out the trash can bring down an entire system. Today's subject is the drm/tegra subsystem, the Direct Rendering Manager driver for NVIDIA's Tegra System-on-Chip (SoC) series. These chips power everything from embedded AI boxes to automotive dashboards and the Nintendo Switch. In the world of kernel drivers, managing the lifecycle of objects is critical. When a driver needs to track a user-space process, it often grabs a reference to that process's PID structure.

In C, unlike managed languages like Python or Java, there is no garbage collector to sweep up your mess. If you grab a reference to an object, you are contractually obligated to release it. It's the "pottery barn rule" of kernel development: if you touch it, you probably own it until you say otherwise. Reference counting is the mechanism that keeps the kernel sanity intact.

CVE-2025-68233 is a classic tale of "I thought you were watching the kids." One function grabbed a reference, passed it to another, and assumed the recipient would handle the cleanup. The recipient, however, just borrowed it and walked away. The result? A struct pid that lives forever, occupying kernel memory long after the actual process has died—a zombie in the truest sense.

The Flaw: The Case of the Missing `put_pid()`

To understand this bug, you have to understand how Linux tracks processes. The kernel uses struct pid to represent a PID. Because PIDs are shared resources (used by signals, file descriptors, and drivers), they are reference-counted. The function get_task_pid() is used to acquire a reference. Internally, this increments an atomic counter. As long as that counter is greater than zero, the kernel cannot free the memory associated with that structure.

The vulnerability resides in the interaction between a caller function in the Tegra DRM driver and host1x_memory_context_alloc(). The code logic went something like this:

  1. The driver calls get_task_pid(current, PIDTYPE_PID) to get a handle on the current process.
  2. It passes this handle to host1x_memory_context_alloc(...) to associate a memory context with that process.
  3. The driver continues execution, assuming host1x_memory_context_alloc took ownership of the reference.

Here is the punchline: host1x_memory_context_alloc did not take ownership. It used the PID to set up some context mapping and then returned. The caller, assuming the reference was consumed, never called put_pid(). This is a resource leak. Every time this code path is triggered (likely via a specific IOCTL), the reference count on that struct pid increments. Even if the user process terminates, the struct pid remains pinned in the slab allocator because the kernel thinks the Tegra driver is still using it.

The Code: Autopsy of a Leak

Let's look at the smoking gun. The fix is embarrassingly simple, which highlights just how easy it is to miss these things during code review. The patch was applied to drivers/gpu/drm/tegra/uapi.c (or similar call site depending on the specific kernel version structure).

The Vulnerable Pattern:

// Get a reference to the current task's PID
struct pid *pid = get_task_pid(current, PIDTYPE_PID);
 
// Allocate the context. 
// DEVELOPER ASSUMPTION: This function consumes 'pid'.
err = host1x_memory_context_alloc(client->host, dev, pid);
if (err < 0)
    goto error;
 
// ... execution continues, 'pid' is never put.

The Fix (Commit 6b572e5154af08ee13f8d2673e86f83bc5ff86cd):

struct pid *pid = get_task_pid(current, PIDTYPE_PID);
 
err = host1x_memory_context_alloc(client->host, dev, pid);
 
// FIX: We must release our reference to the PID here.
// host1x_memory_context_alloc does not take ownership.
put_pid(pid);
 
if (err < 0)
    goto error;

It is literally one line of code: put_pid(pid). Without this line, the struct pid leaks. While a single struct pid is small (a few hundred bytes), the accumulation causes fragmentation in the kernel's slab allocator (kmalloc caches). Furthermore, if the system has limits on the number of PID structures (not just the numerical PID value, but the backing memory), this can lead to an inability to spawn new processes or allocate kernel objects.

The Exploit: Death by a Thousand Allocations

Exploiting this is trivial but tedious. It's not a flashy RCE where you pop a shell; it's a Denial of Service (DoS) where you choke the system until it turns blue. The attack requires access to the DRM device, typically /dev/dri/renderD128 or /dev/dri/card0. On most desktop and embedded Linux systems, any user in the video or render group has this access. This means a compromised low-privilege service or a local user can trigger it.

The Attack Chain:

  1. Open Device: The attacker opens a file descriptor to the Tegra DRM device.
  2. Trigger Allocation: The attacker calls the specific IOCTL that triggers the host1x_memory_context_alloc path. This creates a new context—and leaks one PID reference.
  3. Loop: The attacker repeats step 2 indefinitely. They don't even need to fork new processes; they can use the same process ID. The reference count on their own PID will simply increment to INT_MAX.
  4. The Crash: Eventually, one of two things happens:
    • The reference counter overflows (if not saturated/protected), leading to Use-After-Free (UAF) potential (unlikely in modern kernels with refcount hardening).
    • The kernel runs out of memory (OOM). Specifically, the slab cache for struct pid or general kmalloc pools becomes exhausted. The OOM killer might trigger, but it can't free the leaked structures because the kernel still thinks they are in use.

The beauty of this attack is its stealth. It looks like legitimate heavy usage of the GPU until the system suddenly freezes.

The Impact: Embedded Systems on Life Support

Why does this matter? Tegra chips are frequently used in "set-and-forget" devices: automotive infotainment, medical imaging displays, and edge AI boxes. These systems often run for months or years without rebooting. A slow memory leak here is a ticking time bomb. It might take a week or a month, but eventually, the device will become unstable and crash.

From a security perspective, this is a local DoS. In a multi-tenant environment (like a shared compute cluster using Jetson boards), one malicious user can bring down the node for everyone else. While it scores low on the CVSS scale (usually around 5.5 for local DoS), the operational impact on mission-critical embedded systems is high. You don't want your car's dashboard rebooting because a background process leaked too many PIDs.

Additionally, this highlights a weakness in code auditability. The mismatch between "caller frees" and "callee frees" semantics is a perennial source of bugs in C. Unless clearly documented, host1x_memory_context_alloc is an ambiguity trap waiting to snare the next developer who touches this code.

Official Patches

Linux KernelOfficial Git Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
5.5/ 10
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.04%
Top 89% most exploited

Affected Systems

Linux Kernel 6.0 through 6.17 (Tegra builds)NVIDIA Jetson devices (Orin, Xavier, etc.) running vulnerable kernelsEmbedded systems using CONFIG_DRM_TEGRA

Affected Versions Detail

Product
Affected Versions
Fixed Version
Linux Kernel
Linux
>= 6.0, < 6.1.1596.1.159
Linux Kernel
Linux
>= 6.2, < 6.6.1186.6.118
Linux Kernel
Linux
>= 6.7, < 6.12.606.12.60
AttributeDetail
CWE IDCWE-401 (Memory Leak)
Attack VectorLocal (IOCTL)
CVSS v3.1 (Est)5.5 (Medium)
EPSS Score0.00037
Kernel Subsystemdrm/tegra
Exploit MaturityPoC Possible (Trivial)

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
T1499.001OS Exhaustion
Impact
CWE-401
Improper Release of Memory Before Removing Last Reference

Improper Release of Memory Before Removing Last Reference ('Memory Leak')

Vulnerability Timeline

Patch applied to stable branches
2024-12-01
CVE Published
2024-12-16

References & Sources

  • [1]NVD Entry
  • [2]Kernel Source Patch

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.