Re: net/ipv6: GPF in rt6_ifdown

From: Andrey Konovalov
Date: Wed Jun 21 2017 - 13:53:13 EST


On Wed, Jun 21, 2017 at 3:09 PM, Andrey Konovalov <andreyknvl@xxxxxxxxxx> wrote:
> On Wed, Jun 21, 2017 at 2:08 PM, Andrey Konovalov <andreyknvl@xxxxxxxxxx> wrote:
>> Hi,
>>
>> I've got the following error report while fuzzing the kernel with syzkaller.
>>
>> On commit 9705596d08ac87c18aee32cc97f2783b7d14624e (4.12-rc6+).
>>
>> It might be related to:
>> https://groups.google.com/forum/#!topic/syzkaller/ZJaqAiFLe3k
>>
>> I only have a reproducer in the form of a syzkaller program, attached
>> together with my .config.
>
> I now have a C reproducer as well, attached.

And here's a much simpler reproducer.

>
>>
>> It can be executed as described here:
>> https://github.com/google/syzkaller/blob/master/docs/executing_syzkaller_programs.md
>>
>> With the following flags:
>> ./syz-execprog -repeat=0 -procs=8 -sandbox=namespace ./log
>>
>> Since I'm able to reproduce it, I can apply debug patches and test
>> with them if required.
>>
>> kasan: CONFIG_KASAN_INLINE enabled
>> kasan: GPF could be caused by NULL-ptr deref or user memory access
>> general protection fault: 0000 [#1] SMP KASAN
>> Modules linked in:
>> CPU: 1 PID: 4499 Comm: syz-executor Not tainted 4.12.0-rc6+ #10
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>> task: ffff880068e88000 task.stack: ffff88005e0a0000
>> RIP: 0010:rt6_uncached_list_flush_dev net/ipv6/route.c:167
>> RIP: 0010:rt6_ifdown+0x3d4/0x910 net/ipv6/route.c:2824
>> RSP: 0018:ffff88005e0a6e38 EFLAGS: 00010246
>> RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffc900029a2000
>> RDX: 0000000000002dce RSI: ffffffff83ea9ee8 RDI: ffff88006ca25444
>> RBP: ffff88005e0a6f98 R08: 0000000000000001 R09: c9811a8e00000000
>> R10: ffff880068e88810 R11: dffffc0000000000 R12: ffff88005e0ad518
>> R13: ffff88005e0ad500 R14: ffff88006200b300 R15: dffffc0000000000
>> FS: 00007f4ccaad9700(0000) GS:ffff88006cb00000(0000) knlGS:0000000000000000
>> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> CR2: 000000002000f000 CR3: 00000000672e8000 CR4: 00000000000006e0
>> Call Trace:
>> addrconf_ifdown+0x1a8/0x1a30 net/ipv6/addrconf.c:3588
>> addrconf_notify+0x1cf/0x2630 net/ipv6/addrconf.c:3512
>> 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_notify_flags+0x202/0x330 net/core/dev.c:6647
>> dev_change_flags+0xfa/0x150 net/core/dev.c:6678
>> dev_ifsioc+0x62f/0x9f0 net/core/dev_ioctl.c:254
>> 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:0x446349
>> RSP: 002b:00007f4ccaad8c08 EFLAGS: 00000282 ORIG_RAX: 0000000000000010
>> RAX: ffffffffffffffda RBX: 0000000000003210 RCX: 0000000000446349
>> RDX: 00000000208befe0 RSI: 0000000000008914 RDI: 0000000000000018
>> RBP: 00000000ffffffff R08: 0000000000000000 R09: 0000000000000000
>> R10: 0000000000000000 R11: 0000000000000282 R12: 0000000000000018
>> R13: 0000000000003210 R14: 00000000006e42d0 R15: 0000000000008914
>> Code: 49 8b 9d 58 01 00 00 4c 89 e0 48 c1 e8 03 42 80 3c 38 00 0f 85
>> 6d 04 00 00 49 8b 45 18 48 89 85 f0 fe ff ff 48 89 d8 48 c1 e8 03 <42>
>> 80 3c 38 00 0f 85 5d 04 00 00 4c 3b 33 0f 84 d7 01 00 00 e8
>> RIP: rt6_ifdown+0x3d4/0x910 RSP: ffff88005e0a6e38
>> ---[ end trace f2e889448df70bb4 ]---
>> Kernel panic - not syncing: Fatal exception in interrupt
>> Kernel Offset: disabled
>> ---[ end Kernel panic - not syncing: Fatal exception in interrupt
// autogenerated by syzkaller (http://github.com/google/syzkaller)

#ifndef __NR_sendmmsg
#define __NR_sendmmsg 307
#endif
#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_connect
#define __NR_connect 42
#endif

#define _GNU_SOURCE

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

static void test();

void loop()
{
while (1) {
test();
}
}

long r[81];
void test()
{
memset(r, -1, sizeof(r));
r[0] = syscall(__NR_mmap, 0x20000000ul, 0xfff000ul, 0x3ul, 0x32ul,
0xfffffffffffffffful, 0x0ul);
r[1] = syscall(__NR_socket, 0xaul, 0x3ul, 0x6ul);
memcpy((void*)0x20334000,
"\x73\x69\x74\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00",
16);
*(uint16_t*)0x20334010 = (uint16_t)0x2;
r[4] = syscall(__NR_ioctl, r[1], 0x8914ul, 0x20334000ul);
r[5] = syscall(__NR_socket, 0x2ul, 0x806ul, 0x0ul);
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)0x0;
*(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[13] = syscall(__NR_ioctl, r[5], 0x8922ul, 0x20dc4000ul);
r[14] =
syscall(__NR_socket, 0xaul, 0x8000000080803ul, 0x200000000fful);
*(uint16_t*)0x20ffcfe4 = (uint16_t)0xa;
*(uint16_t*)0x20ffcfe6 = (uint16_t)0x204e;
*(uint32_t*)0x20ffcfe8 = (uint32_t)0xfffffffffffffffd;
*(uint64_t*)0x20ffcfec = (uint64_t)0x0;
*(uint64_t*)0x20ffcff4 = (uint64_t)0x100000000000000;
*(uint32_t*)0x20ffcffc = (uint32_t)0xfffffffffffffffd;
r[21] = syscall(__NR_connect, r[14], 0x20ffcfe4ul, 0x1cul);
*(uint64_t*)0x20fe2f40 = (uint64_t)0x0;
*(uint32_t*)0x20fe2f48 = (uint32_t)0x0;
*(uint64_t*)0x20fe2f50 = (uint64_t)0x20736f70;
*(uint64_t*)0x20fe2f58 = (uint64_t)0x3;
*(uint64_t*)0x20fe2f60 = (uint64_t)0x20ff3000;
*(uint64_t*)0x20fe2f68 = (uint64_t)0x0;
*(uint32_t*)0x20fe2f70 = (uint32_t)0x1;
*(uint32_t*)0x20fe2f78 = (uint32_t)0x0;
*(uint64_t*)0x20fe2f80 = (uint64_t)0x0;
*(uint32_t*)0x20fe2f88 = (uint32_t)0x0;
*(uint64_t*)0x20fe2f90 = (uint64_t)0x20642000;
*(uint64_t*)0x20fe2f98 = (uint64_t)0x2;
*(uint64_t*)0x20fe2fa0 = (uint64_t)0x20acee40;
*(uint64_t*)0x20fe2fa8 = (uint64_t)0x4;
*(uint32_t*)0x20fe2fb0 = (uint32_t)0x4010;
*(uint32_t*)0x20fe2fb8 = (uint32_t)0x5;
*(uint64_t*)0x20fe2fc0 = (uint64_t)0x0;
*(uint32_t*)0x20fe2fc8 = (uint32_t)0x0;
*(uint64_t*)0x20fe2fd0 = (uint64_t)0x20ff4797;
*(uint64_t*)0x20fe2fd8 = (uint64_t)0x0;
*(uint64_t*)0x20fe2fe0 = (uint64_t)0x20f51000;
*(uint64_t*)0x20fe2fe8 = (uint64_t)0x1;
*(uint32_t*)0x20fe2ff0 = (uint32_t)0x20008000;
*(uint32_t*)0x20fe2ff8 = (uint32_t)0x2;
*(uint64_t*)0x20736f70 = (uint64_t)0x20a4ff16;
*(uint64_t*)0x20736f78 = (uint64_t)0x19;
*(uint64_t*)0x20736f80 = (uint64_t)0x20869fff;
*(uint64_t*)0x20736f88 = (uint64_t)0x1;
*(uint64_t*)0x20736f90 = (uint64_t)0x20b69000;
*(uint64_t*)0x20736f98 = (uint64_t)0xe;
memcpy((void*)0x20a4ff16,
"\x8c\x57\x08\xbb\x94\x12\x40\xba\x9d\x13\xee\x30\xb0\x8c\x4e"
"\xb2\x05\xae\x96\x02\xd5\x06\x29\x55\xff",
25);
memcpy((void*)0x20869fff, "\xa5", 1);
memcpy((void*)0x20b69000,
"\xdf\x4b\x85\xcb\x5d\x5f\xd7\xe2\x50\x05\xb2\x5c\xc5\x0e",
14);
*(uint64_t*)0x20642000 = (uint64_t)0x20aa4000;
*(uint64_t*)0x20642008 = (uint64_t)0x19;
*(uint64_t*)0x20642010 = (uint64_t)0x20ff3000;
*(uint64_t*)0x20642018 = (uint64_t)0xa6;
memcpy((void*)0x20aa4000,
"\x01\x45\x00\x00\x00\x1f\x2c\x03\x1d\xd8\xcd\xbd\xce\x3a\x39"
"\xbd\x46\x4e\x0f\xcf\x4c\xdc\x18\x8e\x8a",
25);
memcpy((void*)0x20ff3000,
"\x56\xbe\xdf\x98\x31\x01\xe9\x03\xbb\x60\xd0\xf4\x57\xa4\x4d"
"\x46\x07\xb5\xf0\xb2\x5b\xd6\x67\x44\xf9\xd1\x5f\x57\x48\xca"
"\x8e\xd5\x8b\x3d\x08\xe8\x46\x23\x86\x5b\xcd\xa5\xdd\xaf\x53"
"\x80\x09\xae\xda\xc0\x0f\xdf\x62\xcd\xdb\x0a\xe7\x3f\xe9\x60"
"\xc7\x3b\xc4\x5b\xf0\x5c\x09\xad\x36\x31\xbc\x7a\x82\x0a\xb4"
"\x8b\x2b\x2a\xc0\x55\x88\xac\xd3\x31\x55\x54\x73\x9c\xa3\x91"
"\xff\xe2\x58\xd3\xb6\x7a\x24\xd4\x0f\x09\x69\xca\x49\x7a\xe3"
"\xb6\x48\x45\xc9\x9e\x6d\xba\xd7\x2a\x9c\x04\xcb\xea\x26\xe9"
"\x19\xa2\x74\xde\x70\x28\xe7\x3f\xfb\x4b\xf9\x79\xd5\x9f\xe5"
"\xcf\xa9\x05\xac\xf0\x90\x0f\xa3\x40\x52\x40\x0b\x95\x4f\x43"
"\xd5\x44\x5c\x78\xeb\xc4\x2e\x91\x0f\x2a\x6f\xc2\xa4\xe9\xe6"
"\x12",
166);
*(uint64_t*)0x20acee40 = (uint64_t)0x10;
*(uint32_t*)0x20acee48 = (uint32_t)0x88;
*(uint32_t*)0x20acee4c = (uint32_t)0x800000006;
*(uint64_t*)0x20acee50 = (uint64_t)0x10;
*(uint32_t*)0x20acee58 = (uint32_t)0x108;
*(uint32_t*)0x20acee5c = (uint32_t)0x9;
*(uint64_t*)0x20acee60 = (uint64_t)0x10;
*(uint32_t*)0x20acee68 = (uint32_t)0x11f;
*(uint32_t*)0x20acee6c = (uint32_t)0x6;
*(uint64_t*)0x20acee70 = (uint64_t)0x10;
*(uint32_t*)0x20acee78 = (uint32_t)0x10f;
*(uint32_t*)0x20acee7c = (uint32_t)0x10001;
*(uint64_t*)0x20f51000 = (uint64_t)0x10;
*(uint32_t*)0x20f51008 = (uint32_t)0x1;
*(uint32_t*)0x20f5100c = (uint32_t)0x7;
r[76] = syscall(__NR_sendmmsg, r[14], 0x20fe2f40ul, 0x3ul, 0xc0ul);
r[77] = syscall(__NR_socket, 0xaul, 0x3ul, 0x6ul);
memcpy((void*)0x20334000,
"\x73\x69\x74\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00",
16);
*(uint16_t*)0x20334010 = (uint16_t)0x1;
r[80] = syscall(__NR_ioctl, r[77], 0x8914ul, 0x20334000ul);
}

int main()
{
int i;
for (i = 0; i < 8; i++) {
if (fork() == 0) {
loop();
return 0;
}
}
sleep(1000000);
return 0;
}