diff mbox series

[4.4,4.9] can: gw: synchronize rcu operations before removing gw job entry

Message ID 20210712153036.5937-1-socketcan@hartkopp.net
State New
Headers show
Series [4.4,4.9] can: gw: synchronize rcu operations before removing gw job entry | expand

Commit Message

Oliver Hartkopp July 12, 2021, 3:30 p.m. UTC
From: Oliver Hartkopp <socketcan@hartkopp.net>

commit fb8696ab14adadb2e3f6c17c18ed26b3ecd96691 upstream.

can_can_gw_rcv() is called under RCU protection, so after calling
can_rx_unregister(), we have to call synchronize_rcu in order to wait
for any RCU read-side critical sections to finish before removing the
kmem_cache entry with the referenced gw job entry.

Link: https://lore.kernel.org/r/20210618173645.2238-1-socketcan@hartkopp.net
Fixes: c1aabdf379bc ("can-gw: add netlink based CAN routing")
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 net/can/gw.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Greg KH July 15, 2021, 11:53 a.m. UTC | #1
On Mon, Jul 12, 2021 at 05:30:35PM +0200, Oliver Hartkopp wrote:
> From: Oliver Hartkopp <socketcan@hartkopp.net>

> 

> commit fb8696ab14adadb2e3f6c17c18ed26b3ecd96691 upstream.

> 

> can_can_gw_rcv() is called under RCU protection, so after calling

> can_rx_unregister(), we have to call synchronize_rcu in order to wait

> for any RCU read-side critical sections to finish before removing the

> kmem_cache entry with the referenced gw job entry.

> 

> Link: https://lore.kernel.org/r/20210618173645.2238-1-socketcan@hartkopp.net

> Fixes: c1aabdf379bc ("can-gw: add netlink based CAN routing")

> Cc: linux-stable <stable@vger.kernel.org>

> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>

> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

> ---

>  net/can/gw.c | 3 +++

>  1 file changed, 3 insertions(+)


Both now queued up, thanks.

greg k-h
diff mbox series

Patch

diff --git a/net/can/gw.c b/net/can/gw.c
index 81650affa3fa..1867000f8a65 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -495,10 +495,11 @@  static int cgw_notifier(struct notifier_block *nb,
 		hlist_for_each_entry_safe(gwj, nx, &cgw_list, list) {
 
 			if (gwj->src.dev == dev || gwj->dst.dev == dev) {
 				hlist_del(&gwj->list);
 				cgw_unregister_filter(gwj);
+				synchronize_rcu();
 				kmem_cache_free(cgw_cache, gwj);
 			}
 		}
 	}
 
@@ -939,10 +940,11 @@  static void cgw_remove_all_jobs(void)
 	ASSERT_RTNL();
 
 	hlist_for_each_entry_safe(gwj, nx, &cgw_list, list) {
 		hlist_del(&gwj->list);
 		cgw_unregister_filter(gwj);
+		synchronize_rcu();
 		kmem_cache_free(cgw_cache, gwj);
 	}
 }
 
 static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh)
@@ -1006,10 +1008,11 @@  static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh)
 		if (memcmp(&gwj->ccgw, &ccgw, sizeof(ccgw)))
 			continue;
 
 		hlist_del(&gwj->list);
 		cgw_unregister_filter(gwj);
+		synchronize_rcu();
 		kmem_cache_free(cgw_cache, gwj);
 		err = 0;
 		break;
 	}