Cloudanix VulnDB

CVE-2026-80787

None

CVSS

—

EPSS

0.2%

Published

Sep 4, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A Linux kernel storage driver bug can cause the system to read memory that has already been freed, which may lead to crashes or other problems on affected machines.

Chainable
Exploitation
Local Privilege
Attacker needs
Local User
Complexity
Moderate
Impact
Privilege Gain
Component
OS kernel
Class
Use After Free
Remediation
Patch
Effort
Medium
Patch risk
Low

What it actually does

Use-after-free read in nvmet_pci_epf_exec_iod_work() caused by accessing iod->data_len and iod->dma_dir after req->execute() may have asynchronously completed the command and freed the iod via nvmet_pci_epf_complete_iod() for non-device-to-host transfers.

Why it matters to the business

Kernel instability, crashes, or memory corruption on systems exposing NVMe storage via PCIe endpoint functions, potentially leading to denial of service or limited local privilege escalation with no known widespread exploitation.

How an attack unfolds

An attacker with local access or control over NVMe command submission triggers nvmet_pci_epf_exec_iod_work for a command that does not transfer data from device to host; the asynchronous completion path frees the iod structure before the work function reads its fields, resulting in the reported KFENCE use-after-free.

How to fix it

Apply the upstream kernel fix that moves reads of iod->data_len and iod->dma_dir before the req->execute() call; rebuild and deploy the patched kernel on all affected systems.

How to confirm the fix worked

Rebuild with KFENCE enabled and confirm absence of the use-after-free report; inspect the nvmet_pci_epf source to verify iod field accesses occur prior to req->execute().

Typical attack path

  1. Submit I/O command via nvmet_pci_epf_poll_sqs_work that does not require device-to-host data transfer
  2. Allow req->execute() to complete asynchronously on another CPU
  3. Race nvmet_pci_epf_queue_response calling nvmet_pci_epf_complete_iod to free the iod
  4. Read iod->data_len or iod->dma_dir from the now-freed object in nvmet_pci_epf_exec_iod_work

How to detect it

Search kernel logs and dmesg for KFENCE use-after-free messages referencing nvmet_pci_epf_exec_iod_work or nvmet_pci_epf_free_iod.

  • nvmet_pci_epf_exec_iod_work+0x288/0x798
  • BUG: KFENCE: use-after-free read in nvmet_pci_epf_exec_iod_work
  • nvmet_pci_epf_free_iod+0x88/0x98

What your security team should do

  • Prioritize kernel updates containing the nvmet fix within standard patch windows
  • Enable KFENCE and monitor kernel logs for nvmet_pci_epf related use-after-free reports
  • Restrict untrusted access to NVMe-over-PCIe endpoint configurations where feasible

The record

In the Linux kernel, the following vulnerability has been resolved: nvmet: pci-epf: fix use-after-free in nvmet_pci_epf_exec_iod_work() nvmet_pci_epf_exec_iod_work() submits an I/O command with req->execute() and then waits for the command to complete and transfers the data back to the host. This wait is not needed for commands that do not transfer data from the device to the host. To decide whether that wait is needed, it reads iod->data_len and iod->dma_dir after calling req->execute(). However, once req->execute() is called, the command may complete asynchronously on another CPU. For commands that do not require a device-to-host data transfer, nvmet_pci_epf_queue_response() calls nvmet_pci_epf_complete_iod() directly, which can free the iod before it reads iod->data_len and iod->dma_dir, resulting in the KFENCE use-after- free: BUG: KFENCE: use-after-free read in nvmet_pci_epf_exec_iod_work+0x288/0x798 [nvmet_pci_epf] Use-after-free read at 0x00000000fdfa6d03 (in kfence-#63): nvmet_pci_epf_exec_iod_work+0x288/0x798 [nvmet_pci_epf] process_one_work+0x15c/0x4f0 worker_thread+0x18c/0x30c kthread+0x130/0x140 ret_from_fork+0x10/0x20 kfence-#63: 0x00000000e3de0e71-0x00000000c938ad62, size=712, cache=kmalloc-1k allocated by task 10 on cpu 0 at 73.995480s (0.005122s ago): mempool_kmalloc+0x1c/0x28 mempool_alloc_noprof+0x40/0x9c nvmet_pci_epf_poll_sqs_work+0xd4/0x344 [nvmet_pci_epf] process_one_work+0x15c/0x4f0 worker_thread+0x18c/0x30c kthread+0x130/0x140 ret_from_fork+0x10/0x20 freed by task 131 on cpu 3 at 73.995521s (0.008385s ago): mempool_kfree+0x10/0x20 mempool_free+0x44/0x64 nvmet_pci_epf_free_iod+0x88/0x98 [nvmet_pci_epf] nvmet_pci_epf_cq_work+0xfc/0x280 [nvmet_pci_epf] process_one_work+0x15c/0x4f0 worker_thread+0x18c/0x30c kthread+0x130/0x140 ret_from_fork+0x10/0x20 Fix this by referring to iod->data_len and iod->dma_dir before calling req->execute(). The remaining iod accesses such as iod->status are only reached on the device-to-host read path. In this case, nvmet_pci_epf_queue_response() signals iod->done instead of freeing the iod, so the iod stays valid.

Affected packages

Ecosystem Package Introduced Fixed