diff options
| author | Chuck Lever <chuck.lever@oracle.com> | 2026-05-26 09:36:00 -0400 |
|---|---|---|
| committer | Chuck Lever <cel@kernel.org> | 2026-06-30 09:13:42 -0400 |
| commit | 33045a9f17e33ebdcce61ae51369d2afc9c6b0d6 (patch) | |
| tree | da1e1afb88cc5d3d3d14f1d8ab0120e6cb5b27a1 /include | |
| parent | ab33baa3d0c1766807e65560e59bbd71f552b4ef (diff) | |
| download | linux-next-33045a9f17e33ebdcce61ae51369d2afc9c6b0d6.tar.gz linux-next-33045a9f17e33ebdcce61ae51369d2afc9c6b0d6.zip | |
svcrdma: Validate Read chunk positions at decode time
Read chunk position and length validation is currently scattered
across three consumer functions: svc_rdma_read_data_item(),
svc_rdma_read_multiple_chunks(), and svc_rdma_read_call_chunk().
Each independently guards against the same class of unsigned
arithmetic underflow from untrusted wire values. Any new consumer
of the parsed Read chunk list must replicate these checks or risk
re-introducing the defects fixed by earlier patches in this series.
Add pcl_check_read_chunk_positions() to consolidate position and
length validation into a single post-decode pass, called from
svc_rdma_xdr_decode_req() after all three chunk lists have been
parsed and the inline body length is known. The pass verifies
three properties:
- Each Read chunk's inline-body offset (its unreduced-stream
position minus the cumulative length of preceding Read chunks)
falls within the inline body length, or within the Call chunk
length for interleaved reads.
- Adjacent Read chunk positions do not overlap: cumulative read
bytes at each transition do not exceed the next position.
- Each chunk length does not exceed the receive context's page
budget.
Malformed frames are rejected before reaching any consumer. The
existing consumer-side guards remain as defense in depth.
Acked-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/sunrpc/svc_rdma_pcl.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/sunrpc/svc_rdma_pcl.h b/include/linux/sunrpc/svc_rdma_pcl.h index 655681cf8fed..6346d8cf2587 100644 --- a/include/linux/sunrpc/svc_rdma_pcl.h +++ b/include/linux/sunrpc/svc_rdma_pcl.h @@ -119,6 +119,8 @@ extern bool pcl_alloc_call(struct svc_rdma_recv_ctxt *rctxt, __be32 *p); extern bool pcl_alloc_read(struct svc_rdma_recv_ctxt *rctxt, __be32 *p); extern bool pcl_alloc_write(struct svc_rdma_recv_ctxt *rctxt, struct svc_rdma_pcl *pcl, __be32 *p); +extern bool pcl_check_read_chunk_positions(struct svc_rdma_recv_ctxt *rctxt, + unsigned int inline_len); extern int pcl_process_nonpayloads(const struct svc_rdma_pcl *pcl, const struct xdr_buf *xdr, int (*actor)(const struct xdr_buf *, |
