Skip to content

Commit 393c8b4

Browse files
Jiri Slabygregkh
Jiri Slaby
authored andcommitted
kcm: switch order of device registration to fix a crash
[ Upstream commit 3c446e6 ] When kcm is loaded while many processes try to create a KCM socket, a crash occurs: BUG: unable to handle kernel NULL pointer dereference at 000000000000000e IP: mutex_lock+0x27/0x40 kernel/locking/mutex.c:240 PGD 8000000016ef2067 P4D 8000000016ef2067 PUD 3d6e9067 PMD 0 Oops: 0002 [#1] SMP KASAN PTI CPU: 0 PID: 7005 Comm: syz-executor.5 Not tainted 4.12.14-396-default #1 SLE15-SP1 (unreleased) RIP: 0010:mutex_lock+0x27/0x40 kernel/locking/mutex.c:240 RSP: 0018:ffff88000d487a00 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 000000000000000e RCX: 1ffff100082b0719 ... CR2: 000000000000000e CR3: 000000004b1bc003 CR4: 0000000000060ef0 Call Trace: kcm_create+0x600/0xbf0 [kcm] __sock_create+0x324/0x750 net/socket.c:1272 ... This is due to race between sock_create and unfinished register_pernet_device. kcm_create tries to do "net_generic(net, kcm_net_id)". but kcm_net_id is not initialized yet. So switch the order of the two to close the race. This can be reproduced with mutiple processes doing socket(PF_KCM, ...) and one process doing module removal. Fixes: ab7ac4e ("kcm: Kernel Connection Multiplexor module") Reviewed-by: Michal Kubecek <[email protected]> Signed-off-by: Jiri Slaby <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b74c299 commit 393c8b4

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

net/kcm/kcmsock.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,27 +2059,27 @@ static int __init kcm_init(void)
20592059
if (err)
20602060
goto fail;
20612061

2062-
err = sock_register(&kcm_family_ops);
2063-
if (err)
2064-
goto sock_register_fail;
2065-
20662062
err = register_pernet_device(&kcm_net_ops);
20672063
if (err)
20682064
goto net_ops_fail;
20692065

2066+
err = sock_register(&kcm_family_ops);
2067+
if (err)
2068+
goto sock_register_fail;
2069+
20702070
err = kcm_proc_init();
20712071
if (err)
20722072
goto proc_init_fail;
20732073

20742074
return 0;
20752075

20762076
proc_init_fail:
2077-
unregister_pernet_device(&kcm_net_ops);
2078-
2079-
net_ops_fail:
20802077
sock_unregister(PF_KCM);
20812078

20822079
sock_register_fail:
2080+
unregister_pernet_device(&kcm_net_ops);
2081+
2082+
net_ops_fail:
20832083
proto_unregister(&kcm_proto);
20842084

20852085
fail:
@@ -2095,8 +2095,8 @@ static int __init kcm_init(void)
20952095
static void __exit kcm_exit(void)
20962096
{
20972097
kcm_proc_exit();
2098-
unregister_pernet_device(&kcm_net_ops);
20992098
sock_unregister(PF_KCM);
2099+
unregister_pernet_device(&kcm_net_ops);
21002100
proto_unregister(&kcm_proto);
21012101
destroy_workqueue(kcm_wq);
21022102

0 commit comments

Comments
 (0)