diff options
| author | Kuniyuki Iwashima <kuniyu@google.com> | 2026-06-12 09:32:06 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-15 21:49:28 +0300 |
| commit | 49374d87e839bdd88e6a5dcd866a4034713fb512 (patch) | |
| tree | 50b6fbdce60561f3004283ccb15dddd58a9468ee | |
| parent | c993bd0102aac43deea38f72fc1e909030b1c6ed (diff) | |
| download | linux-49374d87e839bdd88e6a5dcd866a4034713fb512.tar.xz | |
ipv4: fib: Free net->ipv4.{fib_table_hash,notifier_ops} without RTNL.
We will call ip_fib_net_exit() from ->exit_rtnl().
However, some paths will still access net->ipv4.fib_table_hash
after ->exit_rtnl().
For example, fib_flush() is called from fib_disable_ip() for
NETDEV_UNREGISTER.
Let's move kfree(net->ipv4.fib_table_hash) and fib4_notifier_exit()
from ip_fib_net_exit() to its caller.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260612063225.455191-4-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | net/ipv4/fib_frontend.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 3b1bd53c7357..c3e3b5633fd0 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -1615,9 +1615,6 @@ static void ip_fib_net_exit(struct net *net) #ifdef CONFIG_IP_MULTIPLE_TABLES fib4_rules_exit(net); #endif - - kfree(net->ipv4.fib_table_hash); - fib4_notifier_exit(net); } static int __net_init fib_net_init(struct net *net) @@ -1653,6 +1650,9 @@ out_semantics: rtnl_net_lock(net); ip_fib_net_exit(net); rtnl_net_unlock(net); + + kfree(net->ipv4.fib_table_hash); + fib4_notifier_exit(net); goto out; } @@ -1674,8 +1674,11 @@ static void __net_exit fib_net_exit_batch(struct list_head *net_list) } rtnl_unlock(); - list_for_each_entry(net, net_list, exit_list) + list_for_each_entry(net, net_list, exit_list) { + kfree(net->ipv4.fib_table_hash); + fib4_notifier_exit(net); fib4_semantics_exit(net); + } } static struct pernet_operations fib_net_ops = { |
