CVE-2026-93224: svcrdma: Fix unmatched rn_unregister on failed accept
In the Linux kernel, the following vulnerability has been resolved:
svcrdma: Fix unmatched rnunregister on failed accept
When svcrdmaaccept() takes the errout path before rpcrdmarnregister() has succeeded, the existing cleanup block calls rpcrdmarnunregister(dev, &newxprt->scrn) unconditionally. svcxprtrdma is kzalloc'd, so on that path scrn.rnindex is 0 and scrn.rndone is NULL; the unregister therefore xaerase()s another caller's slot 0 and performs an unmatched krefput() on the rpcrdmadevice's rdkref.
The same errout also brackets the cleanup with svcxprtget()/ svcxprtput() around the krefinit() birth reference. The kref goes 1 -> 2 -> 1 and never reaches 0, so the svcxprtrdma (and the net/nstracker it pinned) is leaked on every failed accept.
rpcrdmarnregister() writes rn->rndone last, only after xaalloc() and krefget() have both succeeded, so rndone == NULL is a natural "never registered" sentinel. Guard rpcrdmarnunregister() with an early return when rndone is NULL, and clear rndone before the matching xaerase() so a repeated unregister is also a no-op.
With that guard in place, the accept errout drops the krefinit() birth reference via svcxprtput(), which dispatches svcrdmafree(). Teardown of scqp, scsqcq, scrqcq, and scpd runs under existing ISERR/NULL guards in svcrdmafree(); scrn is covered by the new rndone sentinel; sccmid is non-NULL on every errout path because svcrdmaaccept() dereferences it above the first goto errout.
svcxprtfree() drops the module reference associated with the freed transport, and svchandlexprt() drops its pre-acquired reference when ->xpoaccept() returns NULL. Take a replacement module reference before svcxprtput() so the two moduleput()s remain balanced.
The rndone guard also covers svcrdmafree()'s non-listener call to rpcrdmarnunregister() for transports whose register attempt failed or never ran.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
debian/linuxto a version that resolves this vulnerability.Fixed in 6.1.176-1Fixed in 6.1.190-1Fixed in 6.12.115-2Fixed in 7.2.12-1Fixed in 7.2.15-1 - Upgrade
Upgrade
debian/linux-6.12to a version that resolves this vulnerability.Fixed in 6.12.113-1~deb12u1 - Upgrade
Upgrade
ubuntu/linux-hwe-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-42.42~24.04.1 - Upgrade
Upgrade
ubuntu/linux-riscv-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-42.42.1~24.04.1 - Upgrade
Upgrade
ubuntu/linuxto a version that resolves this vulnerability.Fixed in 7.0.0-42.42 - Upgrade
Upgrade
ubuntu/linux-awsto a version that resolves this vulnerability.Fixed in 7.0.0-1016.17 - Upgrade
Upgrade
ubuntu/linux-gcpto a version that resolves this vulnerability.Fixed in 7.0.0-1016.18 - Upgrade
Upgrade
ubuntu/linux-ibmto a version that resolves this vulnerability.Fixed in 7.0.0-1017.17 - Upgrade
Upgrade
ubuntu/linux-oem-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-1017.17 - Upgrade
Upgrade
ubuntu/linux-oracleto a version that resolves this vulnerability.Fixed in 7.0.0-1015.16 - Upgrade
Upgrade
ubuntu/linux-riscvto a version that resolves this vulnerability.Fixed in 7.0.0-42.42.1 - Compensating control
Guard rpcrdma_rn_unregister() with an early return when rn_done is NULL, and clear rn_done before the matching xa_erase() so repeated unregister calls are no-ops.
- Compensating control
In the svc_rdma_accept() errout path, take a replacement module reference before svc_xprt_put() so the two module_put() calls remain balanced, and bracket cleanup with svc_xprt_get()/svc_xprt_put() around the kref_init() birth reference.
Event History
Frequently Asked Questions
Which systems are affected by this cleanup flaw?
The issue is relevant when the svcrdma accept path fails before rpcrdma_rn_register() has completed successfully. In that state, the transport's rn_done field remains NULL.
What can happen when the failed-accept cleanup runs?
The unconditional unregister can erase another caller's slot 0 and perform an unmatched kref_put() on the rpcrdma device. The failed accept can also leak the svcxprt_rdma object and the net/ns_tracker it pins.
What state should prevent unregister from running?
A NULL rn_done indicates that registration never completed and should make unregister a no-op. Clearing rn_done before the matching xa_erase also makes a repeated unregister a no-op.