net: move fib_rules_unregister() under rtnl lock
authorWANG Cong <xiyou.wangcong@gmail.com>
Tue, 31 Mar 2015 18:01:46 +0000 (11:01 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 3 Apr 2015 00:52:34 +0000 (20:52 -0400)
We have to hold rtnl lock for fib_rules_unregister()
otherwise the following race could happen:

fib_rules_unregister(): fib_nl_delrule():
... ...
... ops = lookup_rules_ops();
list_del_rcu(&ops->list);
list_for_each_entry(ops->rules) {
fib_rules_cleanup_ops(ops);   ...
  list_del_rcu();   list_del_rcu();
}

Note, net->rules_mod_lock is actually not needed at all,
either upper layer netns code or rtnl lock guarantees
we are safe.

Cc: Alexander Duyck <alexander.h.duyck@redhat.com>
Cc: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/fib_rules.c
net/decnet/dn_rules.c
net/ipv4/fib_frontend.c
net/ipv4/ipmr.c
net/ipv6/fib6_rules.c
net/ipv6/ip6mr.c

index 44706e8..e4fdc9d 100644 (file)
@@ -175,9 +175,9 @@ void fib_rules_unregister(struct fib_rules_ops *ops)
 
        spin_lock(&net->rules_mod_lock);
        list_del_rcu(&ops->list);
-       fib_rules_cleanup_ops(ops);
        spin_unlock(&net->rules_mod_lock);
 
+       fib_rules_cleanup_ops(ops);
        call_rcu(&ops->rcu, fib_rules_put_rcu);
 }
 EXPORT_SYMBOL_GPL(fib_rules_unregister);
index faf7cc3..9d66a0f 100644 (file)
@@ -248,7 +248,9 @@ void __init dn_fib_rules_init(void)
 
 void __exit dn_fib_rules_cleanup(void)
 {
+       rtnl_lock();
        fib_rules_unregister(dn_fib_rules_ops);
+       rtnl_unlock();
        rcu_barrier();
 }
 
Simple merge
diff --cc net/ipv4/ipmr.c
Simple merge
Simple merge
Simple merge