ip_vs_dest_trash_expire() accesses the per-network-namespace IPVS state
and rearms the destination trash timer while entries remain. The
cleanup path uses timer_delete_sync(), which waits for a running callback
but still allows a racing callback to rearm the timer.
Use timer_shutdown_sync() when the per-network-namespace destination
trash is finally cleaned up. This prevents the callback from being
queued again before the IPVS state is released.
Fixes: f2431e6e9255 ("IPVS: netns, trash handling")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Runyu Xiao <redacted>
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 4c1c73944..0eb6cdb5f 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1192,7 +1192,7 @@ static void ip_vs_trash_cleanup(struct netns_ipvs *ipvs)
{
struct ip_vs_dest *dest, *nxt;
- timer_delete_sync(&ipvs->dest_trash_timer);
+ timer_shutdown_sync(&ipvs->dest_trash_timer);
/* No need to use dest_trash_lock */
list_for_each_entry_safe(dest, nxt, &ipvs->dest_trash, t_list) {
list_del(&dest->t_list);--
2.34.1