Re: net: heap out-of-bounds in fib6_clean_node/rt6_fill_node/fib6_age/fib6_prune_clone
From: Andrey Konovalov
Date: Wed Apr 19 2017 - 12:12:44 EST
On Wed, Apr 19, 2017 at 6:09 PM, David Ahern <dsa@xxxxxxxxxxxxxxxxxxx> wrote:
> On 4/18/17 2:43 PM, Andrey Konovalov wrote:
>> Hi!
>>
>> I've finally managed to reproduce one of the crashes on commit
>> 4f7d029b9bf009fbee76bb10c0c4351a1870d2f3 (4.11-rc7).
>>
>> I'm not sure if this bug has the same root cause as the first one
>> reported in this thread, but it definitely has to do with ipv6
>> routing.
>>
>> C reproducer, syzkaller program and my .config are attached.
>
> built a kernel with that config. booted the vm. ran the program. nada.
>
> strace is showing:
>
> clone(child_stack=0x72ffb0,
> flags=CLONE_NEWUTS|CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWNET) = -1 EINVAL
> (Invalid argument)
>
That's weird. I usually see this when I have CONFIG_USER_NS disabled.
Anyway, I just finished simplifying the reproducer. Give this one a try.
#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 <netinet/in.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 loop() {
int s0 = socket(AF_INET6, SOCK_STREAM, 0x84);
struct in6_rtmsg rtmsg;
memset(&rtmsg.rtmsg_dst, 0, sizeof(rtmsg.rtmsg_dst));
rtmsg.rtmsg_src = in6addr_loopback;
memset(&rtmsg.rtmsg_gateway, 0, sizeof(rtmsg.rtmsg_gateway));
rtmsg.rtmsg_type = 0x4;
rtmsg.rtmsg_dst_len = 0x0000;
rtmsg.rtmsg_src_len = 0x7;
rtmsg.rtmsg_metric = 0x100;
rtmsg.rtmsg_info = 0x80000001;
rtmsg.rtmsg_flags = 0x40000000;
rtmsg.rtmsg_ifindex = if_nametoindex("gre0");
ioctl(s0, SIOCADDRT, &rtmsg);
int s1 = socket(AF_INET6, SOCK_RAW|SOCK_NONBLOCK, IPPROTO_RAW);
struct sockaddr_in6 si;
memset(&si, 0, sizeof(si));
char buffer[1];
sendto(s1, &buffer[0], 0, MSG_CONFIRM, (const struct sockaddr *)&si, sizeof(si));
}
int main() {
unshare(CLONE_NEWUSER);
unshare(CLONE_NEWNET);
loop();
return 0;
}