From 292a089d78d3e2f7944e60bb897c977785a321e3 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Tue, 20 Dec 2022 13:45:19 -0500 Subject: treewide: Convert del_timer*() to timer_shutdown*() Due to several bugs caused by timers being re-armed after they are shutdown and just before they are freed, a new state of timers was added called "shutdown". After a timer is set to this state, then it can no longer be re-armed. The following script was run to find all the trivial locations where del_timer() or del_timer_sync() is called in the same function that the object holding the timer is freed. It also ignores any locations where the timer->function is modified between the del_timer*() and the free(), as that is not considered a "trivial" case. This was created by using a coccinelle script and the following commands: $ cat timer.cocci @@ expression ptr, slab; identifier timer, rfield; @@ ( - del_timer(&ptr->timer); + timer_shutdown(&ptr->timer); | - del_timer_sync(&ptr->timer); + timer_shutdown_sync(&ptr->timer); ) ... when strict when != ptr->timer ( kfree_rcu(ptr, rfield); | kmem_cache_free(slab, ptr); | kfree(ptr); ) $ spatch timer.cocci . > /tmp/t.patch $ patch -p1 < /tmp/t.patch Link: https://lore.kernel.org/lkml/20221123201306.823305113@linutronix.de/ Signed-off-by: Steven Rostedt (Google) Acked-by: Pavel Machek [ LED ] Acked-by: Kalle Valo [ wireless ] Acked-by: Paolo Abeni [ networking ] Signed-off-by: Linus Torvalds --- net/802/garp.c | 2 +- net/802/mrp.c | 4 ++-- net/bridge/br_multicast.c | 8 ++++---- net/bridge/br_multicast_eht.c | 4 ++-- net/core/gen_estimator.c | 2 +- net/ipv4/ipmr.c | 2 +- net/ipv6/ip6mr.c | 2 +- net/mac80211/mesh_pathtbl.c | 2 +- net/netfilter/ipset/ip_set_list_set.c | 2 +- net/netfilter/ipvs/ip_vs_lblc.c | 2 +- net/netfilter/ipvs/ip_vs_lblcr.c | 2 +- net/netfilter/xt_IDLETIMER.c | 4 ++-- net/netfilter/xt_LED.c | 2 +- net/sched/cls_flow.c | 2 +- net/sunrpc/svc.c | 2 +- net/tipc/discover.c | 2 +- net/tipc/monitor.c | 2 +- 17 files changed, 23 insertions(+), 23 deletions(-) (limited to 'net') diff --git a/net/802/garp.c b/net/802/garp.c index 77aac2763835..ab24b21fbb49 100644 --- a/net/802/garp.c +++ b/net/802/garp.c @@ -618,7 +618,7 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl /* Delete timer and generate a final TRANSMIT_PDU event to flush out * all pending messages before the applicant is gone. */ - del_timer_sync(&app->join_timer); + timer_shutdown_sync(&app->join_timer); spin_lock_bh(&app->lock); garp_gid_event(app, GARP_EVENT_TRANSMIT_PDU); diff --git a/net/802/mrp.c b/net/802/mrp.c index 66fcbf23b486..eafc21ecc287 100644 --- a/net/802/mrp.c +++ b/net/802/mrp.c @@ -911,8 +911,8 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl) /* Delete timer and generate a final TX event to flush out * all pending messages before the applicant is gone. */ - del_timer_sync(&app->join_timer); - del_timer_sync(&app->periodic_timer); + timer_shutdown_sync(&app->join_timer); + timer_shutdown_sync(&app->periodic_timer); spin_lock_bh(&app->lock); mrp_mad_event(app, MRP_EVENT_TX); diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 48170bd3785e..dea1ee1bd095 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -606,7 +606,7 @@ static void br_multicast_destroy_mdb_entry(struct net_bridge_mcast_gc *gc) WARN_ON(!hlist_unhashed(&mp->mdb_node)); WARN_ON(mp->ports); - del_timer_sync(&mp->timer); + timer_shutdown_sync(&mp->timer); kfree_rcu(mp, rcu); } @@ -647,7 +647,7 @@ static void br_multicast_destroy_group_src(struct net_bridge_mcast_gc *gc) src = container_of(gc, struct net_bridge_group_src, mcast_gc); WARN_ON(!hlist_unhashed(&src->node)); - del_timer_sync(&src->timer); + timer_shutdown_sync(&src->timer); kfree_rcu(src, rcu); } @@ -676,8 +676,8 @@ static void br_multicast_destroy_port_group(struct net_bridge_mcast_gc *gc) WARN_ON(!hlist_unhashed(&pg->mglist)); WARN_ON(!hlist_empty(&pg->src_list)); - del_timer_sync(&pg->rexmit_timer); - del_timer_sync(&pg->timer); + timer_shutdown_sync(&pg->rexmit_timer); + timer_shutdown_sync(&pg->timer); kfree_rcu(pg, rcu); } diff --git a/net/bridge/br_multicast_eht.c b/net/bridge/br_multicast_eht.c index f91c071d1608..c126aa4e7551 100644 --- a/net/bridge/br_multicast_eht.c +++ b/net/bridge/br_multicast_eht.c @@ -142,7 +142,7 @@ static void br_multicast_destroy_eht_set_entry(struct net_bridge_mcast_gc *gc) set_h = container_of(gc, struct net_bridge_group_eht_set_entry, mcast_gc); WARN_ON(!RB_EMPTY_NODE(&set_h->rb_node)); - del_timer_sync(&set_h->timer); + timer_shutdown_sync(&set_h->timer); kfree(set_h); } @@ -154,7 +154,7 @@ static void br_multicast_destroy_eht_set(struct net_bridge_mcast_gc *gc) WARN_ON(!RB_EMPTY_NODE(&eht_set->rb_node)); WARN_ON(!RB_EMPTY_ROOT(&eht_set->entry_tree)); - del_timer_sync(&eht_set->timer); + timer_shutdown_sync(&eht_set->timer); kfree(eht_set); } diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 4fcbdd71c59f..fae9c4694186 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -208,7 +208,7 @@ void gen_kill_estimator(struct net_rate_estimator __rcu **rate_est) est = xchg((__force struct net_rate_estimator **)rate_est, NULL); if (est) { - del_timer_sync(&est->timer); + timer_shutdown_sync(&est->timer); kfree_rcu(est, rcu); } } diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index b58df3c1bf7d..eec1f6df80d8 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -412,7 +412,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id) static void ipmr_free_table(struct mr_table *mrt) { - del_timer_sync(&mrt->ipmr_expire_timer); + timer_shutdown_sync(&mrt->ipmr_expire_timer); mroute_clean_tables(mrt, MRT_FLUSH_VIFS | MRT_FLUSH_VIFS_STATIC | MRT_FLUSH_MFC | MRT_FLUSH_MFC_STATIC); rhltable_destroy(&mrt->mfc_hash); diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 23e766597f36..51cf37abd142 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -392,7 +392,7 @@ static struct mr_table *ip6mr_new_table(struct net *net, u32 id) static void ip6mr_free_table(struct mr_table *mrt) { - del_timer_sync(&mrt->ipmr_expire_timer); + timer_shutdown_sync(&mrt->ipmr_expire_timer); mroute_clean_tables(mrt, MRT6_FLUSH_MIFS | MRT6_FLUSH_MIFS_STATIC | MRT6_FLUSH_MFC | MRT6_FLUSH_MFC_STATIC); rhltable_destroy(&mrt->mfc_hash); diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 69d5e1ec6ede..3b81e6df3f34 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -512,7 +512,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl, mpath->flags |= MESH_PATH_RESOLVING | MESH_PATH_DELETED; mesh_gate_del(tbl, mpath); spin_unlock_bh(&mpath->state_lock); - del_timer_sync(&mpath->timer); + timer_shutdown_sync(&mpath->timer); atomic_dec(&sdata->u.mesh.mpaths); atomic_dec(&tbl->entries); mesh_path_flush_pending(mpath); diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 5a67f7966574..e162636525cf 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c @@ -427,7 +427,7 @@ list_set_destroy(struct ip_set *set) struct set_elem *e, *n; if (SET_WITH_TIMEOUT(set)) - del_timer_sync(&map->gc); + timer_shutdown_sync(&map->gc); list_for_each_entry_safe(e, n, &map->members, list) { list_del(&e->list); diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c index 7ac7473e3804..1b87214d385e 100644 --- a/net/netfilter/ipvs/ip_vs_lblc.c +++ b/net/netfilter/ipvs/ip_vs_lblc.c @@ -384,7 +384,7 @@ static void ip_vs_lblc_done_svc(struct ip_vs_service *svc) struct ip_vs_lblc_table *tbl = svc->sched_data; /* remove periodic timer */ - del_timer_sync(&tbl->periodic_timer); + timer_shutdown_sync(&tbl->periodic_timer); /* got to clean up table entries here */ ip_vs_lblc_flush(svc); diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c index 77c323c36a88..ad8f5fea6d3a 100644 --- a/net/netfilter/ipvs/ip_vs_lblcr.c +++ b/net/netfilter/ipvs/ip_vs_lblcr.c @@ -547,7 +547,7 @@ static void ip_vs_lblcr_done_svc(struct ip_vs_service *svc) struct ip_vs_lblcr_table *tbl = svc->sched_data; /* remove periodic timer */ - del_timer_sync(&tbl->periodic_timer); + timer_shutdown_sync(&tbl->periodic_timer); /* got to clean up table entries here */ ip_vs_lblcr_flush(svc); diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index 0f8bb0bf558f..8d36303f3935 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -413,7 +413,7 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par) pr_debug("deleting timer %s\n", info->label); list_del(&info->timer->entry); - del_timer_sync(&info->timer->timer); + timer_shutdown_sync(&info->timer->timer); cancel_work_sync(&info->timer->work); sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr); kfree(info->timer->attr.attr.name); @@ -441,7 +441,7 @@ static void idletimer_tg_destroy_v1(const struct xt_tgdtor_param *par) if (info->timer->timer_type & XT_IDLETIMER_ALARM) { alarm_cancel(&info->timer->alarm); } else { - del_timer_sync(&info->timer->timer); + timer_shutdown_sync(&info->timer->timer); } cancel_work_sync(&info->timer->work); sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr); diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c index 0371c387b0d1..66b0f941d8fb 100644 --- a/net/netfilter/xt_LED.c +++ b/net/netfilter/xt_LED.c @@ -166,7 +166,7 @@ static void led_tg_destroy(const struct xt_tgdtor_param *par) list_del(&ledinternal->list); - del_timer_sync(&ledinternal->timer); + timer_shutdown_sync(&ledinternal->timer); led_trigger_unregister(&ledinternal->netfilter_led_trigger); diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 535668e1f748..6ab317b48d6c 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -369,7 +369,7 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = { static void __flow_destroy_filter(struct flow_filter *f) { - del_timer_sync(&f->perturb_timer); + timer_shutdown_sync(&f->perturb_timer); tcf_exts_destroy(&f->exts); tcf_em_tree_destroy(&f->ematches); tcf_exts_put_net(&f->exts); diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 8f1b596db33f..85f0c3cfc877 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -567,7 +567,7 @@ svc_destroy(struct kref *ref) struct svc_serv *serv = container_of(ref, struct svc_serv, sv_refcnt); dprintk("svc: svc_destroy(%s)\n", serv->sv_program->pg_name); - del_timer_sync(&serv->sv_temptimer); + timer_shutdown_sync(&serv->sv_temptimer); /* * The last user is gone and thus all sockets have to be destroyed to diff --git a/net/tipc/discover.c b/net/tipc/discover.c index e8dcdf267c0c..685389d4b245 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -388,7 +388,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer *b, */ void tipc_disc_delete(struct tipc_discoverer *d) { - del_timer_sync(&d->timer); + timer_shutdown_sync(&d->timer); kfree_skb(d->skb); kfree(d); } diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 9618e4429f0f..77a3d016cade 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c @@ -700,7 +700,7 @@ void tipc_mon_delete(struct net *net, int bearer_id) } mon->self = NULL; write_unlock_bh(&mon->lock); - del_timer_sync(&mon->timer); + timer_shutdown_sync(&mon->timer); kfree(self->domain); kfree(self); kfree(mon); -- cgit v1.2.3