tipc: NULL deref in tipc_net_finalize
From: Dmitry Vyukov
Date: Mon Dec 10 2018 - 10:34:14 EST
Hello,
The following program crashes upstream kernel on
40e020c129cfc991e8ab4736d2665351ffd1468d (Dec 9) with:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000001
PGD 0 P4D 0
Oops: 0000 [#1] SMP PTI
CPU: 1 PID: 45 Comm: kworker/1:1 Not tainted 4.20.0-rc6 #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
Workqueue: events tipc_net_finalize_work
RIP: 0010:rht_bucket_nested+0x31/0x90 lib/rhashtable.c:1190
Code: 89 f3 e8 32 84 ca ff 8b 4d 04 b8 01 00 00 00 48 8b 95 80 00 00
00 44 8b 65 00 d3 e0 83 e8 01 41 d3 ec 21 d8 d3 eb 48 8d 04 c2 <48> 8b
28 48 85 ed 75 22 eb 29 e8 00 84 ca ff 89 d8 41 c1 ec 09 c1
RSP: 0018:ffffb1bd8045fd68 EFLAGS: 00010246
RAX: 0000000000000001 RBX: 0000000000000000 RCX: 00000000ffff9f0e
RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9f0efa5433e0
RBP: ffff9f0efa5433e0 R08: 00000006c423ea71 R09: 0000000000000027
R10: ffffb1bd80377df8 R11: fefefefefefefeff R12: 000000000003e951
R13: ffffb1bd8045fdf0 R14: 0000000000000000 R15: ffff9f0efa5433e0
FS: 0000000000000000(0000) GS:ffff9f0efda80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000001 CR3: 0000000015e0a002 CR4: 0000000000160ee0
Call Trace:
rht_bucket include/linux/rhashtable.h:280 [inline]
__rhashtable_walk_find_next+0x1af/0x1e0 lib/rhashtable.c:801
rhashtable_walk_next+0x56/0xf0 lib/rhashtable.c:885
tipc_sk_reinit+0xaa/0x120 net/tipc/socket.c:2726
tipc_net_finalize.part.4+0x26/0x50 net/tipc/net.c:138
tipc_net_finalize net/tipc/net.c:134 [inline]
tipc_net_finalize_work+0x3f/0x50 net/tipc/net.c:148
process_one_work+0x290/0x540 kernel/workqueue.c:2153
worker_thread+0x39/0x500 kernel/workqueue.c:2296
kthread+0x12c/0x150 kernel/kthread.c:246
ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:352
Modules linked in:
CR2: 0000000000000001
---[ end trace 49f6dae32389e817 ]---
RIP: 0010:rht_bucket_nested+0x31/0x90 lib/rhashtable.c:1190
Code: 89 f3 e8 32 84 ca ff 8b 4d 04 b8 01 00 00 00 48 8b 95 80 00 00
00 44 8b 65 00 d3 e0 83 e8 01 41 d3 ec 21 d8 d3 eb 48 8d 04 c2 <48> 8b
28 48 85 ed 75 22 eb 29 e8 00 84 ca ff 89 d8 41 c1 ec 09 c1
RSP: 0018:ffffb1bd8045fd68 EFLAGS: 00010246
RAX: 0000000000000001 RBX: 0000000000000000 RCX: 00000000ffff9f0e
RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff9f0efa5433e0
RBP: ffff9f0efa5433e0 R08: 00000006c423ea71 R09: 0000000000000027
R10: ffffb1bd80377df8 R11: fefefefefefefeff R12: 000000000003e951
R13: ffffb1bd8045fdf0 R14: 0000000000000000 R15: ffff9f0efa5433e0
FS: 0000000000000000(0000) GS:ffff9f0efda80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000001 CR3: 0000000015e0a002 CR4: 0000000000160ee0
Kernel config (nothing special: mostly defconfig+enabled tipc):
https://gist.githubusercontent.com/dvyukov/b67e6428ecc170b090b9f65eec784e5a/raw/b77b0f3e86d702f868ab7511d04ca307180f3abc/gistfile1.txt
Reproducer program:
https://gist.github.com/dvyukov/9d9d9f2f87b05766323e3a97e07b5af8
There is a bunch of boilerplate to enable namespaces and net devices,
etc, but in a nutshell it basically does only TIPC_NL_BEARER_ENABLE:
r0 = socket$nl_generic(0x10, 0x3, 0x10)
r1 = syz_genetlink_get_family_id$tipc2(&(0x7f0000000000)='TIPCv2\x00')
sendmsg$TIPC_NL_BEARER_ENABLE(r0, &(0x7f0000000080)={0x0, 0x0,
&(0x7f00000000c0)={&(0x7f0000000100)={0x54, r1, 0x1, 0x123, 0x234, {},
[@TIPC_NLA_BEARER={0x40, 0x1, [@TIPC_NLA_BEARER_NAME={0x10, 0x1,
@udp='udp:syz0\x00'}, @TIPC_NLA_BEARER_UDP_OPTS={0x2c, 0x4, {{0x14,
0x1, @in={0x2, 0x4e20, @loopback}}, {0x14, 0x2, @in={0x2, 0x4e20,
@loopback}}}}]}]}, 0x54}}, 0x0)
This makes overall tipc testing a bit problematic as kernel always
crashes whenever syzkaller tries to do just anything with udp bearer,
so I would appreciate timely fix.
Thanks