]>
Commit | Line | Data |
---|---|---|
a9fba688 SL |
1 | From 32122dd0a9645118f691c66702c45eb87e33403c Mon Sep 17 00:00:00 2001 |
2 | From: Jiri Slaby <jslaby@suse.cz> | |
3 | Date: Fri, 29 Mar 2019 12:19:46 +0100 | |
4 | Subject: kcm: switch order of device registration to fix a crash | |
5 | ||
6 | [ Upstream commit 3c446e6f96997f2a95bf0037ef463802162d2323 ] | |
7 | ||
8 | When kcm is loaded while many processes try to create a KCM socket, a | |
9 | crash occurs: | |
10 | BUG: unable to handle kernel NULL pointer dereference at 000000000000000e | |
11 | IP: mutex_lock+0x27/0x40 kernel/locking/mutex.c:240 | |
12 | PGD 8000000016ef2067 P4D 8000000016ef2067 PUD 3d6e9067 PMD 0 | |
13 | Oops: 0002 [#1] SMP KASAN PTI | |
14 | CPU: 0 PID: 7005 Comm: syz-executor.5 Not tainted 4.12.14-396-default #1 SLE15-SP1 (unreleased) | |
15 | RIP: 0010:mutex_lock+0x27/0x40 kernel/locking/mutex.c:240 | |
16 | RSP: 0018:ffff88000d487a00 EFLAGS: 00010246 | |
17 | RAX: 0000000000000000 RBX: 000000000000000e RCX: 1ffff100082b0719 | |
18 | ... | |
19 | CR2: 000000000000000e CR3: 000000004b1bc003 CR4: 0000000000060ef0 | |
20 | Call Trace: | |
21 | kcm_create+0x600/0xbf0 [kcm] | |
22 | __sock_create+0x324/0x750 net/socket.c:1272 | |
23 | ... | |
24 | ||
25 | This is due to race between sock_create and unfinished | |
26 | register_pernet_device. kcm_create tries to do "net_generic(net, | |
27 | kcm_net_id)". but kcm_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 mutiple processes doing socket(PF_KCM, ...) | |
32 | and one process doing module removal. | |
33 | ||
34 | Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module") | |
35 | Reviewed-by: Michal Kubecek <mkubecek@suse.cz> | |
36 | Signed-off-by: Jiri Slaby <jslaby@suse.cz> | |
37 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
38 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
39 | --- | |
40 | net/kcm/kcmsock.c | 16 ++++++++-------- | |
41 | 1 file changed, 8 insertions(+), 8 deletions(-) | |
42 | ||
43 | diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c | |
44 | index 571d824e4e24..b919db02c7f9 100644 | |
45 | --- a/net/kcm/kcmsock.c | |
46 | +++ b/net/kcm/kcmsock.c | |
47 | @@ -2054,14 +2054,14 @@ static int __init kcm_init(void) | |
48 | if (err) | |
49 | goto fail; | |
50 | ||
51 | - err = sock_register(&kcm_family_ops); | |
52 | - if (err) | |
53 | - goto sock_register_fail; | |
54 | - | |
55 | err = register_pernet_device(&kcm_net_ops); | |
56 | if (err) | |
57 | goto net_ops_fail; | |
58 | ||
59 | + err = sock_register(&kcm_family_ops); | |
60 | + if (err) | |
61 | + goto sock_register_fail; | |
62 | + | |
63 | err = kcm_proc_init(); | |
64 | if (err) | |
65 | goto proc_init_fail; | |
66 | @@ -2069,12 +2069,12 @@ static int __init kcm_init(void) | |
67 | return 0; | |
68 | ||
69 | proc_init_fail: | |
70 | - unregister_pernet_device(&kcm_net_ops); | |
71 | - | |
72 | -net_ops_fail: | |
73 | sock_unregister(PF_KCM); | |
74 | ||
75 | sock_register_fail: | |
76 | + unregister_pernet_device(&kcm_net_ops); | |
77 | + | |
78 | +net_ops_fail: | |
79 | proto_unregister(&kcm_proto); | |
80 | ||
81 | fail: | |
82 | @@ -2090,8 +2090,8 @@ static int __init kcm_init(void) | |
83 | static void __exit kcm_exit(void) | |
84 | { | |
85 | kcm_proc_exit(); | |
86 | - unregister_pernet_device(&kcm_net_ops); | |
87 | sock_unregister(PF_KCM); | |
88 | + unregister_pernet_device(&kcm_net_ops); | |
89 | proto_unregister(&kcm_proto); | |
90 | destroy_workqueue(kcm_wq); | |
91 | ||
92 | -- | |
93 | 2.19.1 | |
94 |