aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJunwei Hu <hujunwei4@huawei.com>2019-05-15 22:51:15 -0400
committerDavid S. Miller <davem@davemloft.net>2019-05-16 15:25:02 -0400
commit7e27e8d6130c5e88fac9ddec4249f7f2337fe7f8 (patch)
tree79a25be33c426c2ee802da089de94365cd5fde60 /net/tipc
parent61fb0d01680771f72cc9d39783fb2c122aaad51e (diff)
tipc: switch order of device registration to fix a crash
When tipc is loaded while many processes try to create a TIPC socket, a crash occurs: PANIC: Unable to handle kernel paging request at virtual address "dfff20000000021d" pc : tipc_sk_create+0x374/0x1180 [tipc] lr : tipc_sk_create+0x374/0x1180 [tipc] Exception class = DABT (current EL), IL = 32 bits Call trace: tipc_sk_create+0x374/0x1180 [tipc] __sock_create+0x1cc/0x408 __sys_socket+0xec/0x1f0 __arm64_sys_socket+0x74/0xa8 ... This is due to race between sock_create and unfinished register_pernet_device. tipc_sk_insert tries to do "net_generic(net, tipc_net_id)". but tipc_net_id is not initialized yet. So switch the order of the two to close the race. This can be reproduced with multiple processes doing socket(AF_TIPC, ...) and one process doing module removal. Fixes: a62fbccecd62 ("tipc: make subscriber server support net namespace") Signed-off-by: Junwei Hu <hujunwei4@huawei.com> Reported-by: Wang Wang <wangwang2@huawei.com> Reviewed-by: Xiaogang Wang <wangxiaogang3@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/core.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 27cccd101ef6..ddd2e0f67c07 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -131,10 +131,6 @@ static int __init tipc_init(void)
131 if (err) 131 if (err)
132 goto out_netlink_compat; 132 goto out_netlink_compat;
133 133
134 err = tipc_socket_init();
135 if (err)
136 goto out_socket;
137
138 err = tipc_register_sysctl(); 134 err = tipc_register_sysctl();
139 if (err) 135 if (err)
140 goto out_sysctl; 136 goto out_sysctl;
@@ -143,6 +139,10 @@ static int __init tipc_init(void)
143 if (err) 139 if (err)
144 goto out_pernet; 140 goto out_pernet;
145 141
142 err = tipc_socket_init();
143 if (err)
144 goto out_socket;
145
146 err = tipc_bearer_setup(); 146 err = tipc_bearer_setup();
147 if (err) 147 if (err)
148 goto out_bearer; 148 goto out_bearer;
@@ -150,12 +150,12 @@ static int __init tipc_init(void)
150 pr_info("Started in single node mode\n"); 150 pr_info("Started in single node mode\n");
151 return 0; 151 return 0;
152out_bearer: 152out_bearer:
153 tipc_socket_stop();
154out_socket:
153 unregister_pernet_subsys(&tipc_net_ops); 155 unregister_pernet_subsys(&tipc_net_ops);
154out_pernet: 156out_pernet:
155 tipc_unregister_sysctl(); 157 tipc_unregister_sysctl();
156out_sysctl: 158out_sysctl:
157 tipc_socket_stop();
158out_socket:
159 tipc_netlink_compat_stop(); 159 tipc_netlink_compat_stop();
160out_netlink_compat: 160out_netlink_compat:
161 tipc_netlink_stop(); 161 tipc_netlink_stop();
@@ -167,10 +167,10 @@ out_netlink:
167static void __exit tipc_exit(void) 167static void __exit tipc_exit(void)
168{ 168{
169 tipc_bearer_cleanup(); 169 tipc_bearer_cleanup();
170 tipc_socket_stop();
170 unregister_pernet_subsys(&tipc_net_ops); 171 unregister_pernet_subsys(&tipc_net_ops);
171 tipc_netlink_stop(); 172 tipc_netlink_stop();
172 tipc_netlink_compat_stop(); 173 tipc_netlink_compat_stop();
173 tipc_socket_stop();
174 tipc_unregister_sysctl(); 174 tipc_unregister_sysctl();
175 175
176 pr_info("Deactivated\n"); 176 pr_info("Deactivated\n");