Merge branch 'tipc-syzbot-related-fixes'

Eric Dumazet says:

====================
tipc: syzbot related fixes

First patch fixes a recent syzbot report.

Second patch is inspired by numerous syzbot soft lockup
reports with RTNL pressure.
====================

Link: https://patch.msgid.link/20260623173030.2925059-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2026-06-25 08:53:02 -07:00
2 changed files with 16 additions and 7 deletions

View File

@@ -45,6 +45,7 @@
#include "crypto.h"
#include <linux/module.h>
#include <linux/wait_bit.h>
/* configurable TIPC parameters */
unsigned int tipc_net_id __read_mostly;
@@ -118,8 +119,7 @@ static void __net_exit tipc_exit_net(struct net *net)
#ifdef CONFIG_TIPC_CRYPTO
tipc_crypto_stop(&tipc_net(net)->crypto_tx);
#endif
while (atomic_read(&tn->wq_count))
cond_resched();
wait_var_event(&tn->wq_count, atomic_read(&tn->wq_count) == 0);
}
static void __net_exit tipc_pernet_pre_exit(struct net *net)

View File

@@ -40,6 +40,7 @@
#include <linux/igmp.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include <linux/wait_bit.h>
#include <linux/list.h>
#include <net/sock.h>
#include <net/ip.h>
@@ -803,6 +804,14 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
return err;
}
static void rcast_free_rcu(struct rcu_head *rcu)
{
struct udp_replicast *rcast = container_of(rcu, struct udp_replicast, rcu);
dst_cache_destroy(&rcast->dst_cache);
kfree(rcast);
}
/* cleanup_bearer - break the socket/bearer association */
static void cleanup_bearer(struct work_struct *work)
{
@@ -811,19 +820,19 @@ static void cleanup_bearer(struct work_struct *work)
struct tipc_net *tn;
list_for_each_entry_safe(rcast, tmp, &ub->rcast.list, list) {
dst_cache_destroy(&rcast->dst_cache);
list_del_rcu(&rcast->list);
kfree_rcu(rcast, rcu);
call_rcu_hurry(&rcast->rcu, rcast_free_rcu);
}
tn = tipc_net(sock_net(ub->sk));
dst_cache_destroy(&ub->rcast.dst_cache);
udp_tunnel_sock_release(ub->sk);
/* Note: could use a call_rcu() to avoid another synchronize_net() */
synchronize_net();
atomic_dec(&tn->wq_count);
dst_cache_destroy(&ub->rcast.dst_cache);
if (atomic_dec_and_test(&tn->wq_count))
wake_up_var(&tn->wq_count);
kfree(ub);
}