All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] RDMA/rtrs-srv: Reject usr_len larger than off in process_{read,write}
@ 2026-06-16 16:52 Zhenhao Wan
  2026-06-17 12:10 ` Leon Romanovsky
  0 siblings, 1 reply; 2+ messages in thread
From: Zhenhao Wan @ 2026-06-16 16:52 UTC (permalink / raw)
  To: Md. Haris Iqbal, Jack Wang, Jason Gunthorpe, Leon Romanovsky,
	Danil Kipnis
  Cc: Jack Wang, linux-rdma, linux-kernel, Yuhao Jiang, stable,
	Zhenhao Wan

process_read() and process_write() derive the data length of an I/O
request as:

	usr_len = le16_to_cpu(req->usr_len);
	data_len = off - usr_len;

off comes from the RDMA-Write-with-imm immediate and is only bounded
above (off < max_chunk_size) in rtrs_srv_rdma_done(). usr_len is read
from the chunk buffer the remote peer fills over RDMA, so it is peer
controlled over the full u16 range and is not checked against off.

If a peer sends usr_len > off, the size_t subtraction underflows and
the pointer data + data_len passed to the ->rdma_ev() callback points
before the chunk. The in-tree consumer rnbd_srv_rdma_ev() dereferences
it as the message header (le16_to_cpu(hdr->type)) before validating it;
this is an out-of-bounds read reachable from a remote peer.

Reject usr_len > off before computing data_len in both paths, via the
existing send_err_msg path. For a well-formed request off is the total
length data_len + usr_len, so usr_len <= off holds and valid requests
are unaffected.

Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Zhenhao Wan <whi4ed0g@gmail.com>
---
 drivers/infiniband/ulp/rtrs/rtrs-srv.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
index 6482ad859bd1..ec3f6c2fb0b9 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
@@ -1067,6 +1067,13 @@ static void process_read(struct rtrs_srv_con *con,
 	id->msg_id	= buf_id;
 	id->rd_msg	= msg;
 	usr_len = le16_to_cpu(msg->usr_len);
+	if (usr_len > off) {
+		rtrs_err_rl(s,
+			    "Processing read request failed, invalid usr_len %zu > off %u\n",
+			    usr_len, off);
+		ret = -EINVAL;
+		goto send_err_msg;
+	}
 	data_len = off - usr_len;
 	data = page_address(srv->chunks[buf_id]);
 	ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,
@@ -1120,6 +1127,13 @@ static void process_write(struct rtrs_srv_con *con,
 	id->msg_id = buf_id;
 
 	usr_len = le16_to_cpu(req->usr_len);
+	if (usr_len > off) {
+		rtrs_err_rl(s,
+			    "Processing write request failed, invalid usr_len %zu > off %u\n",
+			    usr_len, off);
+		ret = -EINVAL;
+		goto send_err_msg;
+	}
 	data_len = off - usr_len;
 	data = page_address(srv->chunks[buf_id]);
 	ret = ctx->ops.rdma_ev(srv->priv, id, data, data_len,

---
base-commit: a48671671df5158a0b8e564cd509e04a090a941b
change-id: 20260617-rtrs-srv-usr-len-underflow-e51072f76985

Best regards,
--  
Zhenhao Wan <whi4ed0g@gmail.com>


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-06-17 12:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 16:52 [PATCH] RDMA/rtrs-srv: Reject usr_len larger than off in process_{read,write} Zhenhao Wan
2026-06-17 12:10 ` Leon Romanovsky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.