diff options
author | Xin Long <lucien.xin@gmail.com> | 2021-08-01 02:25:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-08-12 13:19:39 +0200 |
commit | f91e7bd934c705f25dc6651e29e9c857d48a51f4 (patch) | |
tree | f61c97cedc18cd0df8fdd800ee5ac213dc244faa /net | |
parent | 9309cd087b4d9dbb40395d37e5ea2072422a1b95 (diff) | |
download | linux-stable-f91e7bd934c705f25dc6651e29e9c857d48a51f4.tar.gz linux-stable-f91e7bd934c705f25dc6651e29e9c857d48a51f4.tar.bz2 linux-stable-f91e7bd934c705f25dc6651e29e9c857d48a51f4.zip |
sctp: move the active_key update after sh_keys is added
[ Upstream commit ae954bbc451d267f7d60d7b49db811d5a68ebd7b ]
In commit 58acd1009226 ("sctp: update active_key for asoc when old key is
being replaced"), sctp_auth_asoc_init_active_key() is called to update
the active_key right after the old key is deleted and before the new key
is added, and it caused that the active_key could be found with the key_id.
In Ying Xu's testing, the BUG_ON in sctp_auth_asoc_init_active_key() was
triggered:
[ ] kernel BUG at net/sctp/auth.c:416!
[ ] RIP: 0010:sctp_auth_asoc_init_active_key.part.8+0xe7/0xf0 [sctp]
[ ] Call Trace:
[ ] sctp_auth_set_key+0x16d/0x1b0 [sctp]
[ ] sctp_setsockopt.part.33+0x1ba9/0x2bd0 [sctp]
[ ] __sys_setsockopt+0xd6/0x1d0
[ ] __x64_sys_setsockopt+0x20/0x30
[ ] do_syscall_64+0x5b/0x1a0
So fix it by moving the active_key update after sh_keys is added.
Fixes: 58acd1009226 ("sctp: update active_key for asoc when old key is being replaced")
Reported-by: Ying Xu <yinxu@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/auth.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index b2ca66c4a21d..9e0c98df20da 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -880,14 +880,18 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength); cur_key->key = key; - if (replace) { - list_del_init(&shkey->key_list); - sctp_auth_shkey_release(shkey); - if (asoc && asoc->active_key_id == auth_key->sca_keynumber) - sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL); + if (!replace) { + list_add(&cur_key->key_list, sh_keys); + return 0; } + + list_del_init(&shkey->key_list); + sctp_auth_shkey_release(shkey); list_add(&cur_key->key_list, sh_keys); + if (asoc && asoc->active_key_id == auth_key->sca_keynumber) + sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL); + return 0; } |