Skip to main content
Vulnerability Database/CVE-2026-89483

CVE-2026-89483: Linux Kernel Use-After-Free Vulnerability

CVE-2026-89483 is a use-after-free vulnerability in the Linux kernel NVMe subsystem affecting discard operations. Uninitialized memory exposure can leak sensitive data to storage controllers. This article covers technical details, affected versions, security impact, and mitigation strategies.

Published:

CVE-2026-89483 Overview

CVE-2026-89483 is an information disclosure vulnerability in the Linux kernel's NVMe subsystem. The flaw resides in nvme_setup_discard(), which always maps a 4096-byte Dataset Management (DSM) payload regardless of how many ranges a discard command declares. When the primary kzalloc(GFP_ATOMIC | __GFP_NOWARN) allocation fails under memory pressure, the code falls back to a per-controller ctrl->discard_page allocated via alloc_page(GFP_KERNEL) without zeroing. The uninitialized tail bytes, potentially containing vmemmap struct page pointers and other kernel data, are then transmitted to the storage controller, which for NVMe/TCP means they traverse the network.

Critical Impact

Up to 4080 bytes of uninitialized kernel memory can leak to remote NVMe/TCP controllers, exposing kernel pointers useful for defeating KASLR and enabling further exploitation.

Affected Products

  • Linux kernel NVMe subsystem (drivers/nvme/host/core.c)
  • Systems using NVMe over TCP (nvme-tcp) transport
  • Kernel versions prior to the fixes referenced in the stable git commits

Discovery Timeline

  • 2026-09-11 - CVE-2026-89483 published to NVD
  • 2026-09-14 - Last updated in NVD database

Technical Details for CVE-2026-89483

Vulnerability Analysis

The vulnerability is a classic uninitialized memory disclosure [CWE-908] in the NVMe host driver. A single-range discard command populates only the first 16 bytes of a struct nvme_dsm_range array sized for NVME_DSM_MAX_RANGES (256 entries, 4096 bytes total). The kernel deliberately over-maps this buffer because some devices ignore the 'Number of Ranges' field and read past the declared entries.

Under normal operation, kzalloc() guarantees the remaining 4080 bytes are zero. The fallback path breaks this assumption: nvme_init_ctrl() obtains the per-controller discard_page via alloc_page(GFP_KERNEL), which does not clear page contents. A KMSAN report reproduced the leak by forcing the atomic allocation to fail, showing bytes 16 through 2843 as uninitialized during a dma_map_phys() call originating from nvme_tcp_try_send().

Root Cause

The root cause is inconsistent initialization semantics between the primary and fallback allocation paths for the DSM payload buffer. The primary path uses kzalloc() while the fallback per-controller page is allocated once via alloc_page(GFP_KERNEL) and reused across many discard operations without being zeroed between uses.

Attack Vector

Triggering the leak requires the atomic kzalloc to fail, which practically means sustained memory pressure on the initiator host. It is not remotely triggerable by an attacker directly. However, once triggered on an NVMe/TCP initiator, the uninitialized bytes are transmitted over the network as part of the DSM payload to the target controller. An adversary with visibility into NVMe/TCP traffic, or control over a malicious NVMe target, can passively collect kernel pointers and other residual memory contents useful for bypassing Kernel Address Space Layout Randomization (KASLR).

The fix is a one-line change: allocate the fallback page with __GFP_ZERO so unwritten bytes remain zero, and bytes overwritten by prior discard commands hold only that controller's own range list, which it has already received.

Detection Methods for CVE-2026-89483

Indicators of Compromise

  • KMSAN or KASAN reports flagging uninitialized memory reads in dma_map_phys originating from nvme_tcp_try_send or nvme_tcp_queue_rq
  • Kernel log entries indicating kzalloc(GFP_ATOMIC | __GFP_NOWARN) allocation failures in the NVMe discard path under memory pressure
  • NVMe/TCP DSM payload captures containing non-zero data beyond the declared range count (past offset 16 for single-range discards)

Detection Strategies

  • Audit running kernels against the fixed commit hashes (f5827817b4fc, dc4d4b70a863, 66b5af23b6f9, bededeaaeff4, 76139b5bbf53, 67551d8430df, 415f2772ebcb, 3f84d2bd0d8a) to identify unpatched systems
  • Inspect NVMe/TCP network traffic in test environments for DSM commands that contain kernel pointer patterns in unexpected offsets
  • Monitor host memory pressure metrics and correlate with NVMe discard I/O activity, since the fallback path is only reached during low-memory conditions

Monitoring Recommendations

  • Track kernel version inventory across NVMe/TCP initiators and prioritize hosts running kernels prior to the referenced stable fixes
  • Alert on repeated nvme subsystem warnings related to atomic allocation failures, which increase the probability of triggering the leak
  • Capture packet metadata for NVMe/TCP sessions traversing untrusted network segments to identify exposure paths

How to Mitigate CVE-2026-89483

Immediate Actions Required

  • Apply the upstream Linux kernel patches that add __GFP_ZERO to the discard_page allocation in nvme_init_ctrl()
  • Update to the stable kernel releases that incorporate the referenced fix commits from git.kernel.org
  • Restrict NVMe/TCP traffic to isolated, trusted storage network segments to reduce passive exposure of any leaked bytes

Patch Information

The fix modifies the single allocation site for the per-controller discard_page to include __GFP_ZERO, guaranteeing the buffer is zero-initialized on allocation. Reference commits include 3f84d2bd0d8a, 415f2772ebcb, 66b5af23b6f9, 67551d8430df, 76139b5bbf53, bededeaaeff4, dc4d4b70a863, and f5827817b4fc.

Workarounds

  • Encrypt NVMe/TCP transport using TLS (NVMe/TCP with TLS 1.3) to prevent passive network observers from harvesting leaked bytes
  • Ensure sufficient headroom in host memory to make GFP_ATOMIC allocation failure unlikely, reducing the chance of reaching the vulnerable fallback path
  • Where NVMe/TCP is not required, prefer PCIe-attached NVMe or fabric transports on physically isolated storage networks until patched
bash
# Verify the running kernel version against known-fixed stable releases
uname -r

# List NVMe/TCP connections currently established on the host
nvme list-subsys -o json | grep -i tcp

# Check for atomic allocation failures in dmesg that may indicate exposure
dmesg | grep -Ei 'nvme|page allocation failure'

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.