From dc121c0084910db985cf1c8ba6fce5d8c307cc02 Mon Sep 17 00:00:00 2001 From: Matt Johnston Date: Tue, 22 Feb 2022 12:17:38 +0800 Subject: mctp: make __mctp_dev_get() take a refcount hold Previously there was a race that could allow the mctp_dev refcount to hit zero: rcu_read_lock(); mdev = __mctp_dev_get(dev); // mctp_unregister() happens here, mdev->refs hits zero mctp_dev_hold(dev); rcu_read_unlock(); Now we make __mctp_dev_get() take the hold itself. It is safe to test against the zero refcount because __mctp_dev_get() is called holding rcu_read_lock and mctp_dev uses kfree_rcu(). Reported-by: Jakub Kicinski Signed-off-by: Matt Johnston Signed-off-by: David S. Miller --- net/mctp/route.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'net/mctp/route.c') diff --git a/net/mctp/route.c b/net/mctp/route.c index fe6c8bf1ec2c..6f277e56b168 100644 --- a/net/mctp/route.c +++ b/net/mctp/route.c @@ -836,7 +836,7 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt, { struct mctp_sock *msk = container_of(sk, struct mctp_sock, sk); struct mctp_skb_cb *cb = mctp_cb(skb); - struct mctp_route tmp_rt; + struct mctp_route tmp_rt = {0}; struct mctp_sk_key *key; struct net_device *dev; struct mctp_hdr *hdr; @@ -948,6 +948,7 @@ out_release: mctp_route_release(rt); dev_put(dev); + mctp_dev_put(tmp_rt.dev); return rc; @@ -1124,11 +1125,13 @@ static int mctp_pkttype_receive(struct sk_buff *skb, struct net_device *dev, rt->output(rt, skb); mctp_route_release(rt); + mctp_dev_put(mdev); return NET_RX_SUCCESS; err_drop: kfree_skb(skb); + mctp_dev_put(mdev); return NET_RX_DROP; } -- cgit v1.2.3