aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUrsula Braun <ubraun@linux.ibm.com>2019-04-11 11:17:34 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-10 09:53:44 +0200
commit3ddc2a10070675fc93cf36d0496ba5bf78ef667a (patch)
tree608052f2ec2798ecf5d673e43ed9f5293b9abd05
parentcd54dc4cd37d0b18280c29f2bf25ba08d6895b3c (diff)
downloadlinux-stable-3ddc2a10070675fc93cf36d0496ba5bf78ef667a.tar.gz
net/smc: move unhash before release of clcsock
[ Upstream commit f61bca58f6c36e666c2b807697f25e5e98708162 ] Commit <26d92e951fe0> ("net/smc: move unhash as early as possible in smc_release()") fixes one occurrence in the smc code, but the same pattern exists in other places. This patch covers the remaining occurrences and makes sure, the unhash operation is done before the smc->clcsock is released. This avoids a potential use-after-free in smc_diag_dump(). Reviewed-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: Ursula Braun <ubraun@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--net/smc/af_smc.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index e6e506b2db99eb..9bbab6ba2dab0d 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -848,11 +848,11 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
if (rc < 0)
lsk->sk_err = -rc;
if (rc < 0 || lsk->sk_state == SMC_CLOSED) {
+ new_sk->sk_prot->unhash(new_sk);
if (new_clcsock)
sock_release(new_clcsock);
new_sk->sk_state = SMC_CLOSED;
sock_set_flag(new_sk, SOCK_DEAD);
- new_sk->sk_prot->unhash(new_sk);
sock_put(new_sk); /* final */
*new_smc = NULL;
goto out;
@@ -903,11 +903,11 @@ struct sock *smc_accept_dequeue(struct sock *parent,
smc_accept_unlink(new_sk);
if (new_sk->sk_state == SMC_CLOSED) {
+ new_sk->sk_prot->unhash(new_sk);
if (isk->clcsock) {
sock_release(isk->clcsock);
isk->clcsock = NULL;
}
- new_sk->sk_prot->unhash(new_sk);
sock_put(new_sk); /* final */
continue;
}
@@ -932,6 +932,7 @@ void smc_close_non_accepted(struct sock *sk)
sock_set_flag(sk, SOCK_DEAD);
sk->sk_shutdown |= SHUTDOWN_MASK;
}
+ sk->sk_prot->unhash(sk);
if (smc->clcsock) {
struct socket *tcp;
@@ -947,7 +948,6 @@ void smc_close_non_accepted(struct sock *sk)
smc_conn_free(&smc->conn);
}
release_sock(sk);
- sk->sk_prot->unhash(sk);
sock_put(sk); /* final sock_put */
}