]>
Commit | Line | Data |
---|---|---|
b12f0636 GKH |
1 | From foo@baz Wed 22 May 2019 08:35:12 AM CEST |
2 | From: Junwei Hu <hujunwei4@huawei.com> | |
3 | Date: Thu, 16 May 2019 10:51:15 +0800 | |
4 | Subject: tipc: switch order of device registration to fix a crash | |
5 | ||
6 | From: Junwei Hu <hujunwei4@huawei.com> | |
7 | ||
8 | [ Upstream commit 7e27e8d6130c5e88fac9ddec4249f7f2337fe7f8 ] | |
9 | ||
10 | When tipc is loaded while many processes try to create a TIPC socket, | |
11 | a crash occurs: | |
12 | PANIC: Unable to handle kernel paging request at virtual | |
13 | address "dfff20000000021d" | |
14 | pc : tipc_sk_create+0x374/0x1180 [tipc] | |
15 | lr : tipc_sk_create+0x374/0x1180 [tipc] | |
16 | Exception class = DABT (current EL), IL = 32 bits | |
17 | Call trace: | |
18 | tipc_sk_create+0x374/0x1180 [tipc] | |
19 | __sock_create+0x1cc/0x408 | |
20 | __sys_socket+0xec/0x1f0 | |
21 | __arm64_sys_socket+0x74/0xa8 | |
22 | ... | |
23 | ||
24 | This is due to race between sock_create and unfinished | |
25 | register_pernet_device. tipc_sk_insert tries to do | |
26 | "net_generic(net, tipc_net_id)". | |
27 | but tipc_net_id is not initialized yet. | |
28 | ||
29 | So switch the order of the two to close the race. | |
30 | ||
31 | This can be reproduced with multiple processes doing socket(AF_TIPC, ...) | |
32 | and one process doing module removal. | |
33 | ||
34 | Fixes: a62fbccecd62 ("tipc: make subscriber server support net namespace") | |
35 | Signed-off-by: Junwei Hu <hujunwei4@huawei.com> | |
36 | Reported-by: Wang Wang <wangwang2@huawei.com> | |
37 | Reviewed-by: Xiaogang Wang <wangxiaogang3@huawei.com> | |
38 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
39 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
40 | --- | |
41 | net/tipc/core.c | 14 +++++++------- | |
42 | 1 file changed, 7 insertions(+), 7 deletions(-) | |
43 | ||
44 | --- a/net/tipc/core.c | |
45 | +++ b/net/tipc/core.c | |
46 | @@ -129,10 +129,6 @@ static int __init tipc_init(void) | |
47 | if (err) | |
48 | goto out_netlink_compat; | |
49 | ||
50 | - err = tipc_socket_init(); | |
51 | - if (err) | |
52 | - goto out_socket; | |
53 | - | |
54 | err = tipc_register_sysctl(); | |
55 | if (err) | |
56 | goto out_sysctl; | |
57 | @@ -141,6 +137,10 @@ static int __init tipc_init(void) | |
58 | if (err) | |
59 | goto out_pernet; | |
60 | ||
61 | + err = tipc_socket_init(); | |
62 | + if (err) | |
63 | + goto out_socket; | |
64 | + | |
65 | err = tipc_bearer_setup(); | |
66 | if (err) | |
67 | goto out_bearer; | |
68 | @@ -148,12 +148,12 @@ static int __init tipc_init(void) | |
69 | pr_info("Started in single node mode\n"); | |
70 | return 0; | |
71 | out_bearer: | |
72 | + tipc_socket_stop(); | |
73 | +out_socket: | |
74 | unregister_pernet_subsys(&tipc_net_ops); | |
75 | out_pernet: | |
76 | tipc_unregister_sysctl(); | |
77 | out_sysctl: | |
78 | - tipc_socket_stop(); | |
79 | -out_socket: | |
80 | tipc_netlink_compat_stop(); | |
81 | out_netlink_compat: | |
82 | tipc_netlink_stop(); | |
83 | @@ -165,10 +165,10 @@ out_netlink: | |
84 | static void __exit tipc_exit(void) | |
85 | { | |
86 | tipc_bearer_cleanup(); | |
87 | + tipc_socket_stop(); | |
88 | unregister_pernet_subsys(&tipc_net_ops); | |
89 | tipc_netlink_stop(); | |
90 | tipc_netlink_compat_stop(); | |
91 | - tipc_socket_stop(); | |
92 | tipc_unregister_sysctl(); | |
93 | ||
94 | pr_info("Deactivated\n"); |