// https://syzkaller.appspot.com/bug?id=d97ff96e5a38f12752dd53d7a83bfcbdea3fee1b
// autogenerated by syzkaller (http://github.com/google/syzkaller)

#define _GNU_SOURCE

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_tun.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <net/if_arp.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>

const int kFailStatus = 67;
const int kRetryStatus = 69;

__attribute__((noreturn)) static void doexit(int status)
{
  volatile unsigned i;
  syscall(__NR_exit_group, status);
  for (i = 0;; i++) {
  }
}

__attribute__((noreturn)) static void fail(const char* msg, ...)
{
  int e = errno;
  fflush(stdout);
  va_list args;
  va_start(args, msg);
  vfprintf(stderr, msg, args);
  va_end(args);
  fprintf(stderr, " (errno %d)\n", e);
  doexit((e == ENOMEM || e == EAGAIN) ? kRetryStatus : kFailStatus);
}

static void vsnprintf_check(char* str, size_t size, const char* format,
                            va_list args)
{
  int rv;

  rv = vsnprintf(str, size, format, args);
  if (rv < 0)
    fail("tun: snprintf failed");
  if ((size_t)rv >= size)
    fail("tun: string '%s...' doesn't fit into buffer", str);
}

static void snprintf_check(char* str, size_t size, const char* format,
                           ...)
{
  va_list args;

  va_start(args, format);
  vsnprintf_check(str, size, format, args);
  va_end(args);
}

#define COMMAND_MAX_LEN 128

static void execute_command(const char* format, ...)
{
  va_list args;
  char command[COMMAND_MAX_LEN];
  int rv;

  va_start(args, format);

  vsnprintf_check(command, sizeof(command), format, args);
  rv = system(command);
  if (rv != 0)
    fail("tun: command \"%s\" failed with code %d", &command[0], rv);

  va_end(args);
}

static int tunfd = -1;

#define SYZ_TUN_MAX_PACKET_SIZE 1000

#define MAX_PIDS 32
#define ADDR_MAX_LEN 32

#define LOCAL_MAC "aa:aa:aa:aa:aa:%02hx"
#define REMOTE_MAC "bb:bb:bb:bb:bb:%02hx"

#define LOCAL_IPV4 "172.20.%d.170"
#define REMOTE_IPV4 "172.20.%d.187"

#define LOCAL_IPV6 "fe80::%02hxaa"
#define REMOTE_IPV6 "fe80::%02hxbb"

static void initialize_tun(uint64_t pid)
{
  if (pid >= MAX_PIDS)
    fail("tun: no more than %d executors", MAX_PIDS);
  int id = pid;

  tunfd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
  if (tunfd == -1)
    fail("tun: can't open /dev/net/tun");

  char iface[IFNAMSIZ];
  snprintf_check(iface, sizeof(iface), "syz%d", id);

  struct ifreq ifr;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, iface, IFNAMSIZ);
  ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0)
    fail("tun: ioctl(TUNSETIFF) failed");

  char local_mac[ADDR_MAX_LEN];
  snprintf_check(local_mac, sizeof(local_mac), LOCAL_MAC, id);
  char remote_mac[ADDR_MAX_LEN];
  snprintf_check(remote_mac, sizeof(remote_mac), REMOTE_MAC, id);

  char local_ipv4[ADDR_MAX_LEN];
  snprintf_check(local_ipv4, sizeof(local_ipv4), LOCAL_IPV4, id);
  char remote_ipv4[ADDR_MAX_LEN];
  snprintf_check(remote_ipv4, sizeof(remote_ipv4), REMOTE_IPV4, id);

  char local_ipv6[ADDR_MAX_LEN];
  snprintf_check(local_ipv6, sizeof(local_ipv6), LOCAL_IPV6, id);
  char remote_ipv6[ADDR_MAX_LEN];
  snprintf_check(remote_ipv6, sizeof(remote_ipv6), REMOTE_IPV6, id);

  execute_command("sysctl -w net.ipv6.conf.%s.accept_dad=0", iface);

  execute_command("sysctl -w net.ipv6.conf.%s.router_solicitations=0",
                  iface);

  execute_command("ip link set dev %s address %s", iface, local_mac);
  execute_command("ip addr add %s/24 dev %s", local_ipv4, iface);
  execute_command("ip -6 addr add %s/120 dev %s", local_ipv6, iface);
  execute_command("ip neigh add %s lladdr %s dev %s nud permanent",
                  remote_ipv4, remote_mac, iface);
  execute_command("ip -6 neigh add %s lladdr %s dev %s nud permanent",
                  remote_ipv6, remote_mac, iface);
  execute_command("ip link set dev %s up", iface);
}

static void setup_tun(uint64_t pid, bool enable_tun)
{
  if (enable_tun)
    initialize_tun(pid);
}

long r[170];
void loop()
{
  memset(r, -1, sizeof(r));
  r[0] = syscall(__NR_mmap, 0x20000000ul, 0xfff000ul, 0x3ul, 0x32ul,
                 0xfffffffffffffffful, 0x0ul);
  r[1] = syscall(__NR_socket, 0x10ul, 0x3ul, 0x6ul);
  *(uint32_t*)0x20d5bffc = (uint32_t)0x0;
  r[3] =
      syscall(__NR_setsockopt, r[1], 0x1ul, 0x8ul, 0x20d5bffcul, 0x4ul);
  *(uint64_t*)0x20f42000 = (uint64_t)0x20b53b98;
  *(uint32_t*)0x20f42008 = (uint32_t)0xc;
  *(uint64_t*)0x20f42010 = (uint64_t)0x20ced000;
  *(uint64_t*)0x20f42018 = (uint64_t)0x7;
  *(uint64_t*)0x20f42020 = (uint64_t)0x20000000;
  *(uint64_t*)0x20f42028 = (uint64_t)0x0;
  *(uint32_t*)0x20f42030 = (uint32_t)0x51;
  *(uint16_t*)0x20b53b98 = (uint16_t)0x10;
  *(uint16_t*)0x20b53b9a = (uint16_t)0x0;
  *(uint32_t*)0x20b53b9c = (uint32_t)0x0;
  *(uint32_t*)0x20b53ba0 = (uint32_t)0x0;
  *(uint64_t*)0x20ced000 = (uint64_t)0x20fa8000;
  *(uint64_t*)0x20ced008 = (uint64_t)0x10;
  *(uint64_t*)0x20ced010 = (uint64_t)0x20ba2ce4;
  *(uint64_t*)0x20ced018 = (uint64_t)0x30;
  *(uint64_t*)0x20ced020 = (uint64_t)0x2020ce04;
  *(uint64_t*)0x20ced028 = (uint64_t)0x50;
  *(uint64_t*)0x20ced030 = (uint64_t)0x20d19000;
  *(uint64_t*)0x20ced038 = (uint64_t)0x60;
  *(uint64_t*)0x20ced040 = (uint64_t)0x206bc000;
  *(uint64_t*)0x20ced048 = (uint64_t)0x20;
  *(uint64_t*)0x20ced050 = (uint64_t)0x20b64f50;
  *(uint64_t*)0x20ced058 = (uint64_t)0x30;
  *(uint64_t*)0x20ced060 = (uint64_t)0x20608000;
  *(uint64_t*)0x20ced068 = (uint64_t)0x80;
  *(uint32_t*)0x20fa8000 = (uint32_t)0x10;
  *(uint16_t*)0x20fa8004 = (uint16_t)0xffff;
  *(uint16_t*)0x20fa8006 = (uint16_t)0x4;
  *(uint32_t*)0x20fa8008 = (uint32_t)0x0;
  *(uint32_t*)0x20fa800c = (uint32_t)0x0;
  *(uint32_t*)0x20ba2ce4 = (uint32_t)0x10;
  *(uint16_t*)0x20ba2ce8 = (uint16_t)0x0;
  *(uint16_t*)0x20ba2cea = (uint16_t)0x726;
  *(uint32_t*)0x20ba2cec = (uint32_t)0x0;
  *(uint32_t*)0x20ba2cf0 = (uint32_t)0x0;
  *(uint32_t*)0x20ba2cf4 = (uint32_t)0x10;
  *(uint16_t*)0x20ba2cf8 = (uint16_t)0x0;
  *(uint16_t*)0x20ba2cfa = (uint16_t)0x132;
  *(uint32_t*)0x20ba2cfc = (uint32_t)0xfffffffffffffffc;
  *(uint32_t*)0x20ba2d00 = (uint32_t)0x817;
  *(uint32_t*)0x20ba2d04 = (uint32_t)0x10;
  *(uint16_t*)0x20ba2d08 = (uint16_t)0x4;
  *(uint16_t*)0x20ba2d0a = (uint16_t)0x0;
  *(uint32_t*)0x20ba2d0c = (uint32_t)0x1;
  *(uint32_t*)0x20ba2d10 = (uint32_t)0x1f;
  *(uint32_t*)0x2020ce04 = (uint32_t)0x10;
  *(uint16_t*)0x2020ce08 = (uint16_t)0x7f;
  *(uint16_t*)0x2020ce0a = (uint16_t)0x100;
  *(uint32_t*)0x2020ce0c = (uint32_t)0x1000;
  *(uint32_t*)0x2020ce10 = (uint32_t)0x9;
  *(uint32_t*)0x2020ce14 = (uint32_t)0x10;
  *(uint16_t*)0x2020ce18 = (uint16_t)0xffffffff;
  *(uint16_t*)0x2020ce1a = (uint16_t)0x1;
  *(uint32_t*)0x2020ce1c = (uint32_t)0x1f;
  *(uint32_t*)0x2020ce20 = (uint32_t)0x400;
  *(uint32_t*)0x2020ce24 = (uint32_t)0x10;
  *(uint16_t*)0x2020ce28 = (uint16_t)0x7;
  *(uint16_t*)0x2020ce2a = (uint16_t)0x308;
  *(uint32_t*)0x2020ce2c = (uint32_t)0x2;
  *(uint32_t*)0x2020ce30 = (uint32_t)0x4;
  *(uint32_t*)0x2020ce34 = (uint32_t)0x10;
  *(uint16_t*)0x2020ce38 = (uint16_t)0x15;
  *(uint16_t*)0x2020ce3a = (uint16_t)0x525;
  *(uint32_t*)0x2020ce3c = (uint32_t)0x3;
  *(uint32_t*)0x2020ce40 = (uint32_t)0x1;
  *(uint32_t*)0x2020ce44 = (uint32_t)0x10;
  *(uint16_t*)0x2020ce48 = (uint16_t)0xecb;
  *(uint16_t*)0x2020ce4a = (uint16_t)0x100;
  *(uint32_t*)0x2020ce4c = (uint32_t)0x6;
  *(uint32_t*)0x2020ce50 = (uint32_t)0x6;
  *(uint32_t*)0x20d19000 = (uint32_t)0x10;
  *(uint16_t*)0x20d19004 = (uint16_t)0x2;
  *(uint16_t*)0x20d19006 = (uint16_t)0x8;
  *(uint32_t*)0x20d19008 = (uint32_t)0x1fc0000000000000;
  *(uint32_t*)0x20d1900c = (uint32_t)0x1;
  *(uint32_t*)0x20d19010 = (uint32_t)0x10;
  *(uint16_t*)0x20d19014 = (uint16_t)0x6;
  *(uint16_t*)0x20d19016 = (uint16_t)0x600;
  *(uint32_t*)0x20d19018 = (uint32_t)0x10000;
  *(uint32_t*)0x20d1901c = (uint32_t)0x5;
  *(uint32_t*)0x20d19020 = (uint32_t)0x10;
  *(uint16_t*)0x20d19024 = (uint16_t)0xff;
  *(uint16_t*)0x20d19026 = (uint16_t)0x408;
  *(uint32_t*)0x20d19028 = (uint32_t)0x10000;
  *(uint32_t*)0x20d1902c = (uint32_t)0x5;
  *(uint32_t*)0x20d19030 = (uint32_t)0x10;
  *(uint16_t*)0x20d19034 = (uint16_t)0x100;
  *(uint16_t*)0x20d19036 = (uint16_t)0x400;
  *(uint32_t*)0x20d19038 = (uint32_t)0x7;
  *(uint32_t*)0x20d1903c = (uint32_t)0x42852611;
  *(uint32_t*)0x20d19040 = (uint32_t)0x10;
  *(uint16_t*)0x20d19044 = (uint16_t)0x1;
  *(uint16_t*)0x20d19046 = (uint16_t)0x10;
  *(uint32_t*)0x20d19048 = (uint32_t)0x4fe;
  *(uint32_t*)0x20d1904c = (uint32_t)0x6;
  *(uint32_t*)0x20d19050 = (uint32_t)0x10;
  *(uint16_t*)0x20d19054 = (uint16_t)0x2;
  *(uint16_t*)0x20d19056 = (uint16_t)0xc;
  *(uint32_t*)0x20d19058 = (uint32_t)0x3;
  *(uint32_t*)0x20d1905c = (uint32_t)0x200;
  *(uint32_t*)0x206bc000 = (uint32_t)0x10;
  *(uint16_t*)0x206bc004 = (uint16_t)0x0;
  *(uint16_t*)0x206bc006 = (uint16_t)0x2;
  *(uint32_t*)0x206bc008 = (uint32_t)0x4;
  *(uint32_t*)0x206bc00c = (uint32_t)0x3f;
  *(uint32_t*)0x206bc010 = (uint32_t)0x10;
  *(uint16_t*)0x206bc014 = (uint16_t)0x1;
  *(uint16_t*)0x206bc016 = (uint16_t)0x6;
  *(uint32_t*)0x206bc018 = (uint32_t)0x713;
  *(uint32_t*)0x206bc01c = (uint32_t)0xfffffffffffffffc;
  *(uint32_t*)0x20b64f50 = (uint32_t)0x10;
  *(uint16_t*)0x20b64f54 = (uint16_t)0x3ff;
  *(uint16_t*)0x20b64f56 = (uint16_t)0x0;
  *(uint32_t*)0x20b64f58 = (uint32_t)0x1f;
  *(uint32_t*)0x20b64f5c = (uint32_t)0xf78;
  *(uint32_t*)0x20b64f60 = (uint32_t)0x10;
  *(uint16_t*)0x20b64f64 = (uint16_t)0xffffffffffff7fff;
  *(uint16_t*)0x20b64f66 = (uint16_t)0x201;
  *(uint32_t*)0x20b64f68 = (uint32_t)0x1;
  *(uint32_t*)0x20b64f6c = (uint32_t)0x0;
  *(uint32_t*)0x20b64f70 = (uint32_t)0x10;
  *(uint16_t*)0x20b64f74 = (uint16_t)0x100000001;
  *(uint16_t*)0x20b64f76 = (uint16_t)0x800;
  *(uint32_t*)0x20b64f78 = (uint32_t)0x4;
  *(uint32_t*)0x20b64f7c = (uint32_t)0x7;
  *(uint32_t*)0x20608000 = (uint32_t)0x10;
  *(uint16_t*)0x20608004 = (uint16_t)0x80000000;
  *(uint16_t*)0x20608006 = (uint16_t)0x120;
  *(uint32_t*)0x20608008 = (uint32_t)0x2;
  *(uint32_t*)0x2060800c = (uint32_t)0xfff;
  *(uint32_t*)0x20608010 = (uint32_t)0x10;
  *(uint16_t*)0x20608014 = (uint16_t)0xff;
  *(uint16_t*)0x20608016 = (uint16_t)0x0;
  *(uint32_t*)0x20608018 = (uint32_t)0x0;
  *(uint32_t*)0x2060801c = (uint32_t)0x100000000;
  *(uint32_t*)0x20608020 = (uint32_t)0x10;
  *(uint16_t*)0x20608024 = (uint16_t)0xffffffffffff8001;
  *(uint16_t*)0x20608026 = (uint16_t)0x4fd;
  *(uint32_t*)0x20608028 = (uint32_t)0x1f;
  *(uint32_t*)0x2060802c = (uint32_t)0x6;
  *(uint32_t*)0x20608030 = (uint32_t)0x10;
  *(uint16_t*)0x20608034 = (uint16_t)0x100;
  *(uint16_t*)0x20608036 = (uint16_t)0x310;
  *(uint32_t*)0x20608038 = (uint32_t)0x9;
  *(uint32_t*)0x2060803c = (uint32_t)0x80000001;
  *(uint32_t*)0x20608040 = (uint32_t)0x10;
  *(uint16_t*)0x20608044 = (uint16_t)0x6;
  *(uint16_t*)0x20608046 = (uint16_t)0x301;
  *(uint32_t*)0x20608048 = (uint32_t)0x4;
  *(uint32_t*)0x2060804c = (uint32_t)0x5;
  *(uint32_t*)0x20608050 = (uint32_t)0x10;
  *(uint16_t*)0x20608054 = (uint16_t)0x4;
  *(uint16_t*)0x20608056 = (uint16_t)0x200;
  *(uint32_t*)0x20608058 = (uint32_t)0x3;
  *(uint32_t*)0x2060805c = (uint32_t)0x1;
  *(uint32_t*)0x20608060 = (uint32_t)0x10;
  *(uint16_t*)0x20608064 = (uint16_t)0x9;
  *(uint16_t*)0x20608066 = (uint16_t)0x400;
  *(uint32_t*)0x20608068 = (uint32_t)0x0;
  *(uint32_t*)0x2060806c = (uint32_t)0x828;
  *(uint32_t*)0x20608070 = (uint32_t)0x10;
  *(uint16_t*)0x20608074 = (uint16_t)0x2;
  *(uint16_t*)0x20608076 = (uint16_t)0x602;
  *(uint32_t*)0x20608078 = (uint32_t)0x4;
  *(uint32_t*)0x2060807c = (uint32_t)0x9;
  r[169] = syscall(__NR_sendmsg, r[1], 0x20f42000ul, 0x800ul);
}

int main()
{
  setup_tun(0, true);
  loop();
  return 0;
}