diff options
author | Xin Long <lucien.xin@gmail.com> | 2018-10-29 18:13:11 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-11-04 16:50:53 +0300 |
commit | 2b52f2c4e5e7da9203b0e8762e68dc3f3305b634 (patch) | |
tree | 5f521351f5c25a29a7104a1cdbb778d9319ba8b7 /net/sctp | |
parent | 7ce2e02cc6e819563ad7c6ea2db9de7a2e646d69 (diff) | |
download | linux-2b52f2c4e5e7da9203b0e8762e68dc3f3305b634.tar.xz |
sctp: check policy more carefully when getting pr status
[ Upstream commit 713358369382cebf92f6e98ce2005f94e7344931 ]
When getting pr_assocstatus and pr_streamstatus by sctp_getsockopt,
it doesn't correctly process the case when policy is set with
SCTP_PR_SCTP_ALL | SCTP_PR_SCTP_MASK. It even causes a
slab-out-of-bounds in sctp_getsockopt_pr_streamstatus().
This patch fixes it by return -EINVAL for this case.
Fixes: 0ac1077e3a54 ("sctp: get pr_assoc and pr_stream all status with SCTP_PR_SCTP_ALL")
Reported-by: syzbot+5da0d0a72a9e7d791748@syzkaller.appspotmail.com
Suggested-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/socket.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c1c1bda334a4..c1693e28aed4 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -7101,14 +7101,15 @@ static int sctp_getsockopt_pr_assocstatus(struct sock *sk, int len, } policy = params.sprstat_policy; - if (!policy || (policy & ~(SCTP_PR_SCTP_MASK | SCTP_PR_SCTP_ALL))) + if (!policy || (policy & ~(SCTP_PR_SCTP_MASK | SCTP_PR_SCTP_ALL)) || + ((policy & SCTP_PR_SCTP_ALL) && (policy & SCTP_PR_SCTP_MASK))) goto out; asoc = sctp_id2assoc(sk, params.sprstat_assoc_id); if (!asoc) goto out; - if (policy & SCTP_PR_SCTP_ALL) { + if (policy == SCTP_PR_SCTP_ALL) { params.sprstat_abandoned_unsent = 0; params.sprstat_abandoned_sent = 0; for (policy = 0; policy <= SCTP_PR_INDEX(MAX); policy++) { @@ -7160,7 +7161,8 @@ static int sctp_getsockopt_pr_streamstatus(struct sock *sk, int len, } policy = params.sprstat_policy; - if (!policy || (policy & ~(SCTP_PR_SCTP_MASK | SCTP_PR_SCTP_ALL))) + if (!policy || (policy & ~(SCTP_PR_SCTP_MASK | SCTP_PR_SCTP_ALL)) || + ((policy & SCTP_PR_SCTP_ALL) && (policy & SCTP_PR_SCTP_MASK))) goto out; asoc = sctp_id2assoc(sk, params.sprstat_assoc_id); |