CVE-2026-89801 in Linux
Summary
by MITRE • 09/16/2026
In the Linux kernel, the following vulnerability has been resolved:
drm/nouveau/uvmm: fix premature region free on failed OP_UNMAP_SPARSE
In nouveau_uvmm_bind_job_submit()'s OP_UNMAP_SPARSE arm, op->reg is set from nouveau_uvma_region_find(), which only looks the region up and takes no reference; a region's sole reference is its membership in uvmm->region_mt. Two failure paths leave op->reg set: the -ENOENT check when the region is busy, and the drm_gpuvm_sm_unmap_ops_create() failure. The sibling nouveau_uvmm_sm_unmap_prepare() failure just below clears op->reg; these two do not.
unwind_continue steps back one op, so the failing op is skipped by the unwind loop and its op->reg stays set. nouveau_uvmm_bind_job_cleanup() then enters its if (op->reg) branch and calls nouveau_uvma_region_remove() and nouveau_uvma_region_put() on it, dropping the tree's sole reference and freeing a region this job never created. The comment above the cleanup loop documents the broken invariant: op->reg must be NULL on submit failure.
This frees a live region on an unrelated failure, reachable single-job when drm_gpuvm_sm_unmap_ops_create() returns -ENOMEM; if another job owns the same region, its cleanup then removes and puts the freed region, a use-after-free. Clear op->reg on both failure paths.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.
Analysis
by VulDB Data Team • 09/16/2026
The vulnerability identified in the Linux kernel's Nouveau DRM driver involves a critical memory management flaw within the Unified Virtual Memory Manager (UVMM) subsystem, specifically during the handling of sparse unmap operations. The core issue resides in the nouveau_uvmm_bind_job_submit function when processing OP_UNMAP_SPARSE commands. In this code path, the operation structure's region pointer is populated by calling nouveau_uvma_region_find, which performs a lookup without incrementing the reference count for that memory region. Consequently, the only existing reference to the region object remains its membership within the uvmm->region_mt radix tree. This design relies heavily on strict adherence to cleanup protocols where any acquired references must be properly released upon completion or failure of the operation.
The technical flaw manifests when specific error conditions occur during job submission that leave the op->reg pointer set despite a failed state. Specifically, two distinct failure paths fail to clear this pointer: one triggered by an -ENOENT check indicating the region is busy, and another resulting from a memory allocation failure in drm_gpuvm_sm_unmap_ops_create returning -ENOMEM. While subsequent error handling code for nouveau_uvmm_sm_unmap_prepare correctly clears op->reg, these two earlier failures do not. This inconsistency violates the documented invariant that op->reg must be NULL upon submit failure, creating an inconsistent state within the job structure that propagates into the cleanup phase.
During the unwinding process triggered by a failed operation, the unwind_continue mechanism steps back one operation level, effectively skipping the failing operation in the subsequent loop iteration. Because op->reg was not cleared during the initial error handling of the skipped operation, it retains its value pointing to a live memory region. When nouveau_uvmm_bind_job_cleanup executes, it checks if op->reg is set and proceeds to call nouveau_uvma_region_remove and nouveau_uvma_region_put on that pointer. This action incorrectly drops the tree's sole reference count for a region that this specific job did not create or own, leading to premature deallocation of live memory structures.
The operational impact of this flaw is severe, resulting in use-after-free vulnerabilities when multiple jobs interact with overlapping memory regions. If another concurrent job owns the same region and attempts its cleanup sequence after the first job has prematurely freed it, the system accesses invalid memory. This scenario is reachable even in single-job contexts if drm_gpuvm_sm_unmap_ops_create fails due to insufficient memory (-ENOMEM). The resulting use-after-free can lead to kernel panics, data corruption, or potentially arbitrary code execution depending on how the freed memory is reallocated and accessed by other subsystems.
This vulnerability aligns with CWE-416, Use After Free, as it involves accessing memory after it has been made available for reuse without proper synchronization of ownership semantics. From a threat modeling perspective using MITRE ATT&CK techniques, this flaw could be leveraged in the context of T1059 Command and Scripting Interpreter or more specifically within kernel exploitation chains to escalate privileges by corrupting kernel data structures such as reference counts or object headers. The lack of proper error path handling represents a common class of defects where success paths are well-tested but failure paths contain logical omissions regarding resource cleanup.
Mitigation requires ensuring that op->reg is explicitly cleared on all identified failure paths within nouveau_uvmm_bind_job_submit to maintain the invariant required by the cleanup routine. Developers must verify that every branch leading to an error return state resets pointers and reference counts appropriately before exiting the function. Additionally, implementing robust static analysis tools focused on resource management invariants can help detect such discrepancies early in the development lifecycle. For system administrators, applying kernel updates that include this fix is essential to prevent potential exploitation of these memory safety violations within the graphics driver stack.