CVE-2026-64534 Overview
CVE-2026-64534 is a Linux kernel vulnerability in the nvmet-tcp (NVMe over TCP target) subsystem. The flaw resides in nvmet_tcp_try_recv_ddgst(), where a data digest mismatch triggers an unconditional call to nvmet_req_uninit(). When the request originated from the nvmet_tcp_handle_req_failure() path, nvmet_req_init() had returned false and the percpu reference was never acquired. The subsequent percpu_ref_put() causes a refcount underflow, producing a kernel WARNING, a use-after-free condition, and eventually a permanent workqueue deadlock.
Critical Impact
A remote attacker sending crafted NVMe/TCP traffic with mismatched data digests can trigger a use-after-free and workqueue deadlock on the target host, exposing memory corruption and denial-of-service risk on storage servers.
Affected Products
- Linux kernel with nvmet-tcp target driver enabled
- Distributions shipping the NVMe over Fabrics TCP target module
- Stable kernel branches prior to the fix commits referenced by kernel.org
Discovery Timeline
- 2026-07-27 - CVE-2026-64534 published to NVD
- 2026-07-30 - Last updated in NVD database
Technical Details for CVE-2026-64534
Vulnerability Analysis
The defect is a reference-counting error in the Linux kernel NVMe/TCP target. nvmet_tcp_try_recv_ddgst() handles reception of the optional data digest that follows an NVMe/TCP data PDU. When the received digest does not match the computed value, the function tears down the request by invoking nvmet_req_uninit(). That teardown assumes the request was successfully initialized and holds a live percpu reference on the target queue.
When a prior header validation failure routed the command through nvmet_tcp_handle_req_failure(), nvmet_req_init() returned false and percpu_ref_tryget_live() never executed. The teardown path still calls percpu_ref_put(), dropping a reference that was never taken. This produces a refcount underflow, a WARNING in percpu_ref_switch_to_atomic_rcu, a use-after-free diagnostic, and a permanent workqueue deadlock that hangs the target.
Root Cause
The root cause is missing state validation before resource cleanup [CWE-416, CWE-911]. nvmet_tcp_try_recv_ddgst() did not consult the NVMET_TCP_F_INIT_FAILED flag on cmd->flags before calling nvmet_req_uninit(). The parallel function nvmet_tcp_execute_request() already gates cleanup on this flag. The fix propagates that pattern to the digest error path.
Attack Vector
Exploitation requires network reachability to an NVMe over TCP target port (default TCP/4420). An attacker sends an NVMe/TCP data PDU that first fails header handling to mark the command with NVMET_TCP_F_INIT_FAILED, then supplies an incorrect data digest. The digest mismatch triggers the unconditional uninit path, resulting in refcount underflow, use-after-free, and workqueue deadlock on the storage target.
No verified public exploit code is available. See the upstream fix in kernel.org commit 4606467a75cf for technical details.
Detection Methods for CVE-2026-64534
Indicators of Compromise
- Kernel log entries containing WARNING traces from percpu_ref_switch_to_atomic_rcu on hosts running nvmet-tcp
- KASAN or KFENCE use-after-free reports referencing nvmet_req_uninit or nvmet_tcp_try_recv_ddgst
- Hung task warnings tied to NVMe target workqueues and unresponsive NVMe/TCP sessions
Detection Strategies
- Monitor kernel ring buffer and journalctl -k for the WARNING and use-after-free signatures listed above on NVMe/TCP target hosts
- Track NVMe/TCP session teardowns with digest mismatch errors, which indicate that the vulnerable code path is being exercised
- Correlate abnormal NVMe target CPU or queue depth stalls with inbound TCP/4420 traffic patterns
Monitoring Recommendations
- Enable kernel lockdep, KASAN, or panic-on-warn on non-production NVMe target hosts to surface the defect early
- Collect and centralize dmesg telemetry from all storage targets exposing NVMe over Fabrics via TCP
- Alert on repeated NVMe/TCP connection resets from a single source, a common signature of digest-manipulation probing
How to Mitigate CVE-2026-64534
Immediate Actions Required
- Apply the upstream kernel fix that checks cmd->flags & NVMET_TCP_F_INIT_FAILED before calling nvmet_req_uninit() in the digest error path
- Restrict network access to NVMe over TCP target ports (default TCP/4420) to trusted initiators using firewall or segmentation controls
- Disable the nvmet-tcp module on hosts that do not export NVMe over Fabrics via TCP
Patch Information
The fix is landed across multiple stable branches. See the following kernel.org commits: 4606467a75cf, 22ec7a9fe915, 2ed3c9d955e8, ba35b1c674ca, c7874dad84b2, d306da8833e7, and e602c93b25bd. Rebuild or update to a distribution kernel that includes these commits.
Workarounds
- Unload the nvmet_tcp module using modprobe -r nvmet_tcp on target hosts that do not require NVMe/TCP export
- Enforce IPsec or mutual TLS between initiators and targets so that untrusted peers cannot reach the NVMe/TCP listener
- Constrain NVMe subsystem access lists to authorized host NQNs and place the target network on an isolated storage VLAN
# Verify a patched kernel is running and disable nvmet-tcp if not required
uname -r
lsmod | grep nvmet_tcp
sudo modprobe -r nvmet_tcp
echo 'blacklist nvmet_tcp' | sudo tee /etc/modprobe.d/blacklist-nvmet-tcp.conf
# Restrict inbound access to the NVMe/TCP listener port
sudo iptables -A INPUT -p tcp --dport 4420 -s <trusted_initiator_cidr> -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 4420 -j DROP
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

