ZeroHour

CVE-2026-89532

niche

Out-of-bounds read and crash via zero-segment chunk in Linux svcrdma (NFS over RDMA)

CVSS 3.1
9.1 critical
EPSS
Published
()
Modified
AI analysis

The Linux kernel's server-side RPC-over-RMA implementation (svcrdma, used for NFS over RDMA) contains a u32 underflow in the pcl_for_each_segment macro: when a parsed chunk has ch_segcount == 0, the inclusive upper bound computes ch_segcount - 1, wrapping to 0xFFFFFFFF and pointing far past the segment array. An unauthenticated remote client can trigger this simply by sending an RPC/RDMA request whose Write or Reply chunk advertises zero segments, because xdr_check_write_chunk() only rejects counts above rc_maxpages and the chunk is linked onto the list before any segments are filled. When Send-With-Invalidate has been negotiated, svc_rdma_get_inv_rkey() walks these chunk lists and dereferences segment->rs_handle on each iteration, turning the underflow into an out-of-bounds read that ends in a general protection fault and kernel crash (CVSS 9.1, network vector, no privileges or user interaction required, with high availability impact and high confidentiality impact scored for the OOB read). Only systems running kernels with the svcrdma code and actually accepting RDMA transports (e.g., NFS servers exporting over RDMA) are exposed. No public proof of concept exists, the flaw is not in the CISA KEV catalog, and no exploitation in the wild is known.

What to do: Apply kernel updates containing the svcrdma pcl_for_each_segment fix as soon as your distro ships it. If NFS over RDMA is not required, disable the NFSD RDMA listener (avoid loading svcrdma) and restrict RDMA service ports (typically 20049/tcp for NFS over RDMA) to trusted client subnets at the fabric firewall. Review logs on RDMA-serving hosts for general protection faults or oopses in svc_rdma paths, which would indicate probing or crash attempts.

Affected
Linux kernel (svcrdma / server-side RPC-over-RDMA, net/sunrpc/xprtrdma)
Estimated exposure
nicheroughly thousands to low tens of thousands of NFS-over-RDMA servers worldwide, nearly all on private fabrics with near-zero direct internet exposure — RDMA transports are almost always deployed on private InfiniBand/RoCE fabrics inside HPC sites and storage backends and are rarely internet-facing; no exposure counts were provided in the data, so this is a deployment-pattern-based…

Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.

Description

In the Linux kernel, the following vulnerability has been resolved: svcrdma: Fix pcl_for_each_segment for empty chunks When a parsed chunk list contains a chunk whose ch_segcount is zero, pcl_for_each_segment computes its inclusive upper bound as &chunk->ch_segments[ch_segcount - 1]. ch_segcount is u32, so the subtraction wraps to 0xFFFFFFFF and the bound lands far past the ch_segments flex array. The loop body then walks unrelated memory at sizeof(struct svc_rdma_segment) stride until it faults. A zero-segcount chunk is reachable from the wire: xdr_check_write_chunk() only rejects segcount values greater than rc_maxpages, and pcl_alloc_write() links a freshly allocated chunk onto rc_write_pcl/rc_reply_pcl before its segment-fill loop runs, so a Write or Reply chunk advertising zero segments leaves ch_segcount == 0 on the list. When the transport has negotiated Send-With-Invalidate, svc_rdma_get_inv_rkey() iterates all four PCLs with pcl_for_each_segment and dereferences segment->rs_handle on each iteration, turning the underflow into an out-of-bounds read and a general protection fault. xdr_check_write_list / xdr_check_reply_chunk pcl_alloc_write() chunk = pcl_alloc_chunk(...) /* ch_segcount = 0 */ list_add_tail(&chunk->ch_list, &pcl->cl_chunks) /* fill loop iterates zero times for wire segcount 0 */ svc_rdma_get_inv_rkey() pcl_for_each_chunk(rc_write_pcl) pcl_for_each_segment(segment, chunk) pos rs_handle /* OOB read -> GPF */ Fix by switching the macro to a half-open upper bound that uses ch_segcount directly. For ch_segcount == 0 the loop start equals the loop end and the body is skipped; for ch_segcount > 0 the iteration range is unchanged. All six existing call sites in net/sunrpc/xprtrdma/svc_rdma_recvfrom.c and net/sunrpc/xprtrdma/svc_rdma_rw.c remain correct under the new bound, so no caller changes are needed.

Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H

In the news

No ingested article mentions this CVE yet.