{"id":7143,"date":"2026-09-04T18:49:26","date_gmt":"2026-09-04T10:49:26","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-72473"},"modified":"2026-09-04T18:49:26","modified_gmt":"2026-09-04T10:49:26","slug":"cve-2026-72473","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-72473","title":{"rendered":"CVE-2026-72473 [CRITICAL] &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nxprtrdma: Decouple re"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>xprtrdma: Decouple req recycling from RPC completion<\/p>\n<p>rl_kref formerly served two distinct lifetimes through a single<br \/>\nrefcount: it gated when a Reply could wake its RPC task, and it<br \/>\ngated when an rpcrdma_req could return to its free pool. The<br \/>\nmarshal path took the Send-side reference only when SGEs needed<br \/>\nDMA-unmap (sc_unmap_count &gt; 0), which made a Send carrying only<br \/>\npre-registered buffers an exception: the Reply handler dropped<br \/>\nrl_kref from 1 to 0 and freed the req while the HCA might still<br \/>\nbe DMA-reading from its send buffer.<\/p>\n<p>Give rl_kref a narrower job. The RPC layer takes one reference<br \/>\nwhen slot allocation hands a req out. rpcrdma_prepare_send_sges()<br \/>\ntakes a Send-side reference unconditionally after WR preparation<br \/>\nsucceeds. xprt_rdma_free_slot() and xprt_rdma_bc_free_rqst() drop<br \/>\nthe RPC-layer reference; rpcrdma_sendctx_unmap() drops the<br \/>\nSend-side reference. The req returns to its free pool only after<br \/>\nboth owners have signed off.<\/p>\n<p>The existing kref_init(&amp;req-&gt;rl_kref) call in<br \/>\nrpcrdma_prepare_send_sges() is removed. Initialization moves to<br \/>\nthe slot-allocation paths (xprt_rdma_alloc_slot and<br \/>\nrpcrdma_bc_rqst_get), and the release callback re-arms rl_kref<br \/>\nbefore the req returns to a free pool. A re-init in the marshal<br \/>\npath would discard the RPC-layer reference that already exists<br \/>\non entry.<\/p>\n<p>Three invariants follow:<\/p>\n<p>  &#8211; Any rpcrdma_req held by an rpc_rqst has rl_kref &gt;= 1.<br \/>\n    xprt_rdma_alloc_slot(), rpcrdma_bc_rqst_get(), and the<br \/>\n    backlog-wake branch in xprt_rdma_alloc_slot() each kref_init<br \/>\n    rl_kref before publishing the req. Without this invariant,<br \/>\n    an RPC task that aborts between slot allocation and marshal<br \/>\n    (gss_refresh failure or signal during call_connect, for<br \/>\n    example) would drive xprt_release() -&gt;<br \/>\n    xprt_rdma_free_slot() -&gt; kref_put against a refcount of<br \/>\n    zero, saturating refcount_t and stranding the slot.<\/p>\n<p>  &#8211; The Send-side reference is taken only after WR prep<br \/>\n    succeeds. A mapping failure in rpcrdma_prepare_send_sges()<br \/>\n    runs rpcrdma_sendctx_cancel(), which DMA-unmaps the sendctx<br \/>\n    and clears sc_req without touching rl_kref. The sendctx<br \/>\n    ring walks in rpcrdma_sendctx_put_locked() and<br \/>\n    rpcrdma_sendctxs_destroy() skip entries with sc_req == NULL,<br \/>\n    so a burst of -EIO marshal failures cannot hold reqs off<br \/>\n    rb_send_bufs.<\/p>\n<p>  &#8211; The release callback re-arms rl_kref so the next consumer<br \/>\n    enters with the invariant satisfied.<\/p>\n<p>Replies now complete the RPC directly. rpcrdma_reply_handler()<br \/>\ncalls rpcrdma_complete_rqst() in place of kref_put on the<br \/>\nnon-LocalInv branch. The LocalInv branch already completes the<br \/>\nRPC from frwr_unmap_async() and is unaffected.<\/p>\n<p>Because Send-side references can now outlive RPC completion,<br \/>\nconnection teardown drains sendctx entries whose unsignaled<br \/>\nSends never had a later signaled completion to walk the ring.<br \/>\nrpcrdma_sendctxs_destroy() walks the active range and runs<br \/>\nrpcrdma_sendctx_unmap() on each entry with a non-NULL sc_req<br \/>\nbefore the request buffers are reset, and is moved ahead of<br \/>\nrpcrdma_reqs_reset() in rpcrdma_xprt_disconnect() so the reqs<br \/>\nare still in their pre-reset state when the Send-side refs are<br \/>\nreleased.<\/p>\n<p>The drain creates a teardown-ordering hazard on the backchannel<br \/>\npath. With the new lifetime, releasing a bc_prealloc req from<br \/>\nrpcrdma_req_release() re-adds it to bc_pa_list. The disconnect<br \/>\nin xprt_rdma_destroy() runs after xprt_destroy_backchannel() has<br \/>\nalready emptied bc_pa_list, so the drained reqs would otherwise<br \/>\nleak. xprt_rdma_destroy() now runs xprt_rdma_bc_destroy(xprt, 0)<br \/>\na second time after the disconnect to reclaim them.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>xprtrdma: Decouple req recycling from RPC completion<\/p>\n<p>rl_kref formerly served two distinct lifetimes through a single<br \/>\nrefcount: it <\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-7143","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/7143","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7143"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7143"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}