Commit e0b7e7dc authored by David S. Miller's avatar David S. Miller

Merge branch 'ipv6-fix-error-path-of-inet6_init'

Sabrina Dubroca says:

====================
ipv6: fix error path of inet6_init()

The error path of inet6_init() can trigger multiple kernel panics,
mostly due to wrong ordering of cleanups. This series fixes those
issues.
====================
Reviewed-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 85eb9af1 f707ef61
...@@ -324,6 +324,10 @@ void rtnl_unregister_all(int protocol) ...@@ -324,6 +324,10 @@ void rtnl_unregister_all(int protocol)
rtnl_lock(); rtnl_lock();
tab = rtnl_msg_handlers[protocol]; tab = rtnl_msg_handlers[protocol];
if (!tab) {
rtnl_unlock();
return;
}
RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL);
for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) { for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) {
link = tab[msgindex]; link = tab[msgindex];
......
...@@ -938,14 +938,14 @@ static int __init inet6_init(void) ...@@ -938,14 +938,14 @@ static int __init inet6_init(void)
err = proto_register(&pingv6_prot, 1); err = proto_register(&pingv6_prot, 1);
if (err) if (err)
goto out_unregister_ping_proto; goto out_unregister_raw_proto;
/* We MUST register RAW sockets before we create the ICMP6, /* We MUST register RAW sockets before we create the ICMP6,
* IGMP6, or NDISC control sockets. * IGMP6, or NDISC control sockets.
*/ */
err = rawv6_init(); err = rawv6_init();
if (err) if (err)
goto out_unregister_raw_proto; goto out_unregister_ping_proto;
/* Register the family here so that the init calls below will /* Register the family here so that the init calls below will
* be able to create sockets. (?? is this dangerous ??) * be able to create sockets. (?? is this dangerous ??)
...@@ -1113,11 +1113,11 @@ static int __init inet6_init(void) ...@@ -1113,11 +1113,11 @@ static int __init inet6_init(void)
igmp_fail: igmp_fail:
ndisc_cleanup(); ndisc_cleanup();
ndisc_fail: ndisc_fail:
ip6_mr_cleanup(); icmpv6_cleanup();
icmp_fail: icmp_fail:
unregister_pernet_subsys(&inet6_net_ops); ip6_mr_cleanup();
ipmr_fail: ipmr_fail:
icmpv6_cleanup(); unregister_pernet_subsys(&inet6_net_ops);
register_pernet_fail: register_pernet_fail:
sock_unregister(PF_INET6); sock_unregister(PF_INET6);
rtnl_unregister_all(PF_INET6); rtnl_unregister_all(PF_INET6);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment