]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ipv4: fib: Free net->ipv4.{fib_table_hash,notifier_ops} without RTNL.
authorKuniyuki Iwashima <kuniyu@google.com>
Fri, 12 Jun 2026 06:32:06 +0000 (06:32 +0000)
committerJakub Kicinski <kuba@kernel.org>
Mon, 15 Jun 2026 18:49:28 +0000 (11:49 -0700)
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>
net/ipv4/fib_frontend.c

index 3b1bd53c7357fe14b2e5cf161dd5063e84bdb82c..c3e3b5633fd0674ad35cb7cb3ef034c3a4030695 100644 (file)
@@ -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 = {