From 7c472b40b901a12cfc8dc00ca0a99ac2d992c338 Mon Sep 17 00:00:00 2001 From: Moon Hee Lee Date: Tue, 22 Jul 2025 12:31:16 -0700 Subject: [PATCH net] sctp: guard rto_alpha and rto_beta against unsafe shift values rto_alpha and rto_beta are used as shift amounts in the RTT smoothing calculation, where they represent inverse powers of two (e.g. 3 means 1/8). Currently, the code uses net->sctp.rto_alpha and rto_beta directly in shift expressions without validating them. If user-controlled or corrupted values exceed valid shift bounds for 32-bit integers (e.g. 237), this leads to undefined behavior and runtime faults. syzbot reported such a case via UBSAN: UBSAN: shift-out-of-bounds in net/sctp/transport.c:509:41 shift exponent 237 is too large for 32-bit type 'unsigned int' This patch ensures both values are within the safe shift range [0, 31]. If not, the code falls back to the default constants SCTP_RTO_ALPHA and SCTP_RTO_BETA to ensure correctness and system stability. This preserves SCTP tunability while preventing undefined behavior. Signed-off-by: Moon Hee Lee --- net/sctp/transport.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 6946c1462793..848311bb7a9f 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -495,6 +495,8 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) if (tp->rttvar || tp->srtt) { struct net *net = tp->asoc->base.net; + int rto_alpha = net->sctp.rto_alpha; + int rto_beta = net->sctp.rto_beta; /* 6.3.1 C3) When a new RTT measurement R' is made, set * RTTVAR <- (1 - RTO.Beta) * RTTVAR + RTO.Beta * |SRTT - R'| * SRTT <- (1 - RTO.Alpha) * SRTT + RTO.Alpha * R' @@ -505,7 +507,16 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) * of two. * For example, assuming the default value of RTO.Alpha of * 1/8, rto_alpha would be expressed as 3. + * + * Guard rto_alpha and rto_beta to ensure they are within + * valid shift bounds [0, 31] to avoid undefined behavior. */ + if (unlikely(rto_alpha < 0 || rto_alpha >= 32)) + rto_alpha = SCTP_RTO_ALPHA; + + if (unlikely(rto_beta < 0 || rto_beta >= 32)) + rto_beta = SCTP_RTO_BETA; + tp->rttvar = tp->rttvar - (tp->rttvar >> net->sctp.rto_beta) + (((__u32)abs((__s64)tp->srtt - (__s64)rtt)) >> net->sctp.rto_beta); tp->srtt = tp->srtt - (tp->srtt >> net->sctp.rto_alpha) -- 2.43.0