svcrdma: silently discard undersized messages
Subsystems (5)
PATCH 1/1 svcrdma: silently discard undersized messages
RFC 8166 requires an RPC-over-RDMA message shorter than the 28-byte minimum header to be silently discarded because its XID cannot be trusted.
svc_rdma_xdr_decode_req() instead returns -EINVAL when the fixed header cannot be decoded. svc_rdma_recvfrom() turns that into an RDMA_ERROR, whose encoder copies the first two words from rc_recv_buf without checking rc_byte_len. A zero- to seven-byte SEND can therefore return up to eight bytes that were not supplied by the peer.
Check the complete minimum header length before parsing and use the decoder's existing silent-drop return for undersized input. This keeps the error encoder from reading beyond the received message and follows the protocol requirement.
On an unpatched nfsd-testing kernel at 764ffa45f3f2, a two-VM Soft-iWARP test sent 128 complete 28-byte bad-version headers over connection A. After closing that connection, it sent 128 zero-byte SENDs over connection B. All 128 zero-byte requests received replies, and 56 of those replies contained the exact XID and version markers left by connection A. The test process ran as uid/gid 65534 with no effective capabilities and NoNewPrivs set.
With this patch applied, all eight complete 28-byte bad-version headers elicited replies. A zero-byte SEND and a 27-byte SEND each elicited no reply during a five-second observation interval. A normal NFSv4.1/RDMA mount, write, readback, and unmount completed successfully. The server remained running without an oops or panic. Both x86-64 kernels built with GCC 12.2 and CONFIG_WERROR=y without warnings.
The vulnerability research and validation were conducted by members of the Tobabz team as part of the Best of the Best 15th program.
--- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +4 -1
@@ -714,6 +714,9 @@ static int svc_rdma_xdr_decode_req(struct xdr_buf *rq_arg,__be32 *p, *rdma_argp;unsigned int hdr_len; +if (unlikely (rq_arg->len <RPCRDMA_HDRLEN_MIN )) + goto out_short; + rdma_argp = rq_arg->head[0 ].iov_base;xdr_init_decode (&rctxt->rc_stream, rq_arg, rdma_argp,NULL );
@@ -758,7 +761,7 @@ static int svc_rdma_xdr_decode_req(struct xdr_buf *rq_arg, out_short:trace_svcrdma_decode_short_err (rctxt, rq_arg->len); -return -EINVAL ; +return 0 ; out_version:trace_svcrdma_decode_badvers_err (rctxt, rdma_argp);
base-commit: 764ffa45f3f2189cd86ec6d46d248fc0440507b6
Signature · 1 line
2.50.1 (Apple Git-155)
[email protected]
AI reviewSashiko has reviewed this patch and found no issues.
Quoted 15 lines
RFC 8166 requires an RPC-over-RDMA message shorter than the 28-byte minimum header to be silently discarded because its XID cannot be trusted.
svc_rdma_xdr_decode_req()instead returns-EINVALwhen the fixed header cannot be decoded.svc_rdma_recvfrom()turns that into anRDMA_ERROR, whose encoder copies the first two words fromrc_recv_bufwithout checkingrc_byte_len. A zero- to seven-byte SEND can therefore return up to eight bytes that were not supplied by the peer.Check the complete minimum header length before parsing and use the decoder's existing silent-drop return for undersized input. This keeps the error encoder from reading beyond the received message and follows the protocol requirement.
Quoted 6 lines
[ ... ]
Fixes f3ea53fb3bc3 ("svcrdma: Use correct XID in error replies")Assisted-by LLMSigned-off-by Hyunsol Mun <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
Chuck Lever
maintainerQuoted 11 lines · Hyunsol Mun
RFC 8166 requires an RPC-over-RDMA message shorter than the 28-byte minimum header to be silently discarded because its XID cannot be trusted.
svc_rdma_xdr_decode_req()instead returns-EINVALwhen the fixed header cannot be decoded.svc_rdma_recvfrom()turns that into anRDMA_ERROR, whose encoder copies the first two words fromrc_recv_bufwithout checkingrc_byte_len. A zero- to seven-byte SEND can therefore return up to eight bytes that were not supplied by the peer.[...]
Applied to nfsd-testing, thanks!
[1/1] svcrdma: silently discard undersized messages
commit: 667147c17f15824c00a5b2fcfdb66283c3f4cad6
--
Chuck Lever