[PATCH] RDMA/rxe: Validate inline data range in user WQEs

Jiale Yao posted 1 patch an hour ago
drivers/infiniband/sw/rxe/rxe_req.c | 9 +++++++++
1 file changed, 9 insertions(+)
[PATCH] RDMA/rxe: Validate inline data range in user WQEs
Posted by Jiale Yao an hour ago
For a user QP, the send queue is an mmap'd ring which userspace writes
directly.  rxe_post_send() only schedules the send task for such a QP,
so rxe_requester() must validate the WQE before using it.

Commit 126c757e4cd46f866ddc283143b58eb4d9bf52cd ("RDMA/rxe:
Validate num_sge/cur_sge before indexing wqe->dma.sge[]") added bounds
checks for two members of the userspace-controlled dma structure, but
left sge_offset unchecked.  For an inline WQE, finish_packet() uses that
value directly as an index into inline_data[] and copies dma.resid bytes
from the resulting pointer into the packet payload.

A local user with access to uverbs can therefore put an out-of-range
sge_offset in the mmap'd SQ ring.  This can disclose kernel memory in the
outgoing packet or cause a vmalloc out-of-bounds access.

Validate that the remaining inline data range fits in the per-WQE inline
area.  Check the offset first and use subtraction for the length check to
avoid an integer overflow.

I reproduced this on Linux 7.3-rc4 with an RC user QP, IB_SEND_INLINE,
a 64-byte residual length, and sge_offset set to 0x100000.  KASAN
reported:

  BUG: KASAN: vmalloc-out-of-bounds in rxe_requester+0x1f27/0x4940
  Read of size 64 at addr ffffc90000191250 by task kworker/u16:0/12
  Workqueue: rxe_wq do_work
  Call Trace:
   __asan_memcpy
   rxe_requester+0x1f27/0x4940
   rxe_sender+0xe/0x30
   do_work+0x184/0x3d0
   process_scheduled_works+0x7c0/0xf10

Fixes: 8700e3e7c485 ("Soft RoCE driver")
Link: https://lore.kernel.org/all/20260708224534.1206-1-security@auditcode.ai/
Signed-off-by: Jiale Yao <yaojiale02@163.com>
---
 drivers/infiniband/sw/rxe/rxe_req.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
index 24f5c044363f..f3b3f65d1d0c 100644
--- a/drivers/infiniband/sw/rxe/rxe_req.c
+++ b/drivers/infiniband/sw/rxe/rxe_req.c
@@ -716,6 +716,15 @@ int rxe_requester(struct rxe_qp *qp)
 		goto err;
 	}
 
+	if (unlikely((wqe->wr.send_flags & IB_SEND_INLINE) &&
+		     (wqe->dma.sge_offset > qp->sq.max_inline ||
+		      wqe->dma.resid >
+		      qp->sq.max_inline - wqe->dma.sge_offset))) {
+		rxe_dbg_qp(qp, "invalid inline data range in send wqe\n");
+		wqe->status = IB_WC_LOC_QP_OP_ERR;
+		goto err;
+	}
+
 	if (rxe_wqe_is_fenced(qp, wqe)) {
 		qp->req.wait_fence = 1;
 		goto exit;
-- 
2.34.1