From: "D. Wythe" <alibuda@xxxxxxxxxxxxxxxxx> Consider the following scenario: smc_close_passive_work smc_listen_out_connected lock_sock() if (state == SMC_INIT) if (state == SMC_INIT) state = SMC_APPCLOSEWAIT1; state = SMC_ACTIVE release_sock() This would cause the state machine of the connection to be corrupted. Also, this issue can occur in smc_listen_out_err(). To solve this problem, we can protect the state transitions under the lock of sock to avoid collision. Fixes: 3b2dec2603d5 ("net/smc: restructure client and server code in af_smc") Signed-off-by: D. Wythe <alibuda@xxxxxxxxxxxxxxxxx> --- net/smc/af_smc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 5ad2a9f..3bb8265 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -1926,8 +1926,10 @@ static void smc_listen_out_connected(struct smc_sock *new_smc) { struct sock *newsmcsk = &new_smc->sk; + lock_sock(newsmcsk); if (newsmcsk->sk_state == SMC_INIT) newsmcsk->sk_state = SMC_ACTIVE; + release_sock(newsmcsk); smc_listen_out(new_smc); } @@ -1939,9 +1941,12 @@ static void smc_listen_out_err(struct smc_sock *new_smc) struct net *net = sock_net(newsmcsk); this_cpu_inc(net->smc.smc_stats->srv_hshake_err_cnt); + + lock_sock(newsmcsk); if (newsmcsk->sk_state == SMC_INIT) sock_put(&new_smc->sk); /* passive closing */ newsmcsk->sk_state = SMC_CLOSED; + release_sock(newsmcsk); smc_listen_out(new_smc); } -- 1.8.3.1