Both the lane and the connection-generation negotiation are driven by extension headers in handshake packets, and both are processed unconditionally, even on transports that are not multipath capable. A non-MP connection (t_mp_capable unset) owns exactly one rds_conn_path slot, so a peer claiming up to RDS_MPATH_WORKERS lanes makes every subsequent fan-out walk conn->c_path[0..7] at 504-byte strides past the single allocated slot (KASAN: "Read of size 8 in rds_conn_path_connect_if_down"); the generation negotiation opens a similar out-of-bounds walk on the same array. Only process handshake extension headers when the connection's transport is multipath capable, so a peer can never make us walk lanes that do not exist. Both call sites in rds_recv_incoming() are gated. This is a port of the Oracle UEK fix for the same issue, picked up where Paula's series of the same change left off. This issue was discovered by Tencent CodeBuddy Security. Cc: stable@vger.kernel.org Link: https://lore.kernel.org/netdev/20260825120132.51636-1-pamoutafpro@gmail.com/ Link: https://github.com/oracle/linux-uek/commit/2fdeb0513f18 Fixes: 840df162b3eb ("rds: reduce memory footprint for RDS when transport is RDMA") Fixes: 905dd4184e07 ("RDS: TCP: Track peer's connection generation number") Signed-off-by: Henry Martin --- v2: Replace the two allocation-bound clamps with a port of the UEK t_mp_capable handshake gating (suggested by Allison Henderson), correct the Fixes tags and link Paula's series. net/rds/recv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/rds/recv.c b/net/rds/recv.c index 6204e577a90ae..93ee4546ae362 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -379,7 +379,8 @@ void rds_recv_incoming(struct rds_connection *conn, struct in6_addr *saddr, rds_stats_inc(s_recv_ping); rds_send_pong(cp, inc->i_hdr.h_sport); /* if this is a handshake ping, start multipath if necessary */ - if (RDS_HS_PROBE(be16_to_cpu(inc->i_hdr.h_sport), + if (conn->c_trans->t_mp_capable && + RDS_HS_PROBE(be16_to_cpu(inc->i_hdr.h_sport), be16_to_cpu(inc->i_hdr.h_dport))) { rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn); rds_start_mprds(cp->cp_conn); @@ -387,7 +388,8 @@ void rds_recv_incoming(struct rds_connection *conn, struct in6_addr *saddr, goto out; } - if (be16_to_cpu(inc->i_hdr.h_dport) == RDS_FLAG_PROBE_PORT && + if (conn->c_trans->t_mp_capable && + be16_to_cpu(inc->i_hdr.h_dport) == RDS_FLAG_PROBE_PORT && inc->i_hdr.h_sport == 0) { rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn); /* if this is a handshake pong, start multipath if necessary */ -- 2.43.7