Thread (2 messages) 2 messages, 2 authors, 5d ago
COOLING5d REVIEWED: 1 (0M)

[PATCH net 1/1] net: rds: reject oversized TCP receive messages

From: Ren Wei <hidden>
Date: 2026-07-03 04:51:31
Also in: linux-rdma
Subsystem: networking [general], rds - reliable datagram sockets, the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Allison Henderson, Linus Torvalds

From: Wyatt Feng <redacted>

RDS/TCP trusts the wire h_len value once the 48-byte RDS header has
been assembled. A peer can advertise a length larger than
RDS_MAX_MSG_SIZE and force unbounded receive-side reassembly growth by
streaming payload into ti_skb_list until memory is exhausted.

Validate h_len against the existing RDS_MAX_MSG_SIZE limit before any
payload is queued. If the header is oversized, tear down the partial
incoming message, stop tcp_read_sock() immediately, and drop the
connection as a protocol error.

This keeps the sender-side and receiver-side message size contract
consistent and fixes the resource exhaustion bug in the TCP receive
path.

Fixes: 70041088e3b9 ("RDS: Add TCP transport to RDS")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <redacted>
Reported-by: Yifan Wu <redacted>
Reported-by: Juefei Pu <redacted>
Reported-by: Zhengchuan Liang <redacted>
Reported-by: Xin Liu <redacted>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Wyatt Feng <redacted>
Reviewed-by: Ren Wei <redacted>
---
 net/rds/tcp_recv.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index ffe843ca219c..2044b8551b4f 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -205,9 +205,26 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb,
 			offset += to_copy;
 
 			if (tc->t_tinc_hdr_rem == 0) {
+				u32 h_len;
+
+				h_len = be32_to_cpu(tinc->ti_inc.i_hdr.h_len);
+				if (h_len > RDS_MAX_MSG_SIZE) {
+					tc->t_tinc_hdr_rem = sizeof(struct rds_header);
+					tc->t_tinc_data_rem = 0;
+					tc->t_tinc = NULL;
+					rds_inc_put(&tinc->ti_inc);
+					tinc = NULL;
+					desc->count = 0;
+					desc->error = -EMSGSIZE;
+					rds_conn_path_error(cp,
+						"incoming message too large: %u bytes\n",
+						h_len);
+					left = 0;
+					goto out;
+				}
+
 				/* could be 0 for a 0 len message */
-				tc->t_tinc_data_rem =
-					be32_to_cpu(tinc->ti_inc.i_hdr.h_len);
+				tc->t_tinc_data_rem = h_len;
 				tinc->ti_inc.i_rx_lat_trace[RDS_MSG_RX_START] =
 					local_clock();
 			}
-- 
2.47.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help