diff options
author | Xin Long <lucien.xin@gmail.com> | 2019-01-28 15:08:39 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-30 00:44:07 -0800 |
commit | 7fb3be13a23697450f3609877c367a3750aba3b5 (patch) | |
tree | 02c38294465f71f5e364c20190f98e284ac1a8ce /net/sctp | |
parent | e0651a0dc87780c03683ca1613a30b982dbf964d (diff) | |
download | linux-stable-7fb3be13a23697450f3609877c367a3750aba3b5.tar.gz linux-stable-7fb3be13a23697450f3609877c367a3750aba3b5.tar.bz2 linux-stable-7fb3be13a23697450f3609877c367a3750aba3b5.zip |
sctp: use SCTP_FUTURE_ASSOC and add SCTP_CURRENT_ASSOC for SCTP_AUTH_KEY sockopt
Check with SCTP_ALL_ASSOC instead in sctp_setsockopt_auth_key.
SCTP_CURRENT_ASSOC is supported for SCTP_AUTH_KEY in this patch.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/socket.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index bba352e93408..ec969c0a7891 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3768,7 +3768,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk, struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_authkey *authkey; struct sctp_association *asoc; - int ret; + int ret = -EINVAL; if (!ep->auth_enable) return -EACCES; @@ -3778,25 +3778,44 @@ static int sctp_setsockopt_auth_key(struct sock *sk, /* authkey->sca_keylength is u16, so optlen can't be bigger than * this. */ - optlen = min_t(unsigned int, optlen, USHRT_MAX + - sizeof(struct sctp_authkey)); + optlen = min_t(unsigned int, optlen, USHRT_MAX + sizeof(*authkey)); authkey = memdup_user(optval, optlen); if (IS_ERR(authkey)) return PTR_ERR(authkey); - if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) { - ret = -EINVAL; + if (authkey->sca_keylength > optlen - sizeof(*authkey)) goto out; - } asoc = sctp_id2assoc(sk, authkey->sca_assoc_id); - if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)) { - ret = -EINVAL; + if (!asoc && authkey->sca_assoc_id > SCTP_ALL_ASSOC && + sctp_style(sk, UDP)) goto out; + + if (asoc) { + ret = sctp_auth_set_key(ep, asoc, authkey); + goto out; + } + + if (authkey->sca_assoc_id == SCTP_FUTURE_ASSOC || + authkey->sca_assoc_id == SCTP_ALL_ASSOC) { + ret = sctp_auth_set_key(ep, asoc, authkey); + if (ret) + goto out; + } + + ret = 0; + + if (authkey->sca_assoc_id == SCTP_CURRENT_ASSOC || + authkey->sca_assoc_id == SCTP_ALL_ASSOC) { + list_for_each_entry(asoc, &ep->asocs, asocs) { + int res = sctp_auth_set_key(ep, asoc, authkey); + + if (res && !ret) + ret = res; + } } - ret = sctp_auth_set_key(ep, asoc, authkey); out: kzfree(authkey); return ret; |