net/ipv4: trying to register non-static key in ip_mc_clear_src

From: Andrey Konovalov
Date: Tue Jun 20 2017 - 11:14:57 EST


Hi,

I've got the following error report while fuzzing the kernel with syzkaller.

On commit 9705596d08ac87c18aee32cc97f2783b7d14624e (4.12-rc6+).

A reproducer and .config are attached.

INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
CPU: 1 PID: 4099 Comm: a.out Not tainted 4.12.0-rc6+ #9
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:16
dump_stack+0x292/0x395 lib/dump_stack.c:52
register_lock_class+0x717/0x1aa0 kernel/locking/lockdep.c:755
? 0xffffffffa0000000
__lock_acquire+0x269/0x3690 kernel/locking/lockdep.c:3255
lock_acquire+0x22d/0x560 kernel/locking/lockdep.c:3855
__raw_spin_lock_bh ./include/linux/spinlock_api_smp.h:135
_raw_spin_lock_bh+0x36/0x50 kernel/locking/spinlock.c:175
spin_lock_bh ./include/linux/spinlock.h:304
ip_mc_clear_src+0x27/0x1e0 net/ipv4/igmp.c:2076
igmpv3_clear_delrec+0xee/0x4f0 net/ipv4/igmp.c:1194
ip_mc_destroy_dev+0x4e/0x190 net/ipv4/igmp.c:1736
inetdev_destroy net/ipv4/devinet.c:294
inetdev_event+0x5f5/0x1260 net/ipv4/devinet.c:1487
notifier_call_chain+0x14a/0x2e0 kernel/notifier.c:93
__raw_notifier_call_chain kernel/notifier.c:394
raw_notifier_call_chain+0x32/0x40 kernel/notifier.c:401
call_netdevice_notifiers_info+0x56/0x90 net/core/dev.c:1650
call_netdevice_notifiers net/core/dev.c:1666
dev_set_mtu+0x3be/0x5e0 net/core/dev.c:6733
dev_ifsioc+0x798/0x9f0 net/core/dev_ioctl.c:261
dev_ioctl+0x24e/0x1160 net/core/dev_ioctl.c:532
sock_do_ioctl+0x99/0xb0 net/socket.c:913
sock_ioctl+0x294/0x440 net/socket.c:1004
vfs_ioctl fs/ioctl.c:45
do_vfs_ioctl+0x1c4/0x1660 fs/ioctl.c:685
SYSC_ioctl fs/ioctl.c:700
SyS_ioctl+0x94/0xc0 fs/ioctl.c:691
entry_SYSCALL_64_fastpath+0x1f/0xbe arch/x86/entry/entry_64.S:203
RIP: 0033:0x7efe2c1a4b79
RSP: 002b:00007ffe2305a218 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007ffe2305a320 RCX: 00007efe2c1a4b79
RDX: 0000000020dc4000 RSI: 0000000000008922 RDI: 0000000000000005
RBP: 00000000004004e0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ffe2305a320 R14: 0000000000000000 R15: 0000000000000000
qemu: terminating on signal 15 from pid 174244

Attachment: .config
Description: Binary data

// autogenerated by syzkaller (http://github.com/google/syzkaller)

#ifndef __NR_mmap
#define __NR_mmap 9
#endif
#ifndef __NR_socket
#define __NR_socket 41
#endif
#ifndef __NR_ioctl
#define __NR_ioctl 16
#endif
#ifndef __NR_setsockopt
#define __NR_setsockopt 54
#endif

#define _GNU_SOURCE

#include <stdint.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>

long r[22];
void loop()
{
memset(r, -1, sizeof(r));
r[0] = syscall(__NR_mmap, 0x20000000ul, 0xfff000ul, 0x3ul, 0x32ul,
0xfffffffffffffffful, 0x0ul);
r[1] = syscall(__NR_socket, 0x2ul, 0x806ul, 0x0ul);
memcpy((void*)0x2000d000,
"\x6c\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00",
16);
*(uint16_t*)0x2000d010 = (uint16_t)0xfffffffffffffffd;
r[4] = syscall(__NR_ioctl, r[1], 0x8914ul, 0x2000d000ul);
r[5] = syscall(__NR_socket, 0x2ul, 0x1ul, 0x0ul);
*(uint32_t*)0x20000000 = (uint32_t)0x20000e0;
*(uint32_t*)0x20000004 = (uint32_t)0x100007f;
*(uint32_t*)0x20000008 = (uint32_t)0x0;
r[9] = syscall(__NR_setsockopt, r[5], 0x0ul, 0x27ul, 0x20000000ul,
0xcul);
r[10] = syscall(__NR_socket, 0x2ul, 0x806ul, 0x0ul);
memcpy((void*)0x208a3fe0,
"\x6c\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00",
16);
*(uint16_t*)0x208a3ff0 = (uint16_t)0x0;
r[13] = syscall(__NR_ioctl, r[10], 0x8914ul, 0x208a3fe0ul);
memcpy((void*)0x20dc4000,
"\x6c\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00",
16);
*(uint64_t*)0x20dc4010 = (uint64_t)0x4;
*(uint64_t*)0x20dc4018 = (uint64_t)0xffffffffffffffff;
*(uint16_t*)0x20dc4020 = (uint16_t)0x2;
*(uint8_t*)0x20dc4022 = (uint8_t)0x40;
*(uint8_t*)0x20dc4023 = (uint8_t)0x2ed5;
*(uint8_t*)0x20dc4024 = (uint8_t)0x8;
r[21] = syscall(__NR_ioctl, r[10], 0x8922ul, 0x20dc4000ul);
}

int main()
{
loop();
return 0;
}