net: mctp: move expiry timer delete to unhash
authorJeremy Kerr <jk@codeconstruct.com.au>
Tue, 24 Jan 2023 02:01:04 +0000 (10:01 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 25 Jan 2023 13:07:37 +0000 (13:07 +0000)
Currently, we delete the key expiry timer (in sk->close) before
unhashing the sk. This means that another thread may find the sk through
its presence on the key list, and re-queue the timer.

This change moves the timer deletion to the unhash, after we have made
the key no longer observable, so the timer cannot be re-queued.

Fixes: 7b14e15ae6f4 ("mctp: Implement a timeout for tags")
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/mctp/af_mctp.c

index fc9e728b6333a1f126d8ac615e28fb66028217bc..fb6ae3110528af9f6d17bb543b08272c5c10dd2d 100644 (file)
@@ -544,9 +544,6 @@ static int mctp_sk_init(struct sock *sk)
 
 static void mctp_sk_close(struct sock *sk, long timeout)
 {
-       struct mctp_sock *msk = container_of(sk, struct mctp_sock, sk);
-
-       del_timer_sync(&msk->key_expiry);
        sk_common_release(sk);
 }
 
@@ -581,6 +578,12 @@ static void mctp_sk_unhash(struct sock *sk)
                __mctp_key_remove(key, net, fl2, MCTP_TRACE_KEY_CLOSED);
        }
        spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
+
+       /* Since there are no more tag allocations (we have removed all of the
+        * keys), stop any pending expiry events. the timer cannot be re-queued
+        * as the sk is no longer observable
+        */
+       del_timer_sync(&msk->key_expiry);
 }
 
 static struct proto mctp_proto = {