]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.4.5/ipv6-move-ipv6-proc-file-registration-to-end-of-init-order.patch
Linux 4.14.117
[thirdparty/kernel/stable-queue.git] / releases / 3.4.5 / ipv6-move-ipv6-proc-file-registration-to-end-of-init-order.patch
1 From 5413590847cdbd348b79c5d642fe782c0b9bcdc4 Mon Sep 17 00:00:00 2001
2 From: Thomas Graf <tgraf@suug.ch>
3 Date: Mon, 18 Jun 2012 12:08:33 +0000
4 Subject: ipv6: Move ipv6 proc file registration to end of init order
5
6
7 From: Thomas Graf <tgraf@suug.ch>
8
9 [ Upstream commit d189634ecab947c10f6f832258b103d0bbfe73cc ]
10
11 /proc/net/ipv6_route reflects the contents of fib_table_hash. The proc
12 handler is installed in ip6_route_net_init() whereas fib_table_hash is
13 allocated in fib6_net_init() _after_ the proc handler has been installed.
14
15 This opens up a short time frame to access fib_table_hash with its pants
16 down.
17
18 Move the registration of the proc files to a later point in the init
19 order to avoid the race.
20
21 Tested :-)
22
23 Signed-off-by: Thomas Graf <tgraf@suug.ch>
24 Signed-off-by: David S. Miller <davem@davemloft.net>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26 ---
27 net/ipv6/route.c | 41 +++++++++++++++++++++++++++++++----------
28 1 file changed, 31 insertions(+), 10 deletions(-)
29
30 --- a/net/ipv6/route.c
31 +++ b/net/ipv6/route.c
32 @@ -2953,10 +2953,6 @@ static int __net_init ip6_route_net_init
33 net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ;
34 net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
35
36 -#ifdef CONFIG_PROC_FS
37 - proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
38 - proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
39 -#endif
40 net->ipv6.ip6_rt_gc_expire = 30*HZ;
41
42 ret = 0;
43 @@ -2977,10 +2973,6 @@ out_ip6_dst_ops:
44
45 static void __net_exit ip6_route_net_exit(struct net *net)
46 {
47 -#ifdef CONFIG_PROC_FS
48 - proc_net_remove(net, "ipv6_route");
49 - proc_net_remove(net, "rt6_stats");
50 -#endif
51 kfree(net->ipv6.ip6_null_entry);
52 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
53 kfree(net->ipv6.ip6_prohibit_entry);
54 @@ -2989,11 +2981,33 @@ static void __net_exit ip6_route_net_exi
55 dst_entries_destroy(&net->ipv6.ip6_dst_ops);
56 }
57
58 +static int __net_init ip6_route_net_init_late(struct net *net)
59 +{
60 +#ifdef CONFIG_PROC_FS
61 + proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
62 + proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
63 +#endif
64 + return 0;
65 +}
66 +
67 +static void __net_exit ip6_route_net_exit_late(struct net *net)
68 +{
69 +#ifdef CONFIG_PROC_FS
70 + proc_net_remove(net, "ipv6_route");
71 + proc_net_remove(net, "rt6_stats");
72 +#endif
73 +}
74 +
75 static struct pernet_operations ip6_route_net_ops = {
76 .init = ip6_route_net_init,
77 .exit = ip6_route_net_exit,
78 };
79
80 +static struct pernet_operations ip6_route_net_late_ops = {
81 + .init = ip6_route_net_init_late,
82 + .exit = ip6_route_net_exit_late,
83 +};
84 +
85 static struct notifier_block ip6_route_dev_notifier = {
86 .notifier_call = ip6_route_dev_notify,
87 .priority = 0,
88 @@ -3043,19 +3057,25 @@ int __init ip6_route_init(void)
89 if (ret)
90 goto xfrm6_init;
91
92 + ret = register_pernet_subsys(&ip6_route_net_late_ops);
93 + if (ret)
94 + goto fib6_rules_init;
95 +
96 ret = -ENOBUFS;
97 if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) ||
98 __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) ||
99 __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL))
100 - goto fib6_rules_init;
101 + goto out_register_late_subsys;
102
103 ret = register_netdevice_notifier(&ip6_route_dev_notifier);
104 if (ret)
105 - goto fib6_rules_init;
106 + goto out_register_late_subsys;
107
108 out:
109 return ret;
110
111 +out_register_late_subsys:
112 + unregister_pernet_subsys(&ip6_route_net_late_ops);
113 fib6_rules_init:
114 fib6_rules_cleanup();
115 xfrm6_init:
116 @@ -3074,6 +3094,7 @@ out_kmem_cache:
117 void ip6_route_cleanup(void)
118 {
119 unregister_netdevice_notifier(&ip6_route_dev_notifier);
120 + unregister_pernet_subsys(&ip6_route_net_late_ops);
121 fib6_rules_cleanup();
122 xfrm6_fini();
123 fib6_gc_cleanup();