« Volver al listado

CVE-2026-72473

Estado: RecibidaCrítica (9.8)—

In the Linux kernel, the following vulnerability has been resolved:

xprtrdma: Decouple req recycling from RPC completion

rl_kref formerly served two distinct lifetimes through a single refcount: it gated when a Reply could wake its RPC task, and it gated when an rpcrdma_req could return to its free pool. The marshal path took the Send-side reference only when SGEs needed DMA-unmap (sc_unmap_count > 0), which made a Send carrying only pre-registered buffers an exception: the Reply handler dropped rl_kref from 1 to 0 and freed the req while the HCA might still be DMA-reading from its send buffer.

Give rl_kref a narrower job. The RPC layer takes one reference when slot allocation hands a req out. rpcrdma_prepare_send_sges() takes a Send-side reference unconditionally after WR preparation succeeds. xprt_rdma_free_slot() and xprt_rdma_bc_free_rqst() drop the RPC-layer reference; rpcrdma_sendctx_unmap() drops the Send-side reference. The req returns to its free pool only after both owners have signed off.

Leer descripción completaMostrar menos

The existing kref_init(&req->rl_kref) call in rpcrdma_prepare_send_sges() is removed. Initialization moves to the slot-allocation paths (xprt_rdma_alloc_slot and rpcrdma_bc_rqst_get), and the release callback re-arms rl_kref before the req returns to a free pool. A re-init in the marshal path would discard the RPC-layer reference that already exists on entry.

Three invariants follow:

Replies now complete the RPC directly. rpcrdma_reply_handler() calls rpcrdma_complete_rqst() in place of kref_put on the non-LocalInv branch. The LocalInv branch already completes the RPC from frwr_unmap_async() and is unaffected.

Because Send-side references can now outlive RPC completion, connection teardown drains sendctx entries whose unsignaled Sends never had a later signaled completion to walk the ring. rpcrdma_sendctxs_destroy() walks the active range and runs rpcrdma_sendctx_unmap() on each entry with a non-NULL sc_req before the request buffers are reset, and is moved ahead of rpcrdma_reqs_reset() in rpcrdma_xprt_disconnect() so the reqs are still in their pre-reset state when the Send-side refs are released.

The drain creates a teardown-ordering hazard on the backchannel path. With the new lifetime, releasing a bc_prealloc req from rpcrdma_req_release() re-adds it to bc_pa_list. The disconnect in xprt_rdma_destroy() runs after xprt_destroy_backchannel() has already emptied bc_pa_list, so the drained reqs would otherwise leak. xprt_rdma_destroy() now runs xprt_rdma_bc_destroy(xprt, 0) a second time after the disconnect to reclaim them.

Detalles técnicos trazas, registros y código del informe original
  - Any rpcrdma_req held by an rpc_rqst has rl_kref >= 1.
    xprt_rdma_alloc_slot(), rpcrdma_bc_rqst_get(), and the
    backlog-wake branch in xprt_rdma_alloc_slot() each kref_init
    rl_kref before publishing the req. Without this invariant,
    an RPC task that aborts between slot allocation and marshal
    (gss_refresh failure or signal during call_connect, for
    example) would drive xprt_release() ->
    xprt_rdma_free_slot() -> kref_put against a refcount of
    zero, saturating refcount_t and stranding the slot.

  - The Send-side reference is taken only after WR prep
    succeeds. A mapping failure in rpcrdma_prepare_send_sges()
    runs rpcrdma_sendctx_cancel(), which DMA-unmaps the sendctx
    and clears sc_req without touching rl_kref. The sendctx
    ring walks in rpcrdma_sendctx_put_locked() and
    rpcrdma_sendctxs_destroy() skip entries with sc_req == NULL,
    so a burst of -EIO marshal failures cannot hold reqs off
    rb_send_bufs.

  - The release callback re-arms rl_kref so the next consumer
    enters with the invariant satisfied.

CVSS

Probabilidad de explotación (EPSS)

EPSS (Exploit Prediction Scoring System, de FIRST) estima la probabilidad de que una vulnerabilidad sea explotada en 30 días. Complementa a CVSS (impacto) y a CISA KEV (explotación confirmada).

🎯 Técnicas ATT&CK

Cómo se explota esta vulnerabilidad y qué consigue el atacante, en el lenguaje de MITRE ATT&CK.

Vulnerabilidad de kernel Linux en RDMA con vector de red sin autenticación (AV:N/PR:N) que permite DoS por crash/corrupción de memoria; explotable remotamente como T1190. Impactos: denegación de servicio (T1499.004 crash) y posible corrupción de datos en memoria compartida (T1561.002).

Inferido por nuestro agente de análisis a partir de la descripción oficial, el vector CVSS y la CWE, y comprobado por un supervisor. Puede contener errores.

🛡️ Mitigaciones ATT&CK que cubren estas técnicas

Tecnologías afectadas (1)

⚠ Inferidas por IA a partir de la descripción — NVD aún no ha analizado esta CVE; no son CPE verificados.

Referencias

JSON original (NVD)

Mostrar
{
  "id": "CVE-2026-72473",
  "cveTags": [],
  "metrics": {
    "cvssMetricV31": [
      {
        "type": "Secondary",
        "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "cvssData": {
          "scope": "UNCHANGED",
          "version": "3.1",
          "baseScore": 9.8,
          "attackVector": "NETWORK",
          "baseSeverity": "CRITICAL",
          "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
          "integrityImpact": "HIGH",
          "userInteraction": "NONE",
          "attackComplexity": "LOW",
          "availabilityImpact": "HIGH",
          "privilegesRequired": "NONE",
          "confidentialityImpact": "HIGH"
        },
        "impactScore": 5.9,
        "exploitabilityScore": 3.9
      }
    ]
  },
  "affected": [
    {
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
      "affectedData": [
        {
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "product": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "0ab115237025f5e379620bbcd56a02697d07b002",
              "lessThan": "740975054a1970c0cf15f70ac39724a064f45847",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "0ab115237025f5e379620bbcd56a02697d07b002",
              "lessThan": "9f3d9b68c1c6c51746e5ecdb52b2e6a2901de37e",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "0ab115237025f5e379620bbcd56a02697d07b002",
              "lessThan": "e7632089523acddcdd8f090ad19e96fb3107b04d",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "0ab115237025f5e379620bbcd56a02697d07b002",
              "lessThan": "53442c7d0c888e51b8bc3da196970a669cc6b294",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "0ab115237025f5e379620bbcd56a02697d07b002",
              "lessThan": "8203f760a72bd39a3b66bc4eff0aa272a99fe22b",
              "versionType": "git"
            },
            {
              "status": "affected",
              "version": "0ab115237025f5e379620bbcd56a02697d07b002",
              "lessThan": "e786233d2e0bbff9a82e43f02ae3a46ab4b08ec3",
              "versionType": "git"
            }
          ],
          "programFiles": [
            "net/sunrpc/xprtrdma/backchannel.c",
            "net/sunrpc/xprtrdma/rpc_rdma.c",
            "net/sunrpc/xprtrdma/transport.c",
            "net/sunrpc/xprtrdma/verbs.c",
            "net/sunrpc/xprtrdma/xprt_rdma.h"
          ],
          "defaultStatus": "unaffected"
        },
        {
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "product": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "5.3"
            },
            {
              "status": "unaffected",
              "version": "0",
              "lessThan": "5.3",
              "versionType": "semver"
            },
            {
              "status": "unaffected",
              "version": "6.1.178",
              "versionType": "semver",
              "lessThanOrEqual": "6.1.*"
            },
            {
              "status": "unaffected",
              "version": "6.6.145",
              "versionType": "semver",
              "lessThanOrEqual": "6.6.*"
            },
            {
              "status": "unaffected",
              "version": "6.12.97",
              "versionType": "semver",
              "lessThanOrEqual": "6.12.*"
            },
            {
              "status": "unaffected",
              "version": "6.18.40",
              "versionType": "semver",
              "lessThanOrEqual": "6.18.*"
            },
            {
              "status": "unaffected",
              "version": "7.1.5",
              "versionType": "semver",
              "lessThanOrEqual": "7.1.*"
            },
            {
              "status": "unaffected",
              "version": "7.2",
              "versionType": "original_commit_for_fix",
              "lessThanOrEqual": "*"
            }
          ],
          "programFiles": [
            "net/sunrpc/xprtrdma/backchannel.c",
            "net/sunrpc/xprtrdma/rpc_rdma.c",
            "net/sunrpc/xprtrdma/transport.c",
            "net/sunrpc/xprtrdma/verbs.c",
            "net/sunrpc/xprtrdma/xprt_rdma.h"
          ],
          "defaultStatus": "affected"
        }
      ]
    }
  ],
  "published": "2026-08-15T06:22:21.423",
  "references": [
    {
      "url": "https://git.kernel.org/stable/c/53442c7d0c888e51b8bc3da196970a669cc6b294",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/740975054a1970c0cf15f70ac39724a064f45847",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/8203f760a72bd39a3b66bc4eff0aa272a99fe22b",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/9f3d9b68c1c6c51746e5ecdb52b2e6a2901de37e",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/e7632089523acddcdd8f090ad19e96fb3107b04d",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    },
    {
      "url": "https://git.kernel.org/stable/c/e786233d2e0bbff9a82e43f02ae3a46ab4b08ec3",
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
    }
  ],
  "vulnStatus": "Received",
  "descriptions": [
    {
      "lang": "en",
      "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nxprtrdma: Decouple req recycling from RPC completion\n\nrl_kref formerly served two distinct lifetimes through a single\nrefcount: it gated when a Reply could wake its RPC task, and it\ngated when an rpcrdma_req could return to its free pool. The\nmarshal path took the Send-side reference only when SGEs needed\nDMA-unmap (sc_unmap_count > 0), which made a Send carrying only\npre-registered buffers an exception: the Reply handler dropped\nrl_kref from 1 to 0 and freed the req while the HCA might still\nbe DMA-reading from its send buffer.\n\nGive rl_kref a narrower job. The RPC layer takes one reference\nwhen slot allocation hands a req out. rpcrdma_prepare_send_sges()\ntakes a Send-side reference unconditionally after WR preparation\nsucceeds. xprt_rdma_free_slot() and xprt_rdma_bc_free_rqst() drop\nthe RPC-layer reference; rpcrdma_sendctx_unmap() drops the\nSend-side reference. The req returns to its free pool only after\nboth owners have signed off.\n\nThe existing kref_init(&req->rl_kref) call in\nrpcrdma_prepare_send_sges() is removed. Initialization moves to\nthe slot-allocation paths (xprt_rdma_alloc_slot and\nrpcrdma_bc_rqst_get), and the release callback re-arms rl_kref\nbefore the req returns to a free pool. A re-init in the marshal\npath would discard the RPC-layer reference that already exists\non entry.\n\nThree invariants follow:\n\n  - Any rpcrdma_req held by an rpc_rqst has rl_kref >= 1.\n    xprt_rdma_alloc_slot(), rpcrdma_bc_rqst_get(), and the\n    backlog-wake branch in xprt_rdma_alloc_slot() each kref_init\n    rl_kref before publishing the req. Without this invariant,\n    an RPC task that aborts between slot allocation and marshal\n    (gss_refresh failure or signal during call_connect, for\n    example) would drive xprt_release() ->\n    xprt_rdma_free_slot() -> kref_put against a refcount of\n    zero, saturating refcount_t and stranding the slot.\n\n  - The Send-side reference is taken only after WR prep\n    succeeds. A mapping failure in rpcrdma_prepare_send_sges()\n    runs rpcrdma_sendctx_cancel(), which DMA-unmaps the sendctx\n    and clears sc_req without touching rl_kref. The sendctx\n    ring walks in rpcrdma_sendctx_put_locked() and\n    rpcrdma_sendctxs_destroy() skip entries with sc_req == NULL,\n    so a burst of -EIO marshal failures cannot hold reqs off\n    rb_send_bufs.\n\n  - The release callback re-arms rl_kref so the next consumer\n    enters with the invariant satisfied.\n\nReplies now complete the RPC directly. rpcrdma_reply_handler()\ncalls rpcrdma_complete_rqst() in place of kref_put on the\nnon-LocalInv branch. The LocalInv branch already completes the\nRPC from frwr_unmap_async() and is unaffected.\n\nBecause Send-side references can now outlive RPC completion,\nconnection teardown drains sendctx entries whose unsignaled\nSends never had a later signaled completion to walk the ring.\nrpcrdma_sendctxs_destroy() walks the active range and runs\nrpcrdma_sendctx_unmap() on each entry with a non-NULL sc_req\nbefore the request buffers are reset, and is moved ahead of\nrpcrdma_reqs_reset() in rpcrdma_xprt_disconnect() so the reqs\nare still in their pre-reset state when the Send-side refs are\nreleased.\n\nThe drain creates a teardown-ordering hazard on the backchannel\npath. With the new lifetime, releasing a bc_prealloc req from\nrpcrdma_req_release() re-adds it to bc_pa_list. The disconnect\nin xprt_rdma_destroy() runs after xprt_destroy_backchannel() has\nalready emptied bc_pa_list, so the drained reqs would otherwise\nleak. xprt_rdma_destroy() now runs xprt_rdma_bc_destroy(xprt, 0)\na second time after the disconnect to reclaim them."
    }
  ],
  "lastModified": "2026-08-17T06:19:15.273",
  "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}