Get a Demo

Let's Patch It!

Book a short call with one our specialists, we'll walk you through how Endor Patches work, and ask you a few questions about your environment (like your primary programming languages and repository management). We'll also send you an email right after you fill out the form, feel free to reply with any questions you have in advance!

CVE

CVE-2026-72473

xprtrdma: Decouple req recycling from RPC completion
Back to all
CVE

CVE-2026-72473

xprtrdma: Decouple req recycling from RPC completion

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 (scunmapcount > 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. rpcrdmapreparesend_sges()

takes a Send-side reference unconditionally after WR preparation

succeeds. xprtrdmafreeslot() and xprtrdmabcfree_rqst() drop

the RPC-layer reference; rpcrdmasendctxunmap() drops the

Send-side reference. The req returns to its free pool only after

both owners have signed off.

The existing krefinit(&req->rlkref) call in

rpcrdmapreparesend_sges() is removed. Initialization moves to

the slot-allocation paths (xprtrdmaalloc_slot and

rpcrdmabcrqstget), and the release callback re-arms rlkref

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:

  • Any rpcrdmareq held by an rpcrqst has rl_kref >= 1.

    xprtrdmaallocslot(), rpcrdmabcrqstget(), and the

    backlog-wake branch in xprtrdmaallocslot() each krefinit

    rl_kref before publishing the req. Without this invariant,

    an RPC task that aborts between slot allocation and marshal

    (gssrefresh failure or signal during callconnect, for

    example) would drive xprt_release() ->

    xprtrdmafreeslot() -> krefput 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 rpcrdmapreparesend_sges()

    runs rpcrdmasendctxcancel(), which DMA-unmaps the sendctx

    and clears screq without touching rlkref. The sendctx

    ring walks in rpcrdmasendctxput_locked() and

    rpcrdmasendctxsdestroy() skip entries with sc_req == NULL,

    so a burst of -EIO marshal failures cannot hold reqs off

    rbsendbufs.

  • The release callback re-arms rl_kref so the next consumer

    enters with the invariant satisfied.

Replies now complete the RPC directly. rpcrdmareplyhandler()

calls rpcrdmacompleterqst() in place of kref_put on the

non-LocalInv branch. The LocalInv branch already completes the

RPC from frwrunmapasync() 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.

rpcrdmasendctxsdestroy() walks the active range and runs

rpcrdmasendctxunmap() on each entry with a non-NULL sc_req

before the request buffers are reset, and is moved ahead of

rpcrdmareqsreset() in rpcrdmaxprtdisconnect() 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

rpcrdmareqrelease() re-adds it to bcpalist. The disconnect

in xprtrdmadestroy() runs after xprtdestroybackchannel() has

already emptied bcpalist, so the drained reqs would otherwise

leak. xprtrdmadestroy() now runs xprtrdmabc_destroy(xprt, 0)

a second time after the disconnect to reclaim them.

Package Versions Affected

Package Version
patch Availability
No items found.

Automatically patch vulnerabilities without upgrading

Fix Without Upgrading
Detect compatible fix
Apply safe remediation
Fix with a single pull request

CVSS Version

Severity
Base Score
CVSS Version
Score Vector
C
H
U
9.8
-
3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
C
H
U
0
-
3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
C
H
U
-

Related Resources

No items found.

References

https://git.kernel.org/stable/c/53442c7d0c888e51b8bc3da196970a669cc6b294, https://git.kernel.org/stable/c/740975054a1970c0cf15f70ac39724a064f45847, https://git.kernel.org/stable/c/8203f760a72bd39a3b66bc4eff0aa272a99fe22b, https://git.kernel.org/stable/c/9f3d9b68c1c6c51746e5ecdb52b2e6a2901de37e, https://git.kernel.org/stable/c/e7632089523acddcdd8f090ad19e96fb3107b04d, https://git.kernel.org/stable/c/e786233d2e0bbff9a82e43f02ae3a46ab4b08ec3, https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/72xxx/CVE-2026-72473.json, https://nvd.nist.gov/vuln/detail/CVE-2026-72473, https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Severity

9.8

CVSS Score
0
10

Basic Information

Base CVSS
9.8
EPSS Probability
0.00664%
EPSS Percentile
0.49073%
Introduced Version
0ab115237025f5e379620bbcd56a02697d07b002,5.3.0,6.2.0,6.7.0,6.13.0,6.19.0,0
Fix Available
e786233d2e0bbff9a82e43f02ae3a46ab4b08ec3,6.1.178,6.6.145,6.12.97,6.18.40,7.1.5,6.1.180-1,6.12.100-1

Fix Critical Vulnerabilities Instantly

Secure your app without upgrading.
Fix Without Upgrading