summaryrefslogtreecommitdiff
path: root/net/sctp
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2017-12-10 15:40:51 +0800
committerDavid S. Miller <davem@davemloft.net>2017-12-11 14:08:21 -0500
commit2342b8d95bcae5946e1b9b8d58645f37500ef2e7 (patch)
treea5923dfab3ed4bcc5689218d47543c791d8e7e95 /net/sctp
parent8f659a03a0ba9289b9aeb9b4470e6fb263d6f483 (diff)
sctp: make sure stream nums can match optlen in sctp_setsockopt_reset_streams
Now in sctp_setsockopt_reset_streams, it only does the check optlen < sizeof(*params) for optlen. But it's not enough, as params->srs_number_streams should also match optlen. If the streams in params->srs_stream_list are less than stream nums in params->srs_number_streams, later when dereferencing the stream list, it could cause a slab-out-of-bounds crash, as reported by syzbot. This patch is to fix it by also checking the stream numbers in sctp_setsockopt_reset_streams to make sure at least it's not greater than the streams in the list. Fixes: 7f9d68ac944e ("sctp: implement sender-side procedures for SSN Reset Request Parameter") Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/socket.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index eb17a911aa29..3253f724a995 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3891,13 +3891,17 @@ static int sctp_setsockopt_reset_streams(struct sock *sk,
struct sctp_association *asoc;
int retval = -EINVAL;
- if (optlen < sizeof(struct sctp_reset_streams))
+ if (optlen < sizeof(*params))
return -EINVAL;
params = memdup_user(optval, optlen);
if (IS_ERR(params))
return PTR_ERR(params);
+ if (params->srs_number_streams * sizeof(__u16) >
+ optlen - sizeof(*params))
+ goto out;
+
asoc = sctp_id2assoc(sk, params->srs_assoc_id);
if (!asoc)
goto out;