CVE-2026-80789 in Linux
Summary
by MITRE • 09/04/2026
In the Linux kernel, the following vulnerability has been resolved:
nvmet-tcp: bound SGL data length before allocating command buffers
nvmet_tcp_map_data() reads the host-controlled 32-bit sgl->length and, for the in-capsule offset descriptor (type 0x01), checks it against port->inline_data_size before use. Any other SGL descriptor type -- including the non-inline transport SGL data-block descriptor (type (NVME_TRANSPORT_SGL_DATA_DESC << 4) | NVME_SGL_FMT_TRANSPORT_A, the type a real host uses for out-of-capsule writes) skips that check entirely and falls straight through to:
cmd->req.sg = sgl_alloc(len, GFP_KERNEL, &cmd->req.sg_cnt);
with len taken directly from the wire, unbounded up to 4 GiB.
nvmet_req_init() only parses the command and never inspects sgl->length, and nvmet_check_transfer_len() -- the only other place transfer_len is validated -- runs later, from req->execute(), after the allocation has already happened. For a write command the target responds with an R2T and parks the command waiting for the host to send the data; if the host (or an unauthenticated peer that simply never follows up) never does, the sgl_alloc() buffer stays resident for the life of the command. NVMe/TCP has no mandatory authentication in the default configuration, so any peer able to reach the target portal and complete a Fabrics connect can drive this with a single crafted command, repeatable across queues and connections for amplification. This is unbounded kernel memory allocation triggered by a remote, effectively unauthenticated peer.
Validate len against the same NVMET_TCP_MAXH2CDATA ceiling this file already uses to bound per-PDU H2C data, for every SGL descriptor type, before doing any allocation. This closes the gap for the non-inline descriptor while leaving the existing, tighter inline_data_size check in place for the in-capsule case.
Runtime-verified on a v6.19 KASAN stand: with this bound in place, a crafted write command carrying an oversized non-inline SGL length is rejected before sgl_alloc() runs, where the same request previously drove an unbounded ~256 MiB kernel allocation (up to 4 GiB) that stayed resident pending an R2T the host never satisfies.
Be aware that VulDB is the high quality source for vulnerability data.
Analysis
by VulDB Data Team • 09/04/2026
The Linux kernel's NVMe/TCP target implementation contains a critical vulnerability related to improper input validation and resource management, specifically within the nvmet-tcp subsystem. This flaw allows for unbounded kernel memory allocation triggered by remote network traffic, leading to potential denial of service conditions through memory exhaustion or system instability. The issue stems from an inconsistency in how different types of Scatter-Gather List descriptors are processed during command initialization. While the code correctly validates data lengths for inline capsule transfers against a predefined port limit, it fails to apply similar bounds checking for non-inline transport SGL data-block descriptors. This oversight permits attackers to specify arbitrarily large memory allocation requests directly from wire-controlled values without adequate verification prior to resource commitment.
The technical root cause lies in the nvmet_tcp_map_data function, which handles the mapping of host-provided Scatter-Gather List structures. When processing an in-capsule offset descriptor with type 0x01, the implementation correctly compares the sgl->length field against port->inline_data_size to ensure it does not exceed allowed limits for inline data transfer. However, for other SGL descriptor types, particularly those used by real hosts for out-of-capsule writes such as NVME_TRANSPORT_SGL_DATA_DESC combined with NVME_SGL_FMT_TRANSPORT_A, this validation step is entirely skipped. The code proceeds directly to allocate command buffers using sgl_alloc with the length parameter taken verbatim from the network packet. Since there are no upper bounds enforced at this stage, an attacker can specify a length value up to 4 GiB, forcing the kernel to attempt allocation of that massive amount of contiguous memory immediately upon receiving the crafted request.
The operational impact is severe due to the asynchronous nature of NVMe/TCP command processing and the lack of mandatory authentication in default configurations. Upon receipt of a write command with an oversized SGL length, the target responds with a Ready-to-Transfer (R2T) message and parks the command, waiting for the host to send the actual data payload. If the attacker never sends this follow-up data, or if they simply disconnect after sending the initial crafted request, the allocated kernel memory remains resident in system RAM for the entire duration of the pending command. This creates a persistent resource leak that can be exploited repeatedly across multiple queues and connections by any peer capable of reaching the target portal and establishing a Fabrics connection. The vulnerability effectively allows an unauthenticated remote actor to exhaust available kernel memory, leading to denial of service or potential system crashes depending on allocation success rates and surrounding system load conditions.
This flaw aligns with CWE-787: Out-of-bounds Write in terms of resource consumption patterns where unchecked inputs lead to excessive resource usage, though it is more accurately categorized under CWE-400: Uncontrolled Resource Consumption due to the memory exhaustion aspect rather than direct buffer overflow exploitation. From a threat modeling perspective using MITRE ATT&CK frameworks, this vulnerability facilitates Denial of Service (T1499) through endpoint resource harvesting and potentially impacts Availability by degrading system performance or causing crashes. The attack vector is classified as Network-based with Low complexity since it requires only network connectivity to the NVMe/TCP target port and does not require prior authentication in standard deployments, making it a significant risk for publicly accessible storage targets.
The remediation strategy involves enforcing strict bounds checking on all SGL descriptor types before any memory allocation occurs. Specifically, developers must validate the length field against NVMET_TCP_MAXH2CDATA, which serves as the ceiling for per-PDU Host-to-Command data limits currently applied to inline transfers. By applying this same constraint universally across all non-inline transport descriptors, the kernel prevents the allocation of excessively large buffers that exceed reasonable operational parameters. This patch ensures that oversized requests are rejected early in the processing pipeline during nvmet_req_init or related validation stages rather than after sgl_alloc has already committed memory resources. Runtime verification using Kernel Address Sanitizer confirms that this fix successfully blocks crafted write commands with non-inline SGL lengths before allocation takes place, preventing the previously observed ~256 MiB to 4 GiB resident memory leaks and restoring proper resource management controls for remote NVMe/TCP interactions.