Connections on the IB transport (t_mp_capable unset) own exactly one rds_conn_path slot, but the peer can still claim eight lanes through the NPATHS extension header of a handshake packet, and every subsequent fan-out path then treats all eight entries as real: the mp-start helper iterates conn->c_path[0..7], dereferencing cp->cp_conn, taking cp->cp_lock and queueing delayed work on cp->cp_wq at 504-byte strides into whatever comes after the single allocated slot (KASAN: "Read of size 8 in rds_conn_path_connect_if_down"). The negotiated lane count is now clamped to the same value the transport was allocated with (trans->t_mp_capable ? RDS_MPATH_WORKERS : 1), so a peer can never ask us to walk lanes that do not exist. This vulnerability was discovered by Tencent CodeBuddy Security. Cc: stable@vger.kernel.org Fixes: ba3d1f480c7a ("net/rds: size a connection's path set by the transport it ends up with") Signed-off-by: Henry Martin --- net/rds/recv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -224,7 +224,8 @@ /* Process extension header here */ switch (type) { case RDS_EXTHDR_NPATHS: - new_npaths = min_t(int, RDS_MPATH_WORKERS, + new_npaths = min_t(int, conn->c_trans->t_mp_capable ? + RDS_MPATH_WORKERS : 1, be16_to_cpu(buffer.rds_npaths)); break; case RDS_EXTHDR_GEN_NUM: -- 2.43.7