GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

CVE-2025-38658 (GCVE-0-2025-38658)

Vulnerability from cvelistv5 – Published: 2025-08-22 16:01 – Updated: 2026-08-05 12:03
VLAI
Title
nvmet: pci-epf: Do not complete commands twice if nvmet_req_init() fails
Summary
In the Linux kernel, the following vulnerability has been resolved: nvmet: pci-epf: Do not complete commands twice if nvmet_req_init() fails Have nvmet_req_init() and req->execute() complete failed commands. Description of the problem: nvmet_req_init() calls __nvmet_req_complete() internally upon failure, e.g., unsupported opcode, which calls the "queue_response" callback, this results in nvmet_pci_epf_queue_response() being called, which will call nvmet_pci_epf_complete_iod() if data_len is 0 or if dma_dir is different from DMA_TO_DEVICE. This results in a double completion as nvmet_pci_epf_exec_iod_work() also calls nvmet_pci_epf_complete_iod() when nvmet_req_init() fails. Steps to reproduce: On the host send a command with an unsupported opcode with nvme-cli, For example the admin command "security receive" $ sudo nvme security-recv /dev/nvme0n1 -n1 -x4096 This triggers a double completion as nvmet_req_init() fails and nvmet_pci_epf_queue_response() is called, here iod->dma_dir is still in the default state of "DMA_NONE" as set by default in nvmet_pci_epf_alloc_iod(), so nvmet_pci_epf_complete_iod() is called. Because nvmet_req_init() failed nvmet_pci_epf_complete_iod() is also called in nvmet_pci_epf_exec_iod_work() leading to a double completion. This not only sends two completions to the host but also corrupts the state of the PCI NVMe target leading to kernel oops. This patch lets nvmet_req_init() and req->execute() complete all failed commands, and removes the double completion case in nvmet_pci_epf_exec_iod_work() therefore fixing the edge cases where double completions occurred.
Impacted products
Vendor Product Version CPE status
Linux Linux Affected: 0faa0fe6f90ea59b10d1b0f15ce0eb0c18eff186 , < a535c0b10060bc8c174a7964b0f98064ee0c4774 (git)
Affected: 0faa0fe6f90ea59b10d1b0f15ce0eb0c18eff186 , < 746d0ac5a07d5da952ef258dd4d75f0b26c96476 (git)
guessed Create a notification for this product.
Linux Linux Affected: 6.14
Unaffected: 0 , < 6.14 (semver)
Unaffected: 6.16.1 , ≤ 6.16.* (semver)
Unaffected: 6.17 , ≤ * (original_commit_for_fix)
guessed Create a notification for this product.
Show details on NVD website

{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "drivers/nvme/target/pci-epf.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "a535c0b10060bc8c174a7964b0f98064ee0c4774",
              "status": "affected",
              "version": "0faa0fe6f90ea59b10d1b0f15ce0eb0c18eff186",
              "versionType": "git"
            },
            {
              "lessThan": "746d0ac5a07d5da952ef258dd4d75f0b26c96476",
              "status": "affected",
              "version": "0faa0fe6f90ea59b10d1b0f15ce0eb0c18eff186",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "drivers/nvme/target/pci-epf.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "6.14"
            },
            {
              "lessThan": "6.14",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.16.*",
              "status": "unaffected",
              "version": "6.16.1",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "6.17",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.16.1",
                  "versionStartIncluding": "6.14",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.17",
                  "versionStartIncluding": "6.14",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nnvmet: pci-epf: Do not complete commands twice if nvmet_req_init() fails\n\nHave nvmet_req_init() and req-\u003eexecute() complete failed commands.\n\nDescription of the problem:\nnvmet_req_init() calls __nvmet_req_complete() internally upon failure,\ne.g., unsupported opcode, which calls the \"queue_response\" callback,\nthis results in nvmet_pci_epf_queue_response() being called, which will\ncall nvmet_pci_epf_complete_iod() if data_len is 0 or if dma_dir is\ndifferent from DMA_TO_DEVICE. This results in a double completion as\nnvmet_pci_epf_exec_iod_work() also calls nvmet_pci_epf_complete_iod()\nwhen nvmet_req_init() fails.\n\nSteps to reproduce:\nOn the host send a command with an unsupported opcode with nvme-cli,\nFor example the admin command \"security receive\"\n$ sudo nvme security-recv /dev/nvme0n1 -n1 -x4096\n\nThis triggers a double completion as nvmet_req_init() fails and\nnvmet_pci_epf_queue_response() is called, here iod-\u003edma_dir is still\nin the default state of \"DMA_NONE\" as set by default in\nnvmet_pci_epf_alloc_iod(), so nvmet_pci_epf_complete_iod() is called.\nBecause nvmet_req_init() failed nvmet_pci_epf_complete_iod() is also\ncalled in nvmet_pci_epf_exec_iod_work() leading to a double completion.\nThis not only sends two completions to the host but also corrupts the\nstate of the PCI NVMe target leading to kernel oops.\n\nThis patch lets nvmet_req_init() and req-\u003eexecute() complete all failed\ncommands, and removes the double completion case in\nnvmet_pci_epf_exec_iod_work() therefore fixing the edge cases where\ndouble completions occurred."
        }
      ],
      "metrics": [
        {
          "cvssV3_1": {
            "baseScore": 8.8,
            "baseSeverity": "HIGH",
            "vectorString": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
            "version": "3.1"
          },
          "scenarios": [
            {
              "lang": "en",
              "value": "AV:A - The vulnerable code is the NVMe PCI *endpoint* target, driven entirely by NVMe commands submitted by a separate root-complex host across the PCIe link, so the attacker is external software on a directly-attached peer machine rather than a user of the endpoint system. In the deployments this driver targets (disaggregated/composable PCIe storage, and endpoint devices VFIO-passed-through to untrusted guests) no physical manipulation is needed at attack time \u2014 only presence on the same logically adjacent PCIe fabric.\nAC:L - A single NVMe command with an opcode the target does not implement deterministically fails nvmet_req_init() and produces the double completion; the commit itself gives a one-line nvme-cli reproducer. No timing, memory-layout, or victim-state condition outside the attacker\u0027s control is involved.\nPR:N - NVMe over PCIe has no authentication or authorization step \u2014 the host merely enables CC.EN, creates queues, and writes a doorbell \u2014 so the attacker holds no credentials at all on the vulnerable endpoint system. Any command submitter on the attached host or a passed-through guest reaches the failing path.\nUI:N - The endpoint\u0027s SQ-polling work item picks up the malformed command and dispatches it automatically. No action by any user or administrator on the victim endpoint system is required.\nS:U - The corruption is confined to the endpoint kernel\u0027s own heap and driver state, the same security authority that contains the vulnerable code. The cross-machine nature of the attack is already captured by the Attack Vector metric.\nC:H - The dangling CQ list entry causes nvmet_pci_epf_cq_work() to re-read a freed iod and build a completion entry from it (including a dereference of a possibly reallocated iod-\u003esq), which is memcpy_toio()\u0027d straight into the attacker host\u0027s completion queue, leaking reused kernel heap contents. More broadly, the double free and iod aliasing yield general heap-corruption primitives leverageable for arbitrary kernel memory disclosure.\nI:H - The same iod is returned to the mempool twice, so two concurrent commands are handed the identical object and its data_segs buffers are kfree()\u0027d twice in shared kmalloc caches, with the attacker controlling those buffers\u0027 sizes and contents via PRP/SGL lists and DMA. A double free plus use-after-free write on an aliased object is a well-established path to controlled kernel writes and control-flow hijack.\nA:H - The commit explicitly states the double completion \"corrupts the state of the PCI NVMe target leading to kernel oops,\" and CONFIG_DEBUG_LIST additionally trips on the duplicate list_add. The attacker can repeat the triggering command at will to panic or wedge the endpoint system."
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-08-05T12:03:45.053Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/a535c0b10060bc8c174a7964b0f98064ee0c4774"
        },
        {
          "url": "https://git.kernel.org/stable/c/746d0ac5a07d5da952ef258dd4d75f0b26c96476"
        }
      ],
      "title": "nvmet: pci-epf: Do not complete commands twice if nvmet_req_init() fails",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2025-38658",
    "datePublished": "2025-08-22T16:01:01.651Z",
    "dateReserved": "2025-04-16T04:51:24.031Z",
    "dateUpdated": "2026-08-05T12:03:45.053Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "epss": {
      "cve": "CVE-2025-38658",
      "date": "2026-09-14",
      "epss": "0.00196",
      "percentile": "0.09437"
    },
    "nvd": "{\"cve\":{\"id\":\"CVE-2025-38658\",\"sourceIdentifier\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"published\":\"2025-08-22T16:15:40.907\",\"lastModified\":\"2026-07-30T06:23:33.413\",\"vulnStatus\":\"Modified\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"In the Linux kernel, the following vulnerability has been resolved:\\n\\nnvmet: pci-epf: Do not complete commands twice if nvmet_req_init() fails\\n\\nHave nvmet_req_init() and req-\u003eexecute() complete failed commands.\\n\\nDescription of the problem:\\nnvmet_req_init() calls __nvmet_req_complete() internally upon failure,\\ne.g., unsupported opcode, which calls the \\\"queue_response\\\" callback,\\nthis results in nvmet_pci_epf_queue_response() being called, which will\\ncall nvmet_pci_epf_complete_iod() if data_len is 0 or if dma_dir is\\ndifferent from DMA_TO_DEVICE. This results in a double completion as\\nnvmet_pci_epf_exec_iod_work() also calls nvmet_pci_epf_complete_iod()\\nwhen nvmet_req_init() fails.\\n\\nSteps to reproduce:\\nOn the host send a command with an unsupported opcode with nvme-cli,\\nFor example the admin command \\\"security receive\\\"\\n$ sudo nvme security-recv /dev/nvme0n1 -n1 -x4096\\n\\nThis triggers a double completion as nvmet_req_init() fails and\\nnvmet_pci_epf_queue_response() is called, here iod-\u003edma_dir is still\\nin the default state of \\\"DMA_NONE\\\" as set by default in\\nnvmet_pci_epf_alloc_iod(), so nvmet_pci_epf_complete_iod() is called.\\nBecause nvmet_req_init() failed nvmet_pci_epf_complete_iod() is also\\ncalled in nvmet_pci_epf_exec_iod_work() leading to a double completion.\\nThis not only sends two completions to the host but also corrupts the\\nstate of the PCI NVMe target leading to kernel oops.\\n\\nThis patch lets nvmet_req_init() and req-\u003eexecute() complete all failed\\ncommands, and removes the double completion case in\\nnvmet_pci_epf_exec_iod_work() therefore fixing the edge cases where\\ndouble completions occurred.\"},{\"lang\":\"es\",\"value\":\"En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: nvmet: pci-epf: No completar comandos dos veces si nvmet_req_init() falla. nvmet_req_init() y req-\u0026gt;execute() completan los comandos fallidos. Descripci\u00f3n del problema: nvmet_req_init() llama internamente a __nvmet_req_complete() en caso de fallo (p. ej., un c\u00f3digo de operaci\u00f3n no compatible, que llama a la devoluci\u00f3n de llamada \\\"queue_response\\\"). Esto provoca la llamada a nvmet_pci_epf_queue_response(), que a su vez llama a nvmet_pci_epf_complete_iod() si data_len es 0 o si dma_dir es diferente de DMA_TO_DEVICE. Esto genera una doble finalizaci\u00f3n, ya que nvmet_pci_epf_exec_iod_work() tambi\u00e9n llama a nvmet_pci_epf_complete_iod() cuando falla nvmet_req_init(). Pasos para reproducir: En el host, env\u00ede un comando con un c\u00f3digo de operaci\u00f3n no compatible con nvme-cli. Por ejemplo, el comando de administrador \\\"security receive\\\": $ sudo nvme security-recv /dev/nvme0n1 -n1 -x4096. Esto activa una doble finalizaci\u00f3n, ya que nvmet_req_init() falla y se llama a nvmet_pci_epf_queue_response(). En este caso, iod-\u0026gt;dma_dir a\u00fan se encuentra en el estado predeterminado \\\"DMA_NONE\\\", tal como se establece por defecto en nvmet_pci_epf_alloc_iod(), por lo que se llama a nvmet_pci_epf_complete_iod(). Debido a que nvmet_req_init() fall\u00f3, nvmet_pci_epf_complete_iod() tambi\u00e9n se llama en nvmet_pci_epf_exec_iod_work(), lo que provoca una doble finalizaci\u00f3n. Esto no solo env\u00eda dos finalizaciones al host, sino que tambi\u00e9n corrompe el estado del destino PCI NVMe, lo que provoca errores del kernel. Este parche permite que nvmet_req_init() y req-\u0026gt;execute() completen todos los comandos fallidos y elimina el caso de doble finalizaci\u00f3n en nvmet_pci_epf_exec_iod_work(), corrigiendo as\u00ed los casos extremos donde se produc\u00edan dobles finalizaciones.\"}],\"affected\":[{\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"affectedData\":[{\"vendor\":\"Linux\",\"product\":\"Linux\",\"defaultStatus\":\"unaffected\",\"programFiles\":[\"drivers/nvme/target/pci-epf.c\"],\"repo\":\"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git\",\"versions\":[{\"version\":\"0faa0fe6f90ea59b10d1b0f15ce0eb0c18eff186\",\"lessThan\":\"a535c0b10060bc8c174a7964b0f98064ee0c4774\",\"versionType\":\"git\",\"status\":\"affected\"},{\"version\":\"0faa0fe6f90ea59b10d1b0f15ce0eb0c18eff186\",\"lessThan\":\"746d0ac5a07d5da952ef258dd4d75f0b26c96476\",\"versionType\":\"git\",\"status\":\"affected\"}]},{\"vendor\":\"Linux\",\"product\":\"Linux\",\"defaultStatus\":\"affected\",\"programFiles\":[\"drivers/nvme/target/pci-epf.c\"],\"repo\":\"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git\",\"versions\":[{\"version\":\"6.14\",\"status\":\"affected\"},{\"version\":\"0\",\"lessThan\":\"6.14\",\"versionType\":\"semver\",\"status\":\"unaffected\"},{\"version\":\"6.16.1\",\"lessThanOrEqual\":\"6.16.*\",\"versionType\":\"semver\",\"status\":\"unaffected\"},{\"version\":\"6.17\",\"lessThanOrEqual\":\"*\",\"versionType\":\"original_commit_for_fix\",\"status\":\"unaffected\"}]}]}],\"metrics\":{\"cvssMetricV31\":[{\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"type\":\"Secondary\",\"cvssData\":{\"version\":\"3.1\",\"vectorString\":\"CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\",\"baseScore\":8.8,\"baseSeverity\":\"HIGH\",\"attackVector\":\"ADJACENT_NETWORK\",\"attackComplexity\":\"LOW\",\"privilegesRequired\":\"NONE\",\"userInteraction\":\"NONE\",\"scope\":\"UNCHANGED\",\"confidentialityImpact\":\"HIGH\",\"integrityImpact\":\"HIGH\",\"availabilityImpact\":\"HIGH\"},\"exploitabilityScore\":2.8,\"impactScore\":5.9},{\"source\":\"nvd@nist.gov\",\"type\":\"Primary\",\"cvssData\":{\"version\":\"3.1\",\"vectorString\":\"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H\",\"baseScore\":5.5,\"baseSeverity\":\"MEDIUM\",\"attackVector\":\"LOCAL\",\"attackComplexity\":\"LOW\",\"privilegesRequired\":\"LOW\",\"userInteraction\":\"NONE\",\"scope\":\"UNCHANGED\",\"confidentialityImpact\":\"NONE\",\"integrityImpact\":\"NONE\",\"availabilityImpact\":\"HIGH\"},\"exploitabilityScore\":1.8,\"impactScore\":3.6}]},\"weaknesses\":[{\"source\":\"nvd@nist.gov\",\"type\":\"Primary\",\"description\":[{\"lang\":\"en\",\"value\":\"CWE-908\"}]}],\"configurations\":[{\"nodes\":[{\"operator\":\"OR\",\"negate\":false,\"cpeMatch\":[{\"vulnerable\":true,\"criteria\":\"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*\",\"versionStartIncluding\":\"6.14\",\"versionEndExcluding\":\"6.16.1\",\"matchCriteriaId\":\"20B891EE-EEAF-4C89-8B4C-494932C18ACC\"}]}]}],\"references\":[{\"url\":\"https://git.kernel.org/stable/c/746d0ac5a07d5da952ef258dd4d75f0b26c96476\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"tags\":[\"Patch\"]},{\"url\":\"https://git.kernel.org/stable/c/a535c0b10060bc8c174a7964b0f98064ee0c4774\",\"source\":\"416baaa9-dc9f-4396-8d5f-8c081fb06d67\",\"tags\":[\"Patch\"]}]}}",
    "redhat_vex": {
      "aggregate_severity": "None",
      "current_release_date": "2026-06-30T10:19:36+00:00",
      "cve": "CVE-2025-38658",
      "id": "CVE-2025-38658",
      "initial_release_date": "2025-08-22T00:00:00+00:00",
      "product_status:known_not_affected": "274",
      "source": "Red Hat CSAF VEX",
      "status": "final",
      "title": "kernel: nvmet: pci-epf: Do not complete commands twice if nvmet_req_init() fails",
      "url": "https://security.access.redhat.com/data/csaf/v2/vex/2025/cve-2025-38658.json",
      "version": "3"
    },
    "suse_vex": {
      "aggregate_severity": "moderate",
      "current_release_date": "2026-09-12T16:48:23Z",
      "cve": "CVE-2025-38658",
      "id": "CVE-2025-38658",
      "initial_release_date": "2025-08-22T23:28:23Z",
      "product_status:first_fixed": "2",
      "product_status:known_not_affected": "524",
      "product_status:recommended": "154",
      "source": "SUSE CSAF VEX",
      "status": "interim",
      "title": "SUSE CVE CVE-2025-38658",
      "url": "https://ftp.suse.com/pub/projects/security/csaf-vex/cve-2025-38658.json",
      "version": "30"
    }
  }
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…