net/ipv6: GPF in rt6_device_match
From: Andrey Konovalov
Date: Wed May 03 2017 - 12:33:25 EST
Hi David,
Got another report related to fib6.
I'm on 89c9fea3c8034cdb2fd745f551cde0b507fd6893 with your last patch applied.
A reproducer and .config are attached.
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: 4059 Comm: a.out Not tainted 4.11.0+ #312
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
task: ffff880064d11600 task.stack: ffff88006b0e8000
RIP: 0010:rt6_device_match net/ipv6/route.c:515
RIP: 0010:ip6_pol_route_lookup+0x2f2/0xa90 net/ipv6/route.c:885
RSP: 0018:ffff88006b0ef0b8 EFLAGS: 00010246
RAX: 1ffff1000d00f20b RBX: ffff880066dd96c0 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff88006b0ef5b8 RDI: ffff880068079058
RBP: ffff88006b0ef1e0 R08: 0000000000000002 R09: 4e43247300000000
R10: ffff88006b0ef0b8 R11: dffffc0000000000 R12: 0000000000090000
R13: ffff880068078f00 R14: 0000000000000000 R15: dffffc0000000000
FS: 00007fd68b4d5700(0000) GS:ffff88006cb00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000208e2fe0 CR3: 0000000064c9b000 CR4: 00000000000006e0
Call Trace:
fib6_rule_action+0x261/0x8a0 net/ipv6/fib6_rules.c:100
fib_rules_lookup+0x3cf/0xca0 net/core/fib_rules.c:279
fib6_rule_lookup+0x175/0x360 net/ipv6/fib6_rules.c:44
rt6_lookup+0x267/0x3b0 net/ipv6/route.c:924
ip6gre_tnl_link_config+0x774/0xc00 net/ipv6/ip6_gre.c:746
ip6gre_tunnel_locate+0x4ab/0x7c0 net/ipv6/ip6_gre.c:340
ip6gre_tunnel_ioctl+0x5cd/0x21f0 net/ipv6/ip6_gre.c:878
dev_ifsioc+0x53f/0x9f0 net/core/dev_ioctl.c:338
dev_ioctl+0xc3c/0x1160 net/core/dev_ioctl.c:555
sock_ioctl+0x169/0x440 net/socket.c:944
vfs_ioctl fs/ioctl.c:45
do_vfs_ioctl+0x1bf/0x1660 fs/ioctl.c:685
SYSC_ioctl fs/ioctl.c:700
SyS_ioctl+0x8f/0xc0 fs/ioctl.c:691
entry_SYSCALL_64_fastpath+0x1f/0xbe arch/x86/entry/entry_64.S:204
RIP: 0033:0x7fd68abe7b79
RSP: 002b:00007ffce50c8aa8 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007ffce50c8c00 RCX: 00007fd68abe7b79
RDX: 000000002036afd8 RSI: 00000000000089f1 RDI: 0000000000000004
RBP: 00000000004004e0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000
R13: 00007ffce50c8c00 R14: 0000000000000000 R15: 0000000000000000
Code: 95 b1 7d fd 49 8d bd 58 01 00 00 48 89 f8 48 c1 e8 03 42 80 3c
38 00 0f 85 5f 07 00 00 4d 8b b5 58 01 00 00 4c 89 f2 48 c1 ea 03 <42>
80 3c 3a 00 0f 85 39 07 00 00 4d 8b 36 49 8d be 08 01 00 00
RIP: ip6_pol_route_lookup+0x2f2/0xa90 RSP: ffff88006b0ef0b8
---[ end trace 68c87c92d8d28615 ]---
// 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 <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <linux/capability.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_tun.h>
#include <linux/ip.h>
#include <linux/kvm.h>
#include <linux/sched.h>
#include <linux/tcp.h>
#include <net/if_arp.h>
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <pthread.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1,
uintptr_t a2, uintptr_t a3,
uintptr_t a4, uintptr_t a5,
uintptr_t a6, uintptr_t a7,
uintptr_t a8)
{
switch (nr) {
default:
return syscall(nr, a0, a1, a2, a3, a4, a5);
}
}
long r[115];
void main()
{
memset(r, -1, sizeof(r));
r[0] = execute_syscall(__NR_mmap, 0x20000000ul, 0xe91000ul, 0x3ul,
0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
r[1] = execute_syscall(__NR_socket, 0xaul, 0x6ul, 0x0ul, 0, 0, 0, 0,
0, 0);
(*(uint8_t*)0x20000000 = (uint8_t)0xfd);
(*(uint8_t*)0x20000001 = (uint8_t)0x0);
(*(uint8_t*)0x20000002 = (uint8_t)0x0);
(*(uint8_t*)0x20000003 = (uint8_t)0x0);
(*(uint8_t*)0x20000004 = (uint8_t)0x0);
(*(uint8_t*)0x20000005 = (uint8_t)0x0);
(*(uint8_t*)0x20000006 = (uint8_t)0x0);
(*(uint8_t*)0x20000007 = (uint8_t)0x0);
(*(uint8_t*)0x20000008 = (uint8_t)0x0);
(*(uint8_t*)0x20000009 = (uint8_t)0x0);
(*(uint8_t*)0x2000000a = (uint8_t)0x0);
(*(uint8_t*)0x2000000b = (uint8_t)0x0);
(*(uint8_t*)0x2000000c = (uint8_t)0x0);
(*(uint8_t*)0x2000000d = (uint8_t)0x0);
(*(uint8_t*)0x2000000e = (uint8_t)0x0);
(*(uint8_t*)0x2000000f = (uint8_t)0xbb);
(*(uint8_t*)0x20000010 = (uint8_t)0xfd);
(*(uint8_t*)0x20000011 = (uint8_t)0x0);
(*(uint8_t*)0x20000012 = (uint8_t)0x0);
(*(uint8_t*)0x20000013 = (uint8_t)0x0);
(*(uint8_t*)0x20000014 = (uint8_t)0x0);
(*(uint8_t*)0x20000015 = (uint8_t)0x0);
(*(uint8_t*)0x20000016 = (uint8_t)0x0);
(*(uint8_t*)0x20000017 = (uint8_t)0x0);
(*(uint8_t*)0x20000018 = (uint8_t)0x0);
(*(uint8_t*)0x20000019 = (uint8_t)0x0);
(*(uint8_t*)0x2000001a = (uint8_t)0x0);
(*(uint8_t*)0x2000001b = (uint8_t)0x0);
(*(uint8_t*)0x2000001c = (uint8_t)0x0);
(*(uint8_t*)0x2000001d = (uint8_t)0x0);
(*(uint8_t*)0x2000001e = (uint8_t)0x0);
(*(uint8_t*)0x2000001f = (uint8_t)0xaa);
(*(uint8_t*)0x20000020 = (uint8_t)0x0);
(*(uint8_t*)0x20000021 = (uint8_t)0x0);
(*(uint8_t*)0x20000022 = (uint8_t)0x0);
(*(uint8_t*)0x20000023 = (uint8_t)0x0);
(*(uint8_t*)0x20000024 = (uint8_t)0x0);
(*(uint8_t*)0x20000025 = (uint8_t)0x0);
(*(uint8_t*)0x20000026 = (uint8_t)0x0);
(*(uint8_t*)0x20000027 = (uint8_t)0x0);
(*(uint8_t*)0x20000028 = (uint8_t)0x0);
(*(uint8_t*)0x20000029 = (uint8_t)0x0);
(*(uint8_t*)0x2000002a = (uint8_t)0x0);
(*(uint8_t*)0x2000002b = (uint8_t)0x0);
(*(uint8_t*)0x2000002c = (uint8_t)0x0);
(*(uint8_t*)0x2000002d = (uint8_t)0x0);
(*(uint8_t*)0x2000002e = (uint8_t)0x0);
(*(uint8_t*)0x2000002f = (uint8_t)0x0);
(*(uint32_t*)0x20000030 = (uint32_t)0x0);
(*(uint16_t*)0x20000034 = (uint16_t)0x0);
(*(uint16_t*)0x20000036 = (uint16_t)0x0);
(*(uint32_t*)0x20000038 = (uint32_t)0xffffffffffffffff);
(*(uint64_t*)0x20000040 = (uint64_t)0x0);
(*(uint32_t*)0x20000048 = (uint32_t)0x3fffffff);
(*(uint32_t*)0x2000004c = (uint32_t)0x0);
r[57] = execute_syscall(__NR_ioctl, r[1], 0x890bul, 0x20000000ul, 0,
0, 0, 0, 0, 0);
r[58] = execute_syscall(__NR_socket, 0x2ul, 0x1ul, 0x0ul, 0, 0, 0, 0,
0, 0);
(*(uint16_t*)0x208e3000 = (uint16_t)0xa);
(*(uint16_t*)0x208e3002 = (uint16_t)0x204e);
(*(uint32_t*)0x208e3004 = (uint32_t)0x0);
(*(uint8_t*)0x208e3008 = (uint8_t)0xfd);
(*(uint8_t*)0x208e3009 = (uint8_t)0x0);
(*(uint8_t*)0x208e300a = (uint8_t)0x0);
(*(uint8_t*)0x208e300b = (uint8_t)0x0);
(*(uint8_t*)0x208e300c = (uint8_t)0x0);
(*(uint8_t*)0x208e300d = (uint8_t)0x0);
(*(uint8_t*)0x208e300e = (uint8_t)0x0);
(*(uint8_t*)0x208e300f = (uint8_t)0x0);
(*(uint8_t*)0x208e3010 = (uint8_t)0x0);
(*(uint8_t*)0x208e3011 = (uint8_t)0x0);
(*(uint8_t*)0x208e3012 = (uint8_t)0x0);
(*(uint8_t*)0x208e3013 = (uint8_t)0x0);
(*(uint8_t*)0x208e3014 = (uint8_t)0x0);
(*(uint8_t*)0x208e3015 = (uint8_t)0x0);
(*(uint8_t*)0x208e3016 = (uint8_t)0x0);
(*(uint8_t*)0x208e3017 = (uint8_t)0xaa);
(*(uint32_t*)0x208e3018 = (uint32_t)0x0);
(*(uint16_t*)0x208e301c = (uint16_t)0xa);
(*(uint16_t*)0x208e301e = (uint16_t)0x214e);
(*(uint32_t*)0x208e3020 = (uint32_t)0x2);
(*(uint8_t*)0x208e3024 = (uint8_t)0xfd);
(*(uint8_t*)0x208e3025 = (uint8_t)0x0);
(*(uint8_t*)0x208e3026 = (uint8_t)0x0);
(*(uint8_t*)0x208e3027 = (uint8_t)0x0);
(*(uint8_t*)0x208e3028 = (uint8_t)0x0);
(*(uint8_t*)0x208e3029 = (uint8_t)0x0);
(*(uint8_t*)0x208e302a = (uint8_t)0x0);
(*(uint8_t*)0x208e302b = (uint8_t)0x0);
(*(uint8_t*)0x208e302c = (uint8_t)0x0);
(*(uint8_t*)0x208e302d = (uint8_t)0x0);
(*(uint8_t*)0x208e302e = (uint8_t)0x0);
(*(uint8_t*)0x208e302f = (uint8_t)0x0);
(*(uint8_t*)0x208e3030 = (uint8_t)0x0);
(*(uint8_t*)0x208e3031 = (uint8_t)0x0);
(*(uint8_t*)0x208e3032 = (uint8_t)0x0);
(*(uint8_t*)0x208e3033 = (uint8_t)0xaa);
(*(uint32_t*)0x208e3034 = (uint32_t)0x8);
(*(uint16_t*)0x208e3038 = (uint16_t)0x2);
(*(uint16_t*)0x208e303a = (uint16_t)0x204e);
(*(uint32_t*)0x208e303c = (uint32_t)0x20000e0);
(*(uint8_t*)0x208e3040 = (uint8_t)0x0);
(*(uint8_t*)0x208e3041 = (uint8_t)0x0);
(*(uint8_t*)0x208e3042 = (uint8_t)0x0);
(*(uint8_t*)0x208e3043 = (uint8_t)0x0);
(*(uint8_t*)0x208e3044 = (uint8_t)0x0);
(*(uint8_t*)0x208e3045 = (uint8_t)0x0);
(*(uint8_t*)0x208e3046 = (uint8_t)0x0);
(*(uint8_t*)0x208e3047 = (uint8_t)0x0);
r[110] =
execute_syscall(__NR_setsockopt, 0xfffffffffffffffful, 0x84ul,
0x65ul, 0x208e3000ul, 0x3ul, 0, 0, 0, 0);
(memcpy((void*)0x2036afd8,
"\x69\x70\x36\x67\x72\x65\x30\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00",
16));
(*(uint64_t*)0x2036afe8 = (uint64_t)0x208e2fe0);
(memcpy((void*)0x208e2fe0,
"\x22\xc6\x75\x26\x0c\xc0\x64\xb4\x75\x69\x48\xed"
"\xac\x6e\x9b\x34\x00\x00\x09\x00\xa9\x44\x5e\x96"
"\x6f\x34\x04\x20\xff\xff\xff\xb5",
32));
r[114] = execute_syscall(__NR_ioctl, r[58], 0x89f1ul, 0x2036afd8ul, 0,
0, 0, 0, 0, 0);
}
Attachment:
.config
Description: Binary data