| From fb8696ab14adadb2e3f6c17c18ed26b3ecd96691 Mon Sep 17 00:00:00 2001 |
| From: Oliver Hartkopp <socketcan@hartkopp.net> |
| Date: Fri, 18 Jun 2021 19:36:45 +0200 |
| Subject: can: gw: synchronize rcu operations before removing gw job entry |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| net/can/gw.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/net/can/gw.c |
| +++ b/net/can/gw.c |
| @@ -534,6 +534,7 @@ static int cgw_notifier(struct notifier_ |
| if (gwj->src.dev == dev || gwj->dst.dev == dev) { |
| hlist_del(&gwj->list); |
| cgw_unregister_filter(net, gwj); |
| + synchronize_rcu(); |
| kmem_cache_free(cgw_cache, gwj); |
| } |
| } |
| @@ -1092,6 +1093,7 @@ static void cgw_remove_all_jobs(struct n |
| hlist_for_each_entry_safe(gwj, nx, &net->can.cgw_list, list) { |
| hlist_del(&gwj->list); |
| cgw_unregister_filter(net, gwj); |
| + synchronize_rcu(); |
| kmem_cache_free(cgw_cache, gwj); |
| } |
| } |
| @@ -1160,6 +1162,7 @@ static int cgw_remove_job(struct sk_buff |
| |
| hlist_del(&gwj->list); |
| cgw_unregister_filter(net, gwj); |
| + synchronize_rcu(); |
| kmem_cache_free(cgw_cache, gwj); |
| err = 0; |
| break; |