From: Yousef Alhouseen Date: Thu, 25 Jun 2026 14:23:54 +0000 (+0200) Subject: sctp: fix SCTP_RESET_STREAMS stream list length limit X-Git-Tag: v7.2-rc2~22^2~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b9f5ef534184bd81b8a4772780626c40eed1fd5;p=thirdparty%2Fkernel%2Fstable.git sctp: fix SCTP_RESET_STREAMS stream list length limit SCTP_RESET_STREAMS carries a flexible array of u16 stream IDs, but the optlen clamps treat USHRT_MAX as a byte count and then multiply sizeof(__u16) by the fixed header size. That caps the copied and validated option buffer at about 64 KiB, which rejects valid requests containing more than about half of the u16 stream ID range. Use struct_size_t() for the maximum struct sctp_reset_streams layout instead, so the bound matches the flexible array described by srs_number_streams. Fixes: 5960cefab9df ("sctp: add a ceiling to optlen in some sockopts") Acked-by: Xin Long Signed-off-by: Yousef Alhouseen Link: https://patch.msgid.link/20260625142354.2600-1-alhouseenyousef@gmail.com Signed-off-by: Jakub Kicinski --- diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c8481461f7d8b..c7b9e325ec1cd 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4111,8 +4111,9 @@ static int sctp_setsockopt_reset_streams(struct sock *sk, if (optlen < sizeof(*params)) return -EINVAL; /* srs_number_streams is u16, so optlen can't be bigger than this. */ - optlen = min_t(unsigned int, optlen, USHRT_MAX + - sizeof(__u16) * sizeof(*params)); + optlen = min_t(unsigned int, optlen, + struct_size_t(struct sctp_reset_streams, srs_stream_list, + USHRT_MAX)); if (params->srs_number_streams * sizeof(__u16) > optlen - sizeof(*params)) @@ -4598,8 +4599,8 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, if (optlen > 0) { /* Trim it to the biggest size sctp sockopt may need if necessary */ optlen = min_t(unsigned int, optlen, - PAGE_ALIGN(USHRT_MAX + - sizeof(__u16) * sizeof(struct sctp_reset_streams))); + PAGE_ALIGN(struct_size_t(struct sctp_reset_streams, + srs_stream_list, USHRT_MAX))); kopt = memdup_sockptr(optval, optlen); if (IS_ERR(kopt)) return PTR_ERR(kopt);