diff options
author | David S. Miller <davem@davemloft.net> | 2018-08-29 22:28:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-29 22:28:55 -0400 |
commit | e0b7e7dc690183c79f772844cdc03a144d72a3e0 (patch) | |
tree | 45c00ac0e6e8a7daaf4f47761d6f6f355271d815 | |
parent | 85eb9af182243ce9a8b72410d5321c440ac5f8d7 (diff) | |
parent | f707ef61e17261f2bb18c3e4871c6f135ab3aba9 (diff) |
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: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/rtnetlink.c | 4 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 10 |
2 files changed, 9 insertions, 5 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 24431e578310..60c928894a78 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -324,6 +324,10 @@ void rtnl_unregister_all(int protocol) | |||
324 | 324 | ||
325 | rtnl_lock(); | 325 | rtnl_lock(); |
326 | tab = rtnl_msg_handlers[protocol]; | 326 | tab = rtnl_msg_handlers[protocol]; |
327 | if (!tab) { | ||
328 | rtnl_unlock(); | ||
329 | return; | ||
330 | } | ||
327 | RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); | 331 | RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL); |
328 | for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) { | 332 | for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) { |
329 | link = tab[msgindex]; | 333 | link = tab[msgindex]; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 673bba31eb18..9a4261e50272 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -938,14 +938,14 @@ static int __init inet6_init(void) | |||
938 | 938 | ||
939 | err = proto_register(&pingv6_prot, 1); | 939 | err = proto_register(&pingv6_prot, 1); |
940 | if (err) | 940 | if (err) |
941 | goto out_unregister_ping_proto; | 941 | goto out_unregister_raw_proto; |
942 | 942 | ||
943 | /* We MUST register RAW sockets before we create the ICMP6, | 943 | /* We MUST register RAW sockets before we create the ICMP6, |
944 | * IGMP6, or NDISC control sockets. | 944 | * IGMP6, or NDISC control sockets. |
945 | */ | 945 | */ |
946 | err = rawv6_init(); | 946 | err = rawv6_init(); |
947 | if (err) | 947 | if (err) |
948 | goto out_unregister_raw_proto; | 948 | goto out_unregister_ping_proto; |
949 | 949 | ||
950 | /* Register the family here so that the init calls below will | 950 | /* Register the family here so that the init calls below will |
951 | * be able to create sockets. (?? is this dangerous ??) | 951 | * be able to create sockets. (?? is this dangerous ??) |
@@ -1113,11 +1113,11 @@ netfilter_fail: | |||
1113 | igmp_fail: | 1113 | igmp_fail: |
1114 | ndisc_cleanup(); | 1114 | ndisc_cleanup(); |
1115 | ndisc_fail: | 1115 | ndisc_fail: |
1116 | ip6_mr_cleanup(); | 1116 | icmpv6_cleanup(); |
1117 | icmp_fail: | 1117 | icmp_fail: |
1118 | unregister_pernet_subsys(&inet6_net_ops); | 1118 | ip6_mr_cleanup(); |
1119 | ipmr_fail: | 1119 | ipmr_fail: |
1120 | icmpv6_cleanup(); | 1120 | unregister_pernet_subsys(&inet6_net_ops); |
1121 | register_pernet_fail: | 1121 | register_pernet_fail: |
1122 | sock_unregister(PF_INET6); | 1122 | sock_unregister(PF_INET6); |
1123 | rtnl_unregister_all(PF_INET6); | 1123 | rtnl_unregister_all(PF_INET6); |