Messages in this thread | | | From | Andrey Konovalov <> | Date | Thu, 20 Apr 2017 17:28:29 +0200 | Subject | Re: net: heap out-of-bounds in fib6_clean_node/rt6_fill_node/fib6_age/fib6_prune_clone |
| |
I've extracted a reproducer for another bug.
This one seems to be much closer to what Dmitry reported intially.
------------[ cut here ]------------ WARNING: CPU: 1 PID: 3892 at net/ipv6/ip6_fib.c:1472 fib6_del+0xa60/0xdc0 Modules linked in: CPU: 1 PID: 3892 Comm: a.out Not tainted 4.11.0-rc7+ #251 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/0x398 lib/dump_stack.c:52 __warn+0x19f/0x1e0 kernel/panic.c:549 warn_slowpath_null+0x2c/0x40 kernel/panic.c:584 fib6_del+0xa60/0xdc0 net/ipv6/ip6_fib.c:1472 fib6_clean_node+0x3ce/0x550 net/ipv6/ip6_fib.c:1652 fib6_walk_continue+0x577/0x760 net/ipv6/ip6_fib.c:1578 fib6_walk+0x91/0xf0 net/ipv6/ip6_fib.c:1623 fib6_clean_tree+0x266/0x3c0 net/ipv6/ip6_fib.c:1695 __fib6_clean_all+0x1f7/0x3b0 net/ipv6/ip6_fib.c:1711 fib6_clean_all+0x27/0x30 net/ipv6/ip6_fib.c:1722 rt6_ifdown+0xf7/0x910 net/ipv6/route.c:2820 addrconf_ifdown+0x1a3/0x1aa0 net/ipv6/addrconf.c:3541 addrconf_notify+0x1bb/0x2570 net/ipv6/addrconf.c:3466 notifier_call_chain+0x145/0x2f0 kernel/notifier.c:93 __raw_notifier_call_chain kernel/notifier.c:394 raw_notifier_call_chain+0x2d/0x40 kernel/notifier.c:401 call_netdevice_notifiers_info+0x51/0x90 net/core/dev.c:1647 call_netdevice_notifiers net/core/dev.c:1663 __dev_notify_flags+0x1fd/0x320 net/core/dev.c:6499 dev_change_flags+0xf5/0x140 net/core/dev.c:6530 dev_ifsioc+0x62a/0x9f0 net/core/dev_ioctl.c:254 dev_ioctl+0x249/0x1160 net/core/dev_ioctl.c:532 sock_do_ioctl+0x94/0xb0 net/socket.c:913 sock_ioctl+0x28f/0x440 net/socket.c:1004 vfs_ioctl fs/ioctl.c:45 do_vfs_ioctl+0x1bf/0x1780 fs/ioctl.c:685 SYSC_ioctl fs/ioctl.c:700 SyS_ioctl+0x8f/0xc0 fs/ioctl.c:691 entry_SYSCALL_64_fastpath+0x1f/0xc2 arch/x86/entry/entry_64.S:204 RIP: 0033:0x7f575ded4347 RSP: 002b:00007fffc94d9948 EFLAGS: 00000217 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007fffc94d9b30 RCX: 00007f575ded4347 RDX: 00007fffc94d9980 RSI: 0000000000008914 RDI: 0000000000000006 RBP: 00000000004004e0 R08: 0000000000000028 R09: 0101010101010101 R10: 0000000000000000 R11: 0000000000000217 R12: 0000000000000000 R13: 00007fffc94d9b30 R14: 0000000000000000 R15: 0000000000000000 ---[ end trace 9bda4459ad907043 ]--- [unhandled content-type:application/octet-stream]// autogenerated by syzkaller (http://github.com/google/syzkaller)
#ifndef __NR_socket #define __NR_socket 41 #endif #ifndef __NR_ioctl #define __NR_ioctl 16 #endif #ifndef __NR_mmap #define __NR_mmap 9 #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 <linux/capability.h> #include <linux/if.h> #include <linux/if_tun.h> #include <linux/kvm.h> #include <linux/sched.h> #include <net/if_arp.h> #include <linux/in.h> #include <linux/ipv6.h> #include <linux/ipv6_route.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>
void test() { int s0 = socket(AF_INET6, SOCK_RAW, IPPROTO_TCP);
struct ifreq ifr0; memset(&ifr0, 0, sizeof(ifr0)); strcpy(ifr0.ifr_name, "lo"); ifr0.ifr_flags = 0x8301; ioctl(s0, SIOCSIFFLAGS, &ifr0);
int s1 = socket(AF_INET6, SOCK_RAW|SOCK_CLOEXEC, 0x2b);
int s2 = socket(AF_INET6, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP);
struct ifreq ifr1; memset(&ifr1, 0, sizeof(ifr1)); strcpy(ifr1.ifr_name, "ip6_vti0"); ioctl(s2, SIOCGIFINDEX, &ifr1);
struct in6_ifreq ifr2; memset(&ifr2, 0, sizeof(ifr2)); memcpy(&ifr2.ifr6_addr, "\xfd\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\xbb", 16); ifr2.ifr6_prefixlen = 9; ifr2.ifr6_ifindex = ifr1.ifr_ifindex; ioctl(s1, SIOCSIFADDR, &ifr2);
int s3 = socket(AF_INET6, SOCK_STREAM|SOCK_NONBLOCK, 0x84);
struct ifreq ifr3; memset(&ifr3, 0, sizeof(ifr3)); strcpy(ifr3.ifr_name, "lo"); ifr3.ifr_flags = 0x8000; ioctl(s3, SIOCSIFFLAGS, &ifr3);
int s4 = socket(AF_INET6, SOCK_RAW, 0x3);
struct ifreq ifr4; memset(&ifr4, 0, sizeof(ifr4)); strcpy(ifr4.ifr_name, "ip6_vti0"); ifr4.ifr_flags = 0x8301; ioctl(s4, SIOCSIFFLAGS, &ifr4);
ioctl(s0, SIOCSIFFLAGS, &ifr0); ioctl(s3, SIOCSIFFLAGS, &ifr3); }
int main() { test(); return 0; }
| |