linux: add 270 new local repros

Linux reproducers updates from
https://github.com/dvyukov/syzkaller-repros

Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
diff --git a/syzkaller-repros/linux/0139a1a5c800cb341ec87d5b6f92ee2a6e505b16.c b/syzkaller-repros/linux/0139a1a5c800cb341ec87d5b6f92ee2a6e505b16.c
new file mode 100644
index 0000000..e4e72fd
--- /dev/null
+++ b/syzkaller-repros/linux/0139a1a5c800cb341ec87d5b6f92ee2a6e505b16.c
@@ -0,0 +1,1609 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sched.h>
+#include <signal.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/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 <time.h>
+#include <unistd.h>
+
+#include <linux/capability.h>
+#include <linux/futex.h>
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/if_tun.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/tcp.h>
+#include <linux/veth.h>
+
+unsigned long long procid;
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void use_temporary_dir(void)
+{
+  char tmpdir_template[] = "./syzkaller.XXXXXX";
+  char* tmpdir = mkdtemp(tmpdir_template);
+  if (!tmpdir)
+    exit(1);
+  if (chmod(tmpdir, 0777))
+    exit(1);
+  if (chdir(tmpdir))
+    exit(1);
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+  pthread_t th;
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setstacksize(&attr, 128 << 10);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (pthread_create(&th, &attr, fn, arg) == 0) {
+      pthread_attr_destroy(&attr);
+      return;
+    }
+    if (errno == EAGAIN) {
+      usleep(50);
+      continue;
+    }
+    break;
+  }
+  exit(1);
+}
+
+#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
+#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
+  *(type*)(addr) =                                                             \
+      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
+            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))
+
+typedef struct {
+  int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+  if (ev->state)
+    exit(1);
+  __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
+  syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
+}
+
+static void event_wait(event_t* ev)
+{
+  while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
+}
+
+static int event_isset(event_t* ev)
+{
+  return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+  uint64_t start = current_time_ms();
+  uint64_t now = start;
+  for (;;) {
+    uint64_t remain = timeout - (now - start);
+    struct timespec ts;
+    ts.tv_sec = remain / 1000;
+    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
+    if (__atomic_load_n(&ev->state, __ATOMIC_RELAXED))
+      return 1;
+    now = current_time_ms();
+    if (now - start > timeout)
+      return 0;
+  }
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
+                            const void* addr, int addrsize)
+{
+  struct ifaddrmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
+  hdr.ifa_scope = RT_SCOPE_UNIVERSE;
+  hdr.ifa_index = if_nametoindex(dev);
+  netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
+  netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
+  return netlink_send(nlmsg, sock);
+}
+
+static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in_addr in_addr;
+  inet_pton(AF_INET, addr, &in_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
+  (void)err;
+}
+
+static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, addr, &in6_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
+  (void)err;
+}
+
+static void netlink_add_neigh(struct nlmsg* nlmsg, int sock, const char* name,
+                              const void* addr, int addrsize, const void* mac,
+                              int macsize)
+{
+  struct ndmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ndm_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ndm_ifindex = if_nametoindex(name);
+  hdr.ndm_state = NUD_PERMANENT;
+  netlink_init(nlmsg, RTM_NEWNEIGH, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, NDA_DST, addr, addrsize);
+  netlink_attr(nlmsg, NDA_LLADDR, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int tunfd = -1;
+static int tun_frags_enabled;
+
+#define TUN_IFACE "syz_tun"
+
+#define LOCAL_MAC 0xaaaaaaaaaaaa
+#define REMOTE_MAC 0xaaaaaaaaaabb
+
+#define LOCAL_IPV4 "172.20.20.170"
+#define REMOTE_IPV4 "172.20.20.187"
+
+#define LOCAL_IPV6 "fe80::aa"
+#define REMOTE_IPV6 "fe80::bb"
+
+#define IFF_NAPI 0x0010
+#define IFF_NAPI_FRAGS 0x0020
+
+static void initialize_tun(void)
+{
+  tunfd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
+  if (tunfd == -1) {
+    printf("tun: can't open /dev/net/tun: please enable CONFIG_TUN=y\n");
+    printf("otherwise fuzzing or reproducing might not work as intended\n");
+    return;
+  }
+  const int kTunFd = 240;
+  if (dup2(tunfd, kTunFd) < 0)
+    exit(1);
+  close(tunfd);
+  tunfd = kTunFd;
+  struct ifreq ifr;
+  memset(&ifr, 0, sizeof(ifr));
+  strncpy(ifr.ifr_name, TUN_IFACE, IFNAMSIZ);
+  ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_NAPI | IFF_NAPI_FRAGS;
+  if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) {
+    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+    if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0)
+      exit(1);
+  }
+  if (ioctl(tunfd, TUNGETIFF, (void*)&ifr) < 0)
+    exit(1);
+  tun_frags_enabled = (ifr.ifr_flags & IFF_NAPI_FRAGS) != 0;
+  char sysctl[64];
+  sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/accept_dad", TUN_IFACE);
+  write_file(sysctl, "0");
+  sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/router_solicitations", TUN_IFACE);
+  write_file(sysctl, "0");
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  netlink_add_addr4(&nlmsg, sock, TUN_IFACE, LOCAL_IPV4);
+  netlink_add_addr6(&nlmsg, sock, TUN_IFACE, LOCAL_IPV6);
+  uint64_t macaddr = REMOTE_MAC;
+  struct in_addr in_addr;
+  inet_pton(AF_INET, REMOTE_IPV4, &in_addr);
+  netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in_addr, sizeof(in_addr),
+                    &macaddr, ETH_ALEN);
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, REMOTE_IPV6, &in6_addr);
+  netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in6_addr, sizeof(in6_addr),
+                    &macaddr, ETH_ALEN);
+  macaddr = LOCAL_MAC;
+  netlink_device_change(&nlmsg, sock, TUN_IFACE, true, 0, &macaddr, ETH_ALEN,
+                        NULL);
+  close(sock);
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+static int read_tun(char* data, int size)
+{
+  if (tunfd < 0)
+    return -1;
+  int rv = read(tunfd, data, size);
+  if (rv < 0) {
+    if (errno == EAGAIN)
+      return -1;
+    if (errno == EBADFD)
+      return -1;
+    exit(1);
+  }
+  return rv;
+}
+
+static void flush_tun()
+{
+  char data[1000];
+  while (read_tun(&data[0], sizeof(data)) != -1) {
+  }
+}
+
+#define MAX_FDS 30
+
+#define XT_TABLE_SIZE 1536
+#define XT_MAX_ENTRIES 10
+
+struct xt_counters {
+  uint64_t pcnt, bcnt;
+};
+
+struct ipt_getinfo {
+  char name[32];
+  unsigned int valid_hooks;
+  unsigned int hook_entry[5];
+  unsigned int underflow[5];
+  unsigned int num_entries;
+  unsigned int size;
+};
+
+struct ipt_get_entries {
+  char name[32];
+  unsigned int size;
+  void* entrytable[XT_TABLE_SIZE / sizeof(void*)];
+};
+
+struct ipt_replace {
+  char name[32];
+  unsigned int valid_hooks;
+  unsigned int num_entries;
+  unsigned int size;
+  unsigned int hook_entry[5];
+  unsigned int underflow[5];
+  unsigned int num_counters;
+  struct xt_counters* counters;
+  char entrytable[XT_TABLE_SIZE];
+};
+
+struct ipt_table_desc {
+  const char* name;
+  struct ipt_getinfo info;
+  struct ipt_replace replace;
+};
+
+static struct ipt_table_desc ipv4_tables[] = {
+    {.name = "filter"}, {.name = "nat"},      {.name = "mangle"},
+    {.name = "raw"},    {.name = "security"},
+};
+
+static struct ipt_table_desc ipv6_tables[] = {
+    {.name = "filter"}, {.name = "nat"},      {.name = "mangle"},
+    {.name = "raw"},    {.name = "security"},
+};
+
+#define IPT_BASE_CTL 64
+#define IPT_SO_SET_REPLACE (IPT_BASE_CTL)
+#define IPT_SO_GET_INFO (IPT_BASE_CTL)
+#define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1)
+
+struct arpt_getinfo {
+  char name[32];
+  unsigned int valid_hooks;
+  unsigned int hook_entry[3];
+  unsigned int underflow[3];
+  unsigned int num_entries;
+  unsigned int size;
+};
+
+struct arpt_get_entries {
+  char name[32];
+  unsigned int size;
+  void* entrytable[XT_TABLE_SIZE / sizeof(void*)];
+};
+
+struct arpt_replace {
+  char name[32];
+  unsigned int valid_hooks;
+  unsigned int num_entries;
+  unsigned int size;
+  unsigned int hook_entry[3];
+  unsigned int underflow[3];
+  unsigned int num_counters;
+  struct xt_counters* counters;
+  char entrytable[XT_TABLE_SIZE];
+};
+
+struct arpt_table_desc {
+  const char* name;
+  struct arpt_getinfo info;
+  struct arpt_replace replace;
+};
+
+static struct arpt_table_desc arpt_tables[] = {
+    {.name = "filter"},
+};
+
+#define ARPT_BASE_CTL 96
+#define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL)
+#define ARPT_SO_GET_INFO (ARPT_BASE_CTL)
+#define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1)
+
+static void checkpoint_iptables(struct ipt_table_desc* tables, int num_tables,
+                                int family, int level)
+{
+  struct ipt_get_entries entries;
+  socklen_t optlen;
+  int fd, i;
+  fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < num_tables; i++) {
+    struct ipt_table_desc* table = &tables[i];
+    strcpy(table->info.name, table->name);
+    strcpy(table->replace.name, table->name);
+    optlen = sizeof(table->info);
+    if (getsockopt(fd, level, IPT_SO_GET_INFO, &table->info, &optlen)) {
+      switch (errno) {
+      case EPERM:
+      case ENOENT:
+      case ENOPROTOOPT:
+        continue;
+      }
+      exit(1);
+    }
+    if (table->info.size > sizeof(table->replace.entrytable))
+      exit(1);
+    if (table->info.num_entries > XT_MAX_ENTRIES)
+      exit(1);
+    memset(&entries, 0, sizeof(entries));
+    strcpy(entries.name, table->name);
+    entries.size = table->info.size;
+    optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
+    if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
+      exit(1);
+    table->replace.valid_hooks = table->info.valid_hooks;
+    table->replace.num_entries = table->info.num_entries;
+    table->replace.size = table->info.size;
+    memcpy(table->replace.hook_entry, table->info.hook_entry,
+           sizeof(table->replace.hook_entry));
+    memcpy(table->replace.underflow, table->info.underflow,
+           sizeof(table->replace.underflow));
+    memcpy(table->replace.entrytable, entries.entrytable, table->info.size);
+  }
+  close(fd);
+}
+
+static void reset_iptables(struct ipt_table_desc* tables, int num_tables,
+                           int family, int level)
+{
+  struct xt_counters counters[XT_MAX_ENTRIES];
+  struct ipt_get_entries entries;
+  struct ipt_getinfo info;
+  socklen_t optlen;
+  int fd, i;
+  fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < num_tables; i++) {
+    struct ipt_table_desc* table = &tables[i];
+    if (table->info.valid_hooks == 0)
+      continue;
+    memset(&info, 0, sizeof(info));
+    strcpy(info.name, table->name);
+    optlen = sizeof(info);
+    if (getsockopt(fd, level, IPT_SO_GET_INFO, &info, &optlen))
+      exit(1);
+    if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
+      memset(&entries, 0, sizeof(entries));
+      strcpy(entries.name, table->name);
+      entries.size = table->info.size;
+      optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
+      if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
+        exit(1);
+      if (memcmp(table->replace.entrytable, entries.entrytable,
+                 table->info.size) == 0)
+        continue;
+    }
+    table->replace.num_counters = info.num_entries;
+    table->replace.counters = counters;
+    optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) +
+             table->replace.size;
+    if (setsockopt(fd, level, IPT_SO_SET_REPLACE, &table->replace, optlen))
+      exit(1);
+  }
+  close(fd);
+}
+
+static void checkpoint_arptables(void)
+{
+  struct arpt_get_entries entries;
+  socklen_t optlen;
+  unsigned i;
+  int fd;
+  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < sizeof(arpt_tables) / sizeof(arpt_tables[0]); i++) {
+    struct arpt_table_desc* table = &arpt_tables[i];
+    strcpy(table->info.name, table->name);
+    strcpy(table->replace.name, table->name);
+    optlen = sizeof(table->info);
+    if (getsockopt(fd, SOL_IP, ARPT_SO_GET_INFO, &table->info, &optlen)) {
+      switch (errno) {
+      case EPERM:
+      case ENOENT:
+      case ENOPROTOOPT:
+        continue;
+      }
+      exit(1);
+    }
+    if (table->info.size > sizeof(table->replace.entrytable))
+      exit(1);
+    if (table->info.num_entries > XT_MAX_ENTRIES)
+      exit(1);
+    memset(&entries, 0, sizeof(entries));
+    strcpy(entries.name, table->name);
+    entries.size = table->info.size;
+    optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
+    if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
+      exit(1);
+    table->replace.valid_hooks = table->info.valid_hooks;
+    table->replace.num_entries = table->info.num_entries;
+    table->replace.size = table->info.size;
+    memcpy(table->replace.hook_entry, table->info.hook_entry,
+           sizeof(table->replace.hook_entry));
+    memcpy(table->replace.underflow, table->info.underflow,
+           sizeof(table->replace.underflow));
+    memcpy(table->replace.entrytable, entries.entrytable, table->info.size);
+  }
+  close(fd);
+}
+
+static void reset_arptables()
+{
+  struct xt_counters counters[XT_MAX_ENTRIES];
+  struct arpt_get_entries entries;
+  struct arpt_getinfo info;
+  socklen_t optlen;
+  unsigned i;
+  int fd;
+  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < sizeof(arpt_tables) / sizeof(arpt_tables[0]); i++) {
+    struct arpt_table_desc* table = &arpt_tables[i];
+    if (table->info.valid_hooks == 0)
+      continue;
+    memset(&info, 0, sizeof(info));
+    strcpy(info.name, table->name);
+    optlen = sizeof(info);
+    if (getsockopt(fd, SOL_IP, ARPT_SO_GET_INFO, &info, &optlen))
+      exit(1);
+    if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
+      memset(&entries, 0, sizeof(entries));
+      strcpy(entries.name, table->name);
+      entries.size = table->info.size;
+      optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
+      if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
+        exit(1);
+      if (memcmp(table->replace.entrytable, entries.entrytable,
+                 table->info.size) == 0)
+        continue;
+    } else {
+    }
+    table->replace.num_counters = info.num_entries;
+    table->replace.counters = counters;
+    optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) +
+             table->replace.size;
+    if (setsockopt(fd, SOL_IP, ARPT_SO_SET_REPLACE, &table->replace, optlen))
+      exit(1);
+  }
+  close(fd);
+}
+
+#define NF_BR_NUMHOOKS 6
+#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN 32
+#define EBT_BASE_CTL 128
+#define EBT_SO_SET_ENTRIES (EBT_BASE_CTL)
+#define EBT_SO_GET_INFO (EBT_BASE_CTL)
+#define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO + 1)
+#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES + 1)
+#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO + 1)
+
+struct ebt_replace {
+  char name[EBT_TABLE_MAXNAMELEN];
+  unsigned int valid_hooks;
+  unsigned int nentries;
+  unsigned int entries_size;
+  struct ebt_entries* hook_entry[NF_BR_NUMHOOKS];
+  unsigned int num_counters;
+  struct ebt_counter* counters;
+  char* entries;
+};
+
+struct ebt_entries {
+  unsigned int distinguisher;
+  char name[EBT_CHAIN_MAXNAMELEN];
+  unsigned int counter_offset;
+  int policy;
+  unsigned int nentries;
+  char data[0] __attribute__((aligned(__alignof__(struct ebt_replace))));
+};
+
+struct ebt_table_desc {
+  const char* name;
+  struct ebt_replace replace;
+  char entrytable[XT_TABLE_SIZE];
+};
+
+static struct ebt_table_desc ebt_tables[] = {
+    {.name = "filter"},
+    {.name = "nat"},
+    {.name = "broute"},
+};
+
+static void checkpoint_ebtables(void)
+{
+  socklen_t optlen;
+  unsigned i;
+  int fd;
+  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < sizeof(ebt_tables) / sizeof(ebt_tables[0]); i++) {
+    struct ebt_table_desc* table = &ebt_tables[i];
+    strcpy(table->replace.name, table->name);
+    optlen = sizeof(table->replace);
+    if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_INFO, &table->replace,
+                   &optlen)) {
+      switch (errno) {
+      case EPERM:
+      case ENOENT:
+      case ENOPROTOOPT:
+        continue;
+      }
+      exit(1);
+    }
+    if (table->replace.entries_size > sizeof(table->entrytable))
+      exit(1);
+    table->replace.num_counters = 0;
+    table->replace.entries = table->entrytable;
+    optlen = sizeof(table->replace) + table->replace.entries_size;
+    if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_ENTRIES, &table->replace,
+                   &optlen))
+      exit(1);
+  }
+  close(fd);
+}
+
+static void reset_ebtables()
+{
+  struct ebt_replace replace;
+  char entrytable[XT_TABLE_SIZE];
+  socklen_t optlen;
+  unsigned i, j, h;
+  int fd;
+  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < sizeof(ebt_tables) / sizeof(ebt_tables[0]); i++) {
+    struct ebt_table_desc* table = &ebt_tables[i];
+    if (table->replace.valid_hooks == 0)
+      continue;
+    memset(&replace, 0, sizeof(replace));
+    strcpy(replace.name, table->name);
+    optlen = sizeof(replace);
+    if (getsockopt(fd, SOL_IP, EBT_SO_GET_INFO, &replace, &optlen))
+      exit(1);
+    replace.num_counters = 0;
+    table->replace.entries = 0;
+    for (h = 0; h < NF_BR_NUMHOOKS; h++)
+      table->replace.hook_entry[h] = 0;
+    if (memcmp(&table->replace, &replace, sizeof(table->replace)) == 0) {
+      memset(&entrytable, 0, sizeof(entrytable));
+      replace.entries = entrytable;
+      optlen = sizeof(replace) + replace.entries_size;
+      if (getsockopt(fd, SOL_IP, EBT_SO_GET_ENTRIES, &replace, &optlen))
+        exit(1);
+      if (memcmp(table->entrytable, entrytable, replace.entries_size) == 0)
+        continue;
+    }
+    for (j = 0, h = 0; h < NF_BR_NUMHOOKS; h++) {
+      if (table->replace.valid_hooks & (1 << h)) {
+        table->replace.hook_entry[h] =
+            (struct ebt_entries*)table->entrytable + j;
+        j++;
+      }
+    }
+    table->replace.entries = table->entrytable;
+    optlen = sizeof(table->replace) + table->replace.entries_size;
+    if (setsockopt(fd, SOL_IP, EBT_SO_SET_ENTRIES, &table->replace, optlen))
+      exit(1);
+  }
+  close(fd);
+}
+
+static void checkpoint_net_namespace(void)
+{
+  checkpoint_ebtables();
+  checkpoint_arptables();
+  checkpoint_iptables(ipv4_tables, sizeof(ipv4_tables) / sizeof(ipv4_tables[0]),
+                      AF_INET, SOL_IP);
+  checkpoint_iptables(ipv6_tables, sizeof(ipv6_tables) / sizeof(ipv6_tables[0]),
+                      AF_INET6, SOL_IPV6);
+}
+
+static void reset_net_namespace(void)
+{
+  reset_ebtables();
+  reset_arptables();
+  reset_iptables(ipv4_tables, sizeof(ipv4_tables) / sizeof(ipv4_tables[0]),
+                 AF_INET, SOL_IP);
+  reset_iptables(ipv6_tables, sizeof(ipv6_tables) / sizeof(ipv6_tables[0]),
+                 AF_INET6, SOL_IPV6);
+}
+
+static void setup_cgroups()
+{
+  if (mkdir("/syzcgroup", 0777)) {
+  }
+  if (mkdir("/syzcgroup/unified", 0777)) {
+  }
+  if (mount("none", "/syzcgroup/unified", "cgroup2", 0, NULL)) {
+  }
+  if (chmod("/syzcgroup/unified", 0777)) {
+  }
+  write_file("/syzcgroup/unified/cgroup.subtree_control",
+             "+cpu +memory +io +pids +rdma");
+  if (mkdir("/syzcgroup/cpu", 0777)) {
+  }
+  if (mount("none", "/syzcgroup/cpu", "cgroup", 0,
+            "cpuset,cpuacct,perf_event,hugetlb")) {
+  }
+  write_file("/syzcgroup/cpu/cgroup.clone_children", "1");
+  if (chmod("/syzcgroup/cpu", 0777)) {
+  }
+  if (mkdir("/syzcgroup/net", 0777)) {
+  }
+  if (mount("none", "/syzcgroup/net", "cgroup", 0,
+            "net_cls,net_prio,devices,freezer")) {
+  }
+  if (chmod("/syzcgroup/net", 0777)) {
+  }
+}
+
+static void setup_cgroups_loop()
+{
+  int pid = getpid();
+  char file[128];
+  char cgroupdir[64];
+  snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/unified/syz%llu", procid);
+  if (mkdir(cgroupdir, 0777)) {
+  }
+  snprintf(file, sizeof(file), "%s/pids.max", cgroupdir);
+  write_file(file, "32");
+  snprintf(file, sizeof(file), "%s/memory.low", cgroupdir);
+  write_file(file, "%d", 298 << 20);
+  snprintf(file, sizeof(file), "%s/memory.high", cgroupdir);
+  write_file(file, "%d", 299 << 20);
+  snprintf(file, sizeof(file), "%s/memory.max", cgroupdir);
+  write_file(file, "%d", 300 << 20);
+  snprintf(file, sizeof(file), "%s/cgroup.procs", cgroupdir);
+  write_file(file, "%d", pid);
+  snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/cpu/syz%llu", procid);
+  if (mkdir(cgroupdir, 0777)) {
+  }
+  snprintf(file, sizeof(file), "%s/cgroup.procs", cgroupdir);
+  write_file(file, "%d", pid);
+  snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/net/syz%llu", procid);
+  if (mkdir(cgroupdir, 0777)) {
+  }
+  snprintf(file, sizeof(file), "%s/cgroup.procs", cgroupdir);
+  write_file(file, "%d", pid);
+}
+
+static void setup_cgroups_test()
+{
+  char cgroupdir[64];
+  snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/unified/syz%llu", procid);
+  if (symlink(cgroupdir, "./cgroup")) {
+  }
+  snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/cpu/syz%llu", procid);
+  if (symlink(cgroupdir, "./cgroup.cpu")) {
+  }
+  snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/net/syz%llu", procid);
+  if (symlink(cgroupdir, "./cgroup.net")) {
+  }
+}
+
+static void setup_common()
+{
+  if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
+  }
+  setup_cgroups();
+}
+
+static void loop();
+
+static void sandbox_common()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setsid();
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  if (dup2(netns, kInitNetNsFd) < 0)
+    exit(1);
+  close(netns);
+  struct rlimit rlim;
+  rlim.rlim_cur = rlim.rlim_max = (200 << 20);
+  setrlimit(RLIMIT_AS, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 32 << 20;
+  setrlimit(RLIMIT_MEMLOCK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 136 << 20;
+  setrlimit(RLIMIT_FSIZE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+  setrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 0;
+  setrlimit(RLIMIT_CORE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 256;
+  setrlimit(RLIMIT_NOFILE, &rlim);
+  if (unshare(CLONE_NEWNS)) {
+  }
+  if (unshare(CLONE_NEWIPC)) {
+  }
+  if (unshare(0x02000000)) {
+  }
+  if (unshare(CLONE_NEWUTS)) {
+  }
+  if (unshare(CLONE_SYSVSEM)) {
+  }
+  typedef struct {
+    const char* name;
+    const char* value;
+  } sysctl_t;
+  static const sysctl_t sysctls[] = {
+      {"/proc/sys/kernel/shmmax", "16777216"},
+      {"/proc/sys/kernel/shmall", "536870912"},
+      {"/proc/sys/kernel/shmmni", "1024"},
+      {"/proc/sys/kernel/msgmax", "8192"},
+      {"/proc/sys/kernel/msgmni", "1024"},
+      {"/proc/sys/kernel/msgmnb", "1024"},
+      {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
+    write_file(sysctls[i].name, sysctls[i].value);
+}
+
+int wait_for_loop(int pid)
+{
+  if (pid < 0)
+    exit(1);
+  int status = 0;
+  while (waitpid(-1, &status, __WALL) != pid) {
+  }
+  return WEXITSTATUS(status);
+}
+
+static void drop_caps(void)
+{
+  struct __user_cap_header_struct cap_hdr = {};
+  struct __user_cap_data_struct cap_data[2] = {};
+  cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
+  cap_hdr.pid = getpid();
+  if (syscall(SYS_capget, &cap_hdr, &cap_data))
+    exit(1);
+  const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
+  cap_data[0].effective &= ~drop;
+  cap_data[0].permitted &= ~drop;
+  cap_data[0].inheritable &= ~drop;
+  if (syscall(SYS_capset, &cap_hdr, &cap_data))
+    exit(1);
+}
+
+static int do_sandbox_none(void)
+{
+  if (unshare(CLONE_NEWPID)) {
+  }
+  int pid = fork();
+  if (pid != 0)
+    return wait_for_loop(pid);
+  setup_common();
+  sandbox_common();
+  drop_caps();
+  if (unshare(CLONE_NEWNET)) {
+  }
+  initialize_devlink_pci();
+  initialize_tun();
+  loop();
+  exit(1);
+}
+
+#define FS_IOC_SETFLAGS _IOW('f', 2, long)
+static void remove_dir(const char* dir)
+{
+  DIR* dp;
+  struct dirent* ep;
+  int iter = 0;
+retry:
+  while (umount2(dir, MNT_DETACH) == 0) {
+  }
+  dp = opendir(dir);
+  if (dp == NULL) {
+    if (errno == EMFILE) {
+      exit(1);
+    }
+    exit(1);
+  }
+  while ((ep = readdir(dp))) {
+    if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+      continue;
+    char filename[FILENAME_MAX];
+    snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
+    while (umount2(filename, MNT_DETACH) == 0) {
+    }
+    struct stat st;
+    if (lstat(filename, &st))
+      exit(1);
+    if (S_ISDIR(st.st_mode)) {
+      remove_dir(filename);
+      continue;
+    }
+    int i;
+    for (i = 0;; i++) {
+      if (unlink(filename) == 0)
+        break;
+      if (errno == EPERM) {
+        int fd = open(filename, O_RDONLY);
+        if (fd != -1) {
+          long flags = 0;
+          if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) {
+          }
+          close(fd);
+          continue;
+        }
+      }
+      if (errno == EROFS) {
+        break;
+      }
+      if (errno != EBUSY || i > 100)
+        exit(1);
+      if (umount2(filename, MNT_DETACH))
+        exit(1);
+    }
+  }
+  closedir(dp);
+  int i;
+  for (i = 0;; i++) {
+    if (rmdir(dir) == 0)
+      break;
+    if (i < 100) {
+      if (errno == EPERM) {
+        int fd = open(dir, O_RDONLY);
+        if (fd != -1) {
+          long flags = 0;
+          if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) {
+          }
+          close(fd);
+          continue;
+        }
+      }
+      if (errno == EROFS) {
+        break;
+      }
+      if (errno == EBUSY) {
+        if (umount2(dir, MNT_DETACH))
+          exit(1);
+        continue;
+      }
+      if (errno == ENOTEMPTY) {
+        if (iter < 100) {
+          iter++;
+          goto retry;
+        }
+      }
+    }
+    exit(1);
+  }
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void setup_loop()
+{
+  setup_cgroups_loop();
+  checkpoint_net_namespace();
+}
+
+static void reset_loop()
+{
+  reset_net_namespace();
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setup_cgroups_test();
+  write_file("/proc/self/oom_score_adj", "1000");
+  flush_tun();
+}
+
+static void close_fds()
+{
+  int fd;
+  for (fd = 3; fd < MAX_FDS; fd++)
+    close(fd);
+}
+
+struct thread_t {
+  int created, call;
+  event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+  struct thread_t* th = (struct thread_t*)arg;
+  for (;;) {
+    event_wait(&th->ready);
+    event_reset(&th->ready);
+    execute_call(th->call);
+    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+    event_set(&th->done);
+  }
+  return 0;
+}
+
+static void execute_one(void)
+{
+  int i, call, thread;
+  for (call = 0; call < 25; call++) {
+    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+         thread++) {
+      struct thread_t* th = &threads[thread];
+      if (!th->created) {
+        th->created = 1;
+        event_init(&th->ready);
+        event_init(&th->done);
+        event_set(&th->done);
+        thread_start(thr, th);
+      }
+      if (!event_isset(&th->done))
+        continue;
+      event_reset(&th->done);
+      th->call = call;
+      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+      event_set(&th->ready);
+      event_timedwait(&th->done, 45);
+      break;
+    }
+  }
+  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+    sleep_ms(1);
+  close_fds();
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  setup_loop();
+  int iter;
+  for (iter = 0;; iter++) {
+    char cwdbuf[32];
+    sprintf(cwdbuf, "./%d", iter);
+    if (mkdir(cwdbuf, 0777))
+      exit(1);
+    reset_loop();
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      if (chdir(cwdbuf))
+        exit(1);
+      setup_test();
+      execute_one();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+    remove_dir(cwdbuf);
+  }
+}
+
+uint64_t r[10] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+                  0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+                  0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+                  0xffffffffffffffff};
+
+void execute_call(int call)
+{
+  intptr_t res;
+  switch (call) {
+  case 0:
+    memcpy((void*)0x20000140, "./bus\000", 6);
+    res = syscall(__NR_open, 0x20000140ul, 0x141042ul, 0ul);
+    if (res != -1)
+      r[0] = res;
+    break;
+  case 1:
+    res = syscall(__NR_socket, 0xaul, 1ul, 0ul);
+    if (res != -1)
+      r[1] = res;
+    break;
+  case 2:
+    res = syscall(__NR_dup2, r[1], r[1]);
+    if (res != -1)
+      r[2] = res;
+    break;
+  case 3:
+    syscall(__NR_setsockopt, r[2], 0ul, 0x40ul, 0ul, 0ul);
+    break;
+  case 4:
+    res = syscall(__NR_accept4, r[2], 0ul, 0ul, 0x80000ul);
+    if (res != -1)
+      r[3] = res;
+    break;
+  case 5:
+    res = syscall(__NR_socket, 0xaul, 1ul, 0ul);
+    if (res != -1)
+      r[4] = res;
+    break;
+  case 6:
+    syscall(__NR_ioctl, r[0], 0x8904ul, 0ul);
+    break;
+  case 7:
+    *(uint32_t*)0x20000440 = 0;
+    *(uint32_t*)0x20000444 = 0x70;
+    *(uint8_t*)0x20000448 = 0;
+    *(uint8_t*)0x20000449 = 0xf8;
+    *(uint8_t*)0x2000044a = 0xf9;
+    *(uint8_t*)0x2000044b = 3;
+    *(uint32_t*)0x2000044c = 0;
+    *(uint64_t*)0x20000450 = 3;
+    *(uint64_t*)0x20000458 = 0x8eae8d1ce7182c60;
+    *(uint64_t*)0x20000460 = 2;
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 0, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 1, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 2, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 3, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 4, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 5, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 6, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 7, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 8, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 9, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 10, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 11, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 12, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 13, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 14, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 15, 2);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 17, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 18, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 19, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 20, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 21, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 22, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 23, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 1, 24, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 25, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 26, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 27, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 28, 1);
+    STORE_BY_BITMASK(uint64_t, , 0x20000468, 0, 29, 35);
+    *(uint32_t*)0x20000470 = 0x29;
+    *(uint32_t*)0x20000474 = 4;
+    *(uint64_t*)0x20000478 = 0x1000;
+    *(uint64_t*)0x20000480 = 5;
+    *(uint64_t*)0x20000488 = 1;
+    *(uint64_t*)0x20000490 = 0x80000001;
+    *(uint32_t*)0x20000498 = 5;
+    *(uint32_t*)0x2000049c = 0;
+    *(uint64_t*)0x200004a0 = 0x80;
+    *(uint32_t*)0x200004a8 = 0xfffffffe;
+    *(uint16_t*)0x200004ac = 5;
+    *(uint16_t*)0x200004ae = 0;
+    syscall(__NR_perf_event_open, 0x20000440ul, 0, 0xeul, r[2], 0xbul);
+    break;
+  case 8:
+    res = syscall(__NR_dup2, r[4], r[4]);
+    if (res != -1)
+      r[5] = res;
+    break;
+  case 9:
+    syscall(__NR_fcntl, r[4], 0x10ul, 0ul);
+    break;
+  case 10:
+    syscall(__NR_fcntl, r[3], 0xful, 0ul);
+    break;
+  case 11:
+    memcpy((void*)0x20000300, "./file0\000", 8);
+    res = syscall(__NR_creat, 0x20000300ul, 0ul);
+    if (res != -1)
+      r[6] = res;
+    break;
+  case 12:
+    *(uint32_t*)0x20000280 = 1;
+    *(uint8_t*)0x20000284 = 0x7b;
+    *(uint16_t*)0x20000285 = 0;
+    syscall(__NR_write, r[6], 0x20000280ul, 0xff7ful);
+    break;
+  case 13:
+    memcpy((void*)0x20000700, "./bus\000", 6);
+    res = syscall(__NR_creat, 0x20000700ul, 0ul);
+    if (res != -1)
+      r[7] = res;
+    break;
+  case 14:
+    syscall(__NR_ftruncate, -1, 0x2081fcul);
+    break;
+  case 15:
+    memcpy((void*)0x20000240, "./file0\000", 8);
+    res = syscall(__NR_open, 0x20000240ul, 0x20141042ul, 0ul);
+    if (res != -1)
+      r[8] = res;
+    break;
+  case 16:
+    syscall(__NR_ioctl, r[0], 0x227dul, 0ul);
+    break;
+  case 17:
+    syscall(__NR_ioctl, -1, 0xc014563bul, 0ul);
+    break;
+  case 18:
+    syscall(__NR_mmap, 0x20003000ul, 0x3000ul, 0x800002ul, 0x11ul, r[8], 0);
+    break;
+  case 19:
+    syscall(__NR_fcntl, r[5], 4ul, 0x22c00ul);
+    break;
+  case 20:
+    memcpy((void*)0x20000200, "threaded\000", 9);
+    syscall(__NR_write, r[7], 0x20000200ul, 0xf642e7eul);
+    break;
+  case 21:
+    *(uint32_t*)0x20000200 = 0;
+    *(uint32_t*)0x20000204 = r[6];
+    *(uint64_t*)0x20000208 = 0;
+    *(uint64_t*)0x20000210 = 0;
+    *(uint64_t*)0x20000218 = 0;
+    *(uint64_t*)0x20000220 = 0;
+    syscall(__NR_ioctl, r[0], 0xc028660ful, 0x20000200ul);
+    break;
+  case 22:
+    res = syscall(__NR_socket, 0x2cul, 3ul, 0ul);
+    if (res != -1)
+      r[9] = res;
+    break;
+  case 23:
+    *(uint64_t*)0x200000c0 = 0x20000000;
+    *(uint64_t*)0x200000c8 = 0x20000;
+    *(uint32_t*)0x200000d0 = 0x1000;
+    *(uint32_t*)0x200000d4 = 0;
+    *(uint32_t*)0x200000d8 = 0;
+    syscall(__NR_setsockopt, r[9], 0x11bul, 4ul, 0x200000c0ul, 0x18ul);
+    break;
+  case 24:
+    syscall(__NR_bind, -1, 0ul, 0ul);
+    break;
+  }
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  for (procid = 0; procid < 4; procid++) {
+    if (fork() == 0) {
+      use_temporary_dir();
+      do_sandbox_none();
+    }
+  }
+  sleep(1000000);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/01e50119f4515ff34aca0aff7b80c67196cb5c43.c b/syzkaller-repros/linux/01e50119f4515ff34aca0aff7b80c67196cb5c43.c
new file mode 100644
index 0000000..9f904f7
--- /dev/null
+++ b/syzkaller-repros/linux/01e50119f4515ff34aca0aff7b80c67196cb5c43.c
@@ -0,0 +1,117 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <endian.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
+#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
+  *(type*)(addr) =                                                             \
+      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
+            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[0] = res;
+  *(uint64_t*)0x20000300 = 0;
+  *(uint32_t*)0x20000308 = 0;
+  *(uint64_t*)0x20000310 = 0x200002c0;
+  *(uint64_t*)0x200002c0 = 0x20000000;
+  *(uint32_t*)0x20000000 = 0x64;
+  *(uint8_t*)0x20000004 = 2;
+  *(uint8_t*)0x20000005 = 6;
+  *(uint16_t*)0x20000006 = 1;
+  *(uint32_t*)0x20000008 = 0;
+  *(uint32_t*)0x2000000c = 0;
+  *(uint8_t*)0x20000010 = 0;
+  *(uint8_t*)0x20000011 = 0;
+  *(uint16_t*)0x20000012 = htobe16(0);
+  *(uint16_t*)0x20000014 = 0xe;
+  *(uint16_t*)0x20000016 = 3;
+  memcpy((void*)0x20000018, "bitmap:ip\000", 10);
+  *(uint16_t*)0x20000024 = 9;
+  *(uint16_t*)0x20000026 = 2;
+  memcpy((void*)0x20000028, "syz1\000", 5);
+  *(uint16_t*)0x20000030 = 0x1c;
+  STORE_BY_BITMASK(uint16_t, , 0x20000032, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000033, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000033, 1, 7, 1);
+  *(uint16_t*)0x20000034 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x20000036, 1, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000037, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000037, 1, 7, 1);
+  *(uint16_t*)0x20000038 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x2000003a, 1, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000003b, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000003b, 0, 7, 1);
+  *(uint32_t*)0x2000003c = htobe32(0);
+  *(uint16_t*)0x20000040 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x20000042, 2, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000043, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000043, 1, 7, 1);
+  *(uint16_t*)0x20000044 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x20000046, 1, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000047, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000047, 0, 7, 1);
+  *(uint32_t*)0x20000048 = htobe32(0);
+  *(uint16_t*)0x2000004c = 5;
+  *(uint16_t*)0x2000004e = 1;
+  *(uint8_t*)0x20000050 = 7;
+  *(uint16_t*)0x20000054 = 5;
+  *(uint16_t*)0x20000056 = 4;
+  *(uint8_t*)0x20000058 = 0;
+  *(uint16_t*)0x2000005c = 5;
+  *(uint16_t*)0x2000005e = 5;
+  *(uint8_t*)0x20000060 = 2;
+  *(uint64_t*)0x200002c8 = 0x64;
+  *(uint64_t*)0x20000318 = 1;
+  *(uint64_t*)0x20000320 = 0;
+  *(uint64_t*)0x20000328 = 0;
+  *(uint32_t*)0x20000330 = 0;
+  syscall(__NR_sendmsg, r[0], 0x20000300ul, 0ul);
+  syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[1] = res;
+  *(uint64_t*)0x200003c0 = 0;
+  *(uint32_t*)0x200003c8 = 0;
+  *(uint64_t*)0x200003d0 = 0x20000380;
+  *(uint64_t*)0x20000380 = 0x20000180;
+  *(uint32_t*)0x20000180 = 0x24;
+  *(uint8_t*)0x20000184 = 7;
+  *(uint8_t*)0x20000185 = 6;
+  *(uint16_t*)0x20000186 = 0x301;
+  *(uint32_t*)0x20000188 = 0;
+  *(uint32_t*)0x2000018c = 0;
+  *(uint8_t*)0x20000190 = 1;
+  *(uint8_t*)0x20000191 = 0;
+  *(uint16_t*)0x20000192 = htobe16(0);
+  *(uint16_t*)0x20000194 = 5;
+  *(uint16_t*)0x20000196 = 1;
+  *(uint8_t*)0x20000198 = 7;
+  *(uint16_t*)0x2000019c = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x2000019e, 6, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000019f, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000019f, 0, 7, 1);
+  *(uint32_t*)0x200001a0 = htobe32(8);
+  *(uint64_t*)0x20000388 = 0x24;
+  *(uint64_t*)0x200003d8 = 1;
+  *(uint64_t*)0x200003e0 = 0;
+  *(uint64_t*)0x200003e8 = 0;
+  *(uint32_t*)0x200003f0 = 0x11;
+  syscall(__NR_sendmsg, r[1], 0x200003c0ul, 0x10ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/03ee30ae11dfd0ddd062af26566c34a8c853698d.c b/syzkaller-repros/linux/03ee30ae11dfd0ddd062af26566c34a8c853698d.c
new file mode 100644
index 0000000..b843d74
--- /dev/null
+++ b/syzkaller-repros/linux/03ee30ae11dfd0ddd062af26566c34a8c853698d.c
@@ -0,0 +1,824 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <sched.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/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/uio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <linux/capability.h>
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/if_tun.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/tcp.h>
+#include <linux/veth.h>
+
+unsigned long long procid;
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static void netlink_nest(struct nlmsg* nlmsg, int typ)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_type = typ;
+  nlmsg->pos += sizeof(*attr);
+  nlmsg->nested[nlmsg->nesting++] = attr;
+}
+
+static void netlink_done(struct nlmsg* nlmsg)
+{
+  struct nlattr* attr = nlmsg->nested[--nlmsg->nesting];
+  attr->nla_len = nlmsg->pos - (char*)attr;
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_add_device_impl(struct nlmsg* nlmsg, const char* type,
+                                    const char* name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  if (name)
+    netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name));
+  netlink_nest(nlmsg, IFLA_LINKINFO);
+  netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type));
+}
+
+static void netlink_add_device(struct nlmsg* nlmsg, int sock, const char* type,
+                               const char* name)
+{
+  netlink_add_device_impl(nlmsg, type, name);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_veth(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* peer)
+{
+  netlink_add_device_impl(nlmsg, "veth", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_nest(nlmsg, VETH_INFO_PEER);
+  nlmsg->pos += sizeof(struct ifinfomsg);
+  netlink_attr(nlmsg, IFLA_IFNAME, peer, strlen(peer));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_hsr(struct nlmsg* nlmsg, int sock, const char* name,
+                            const char* slave1, const char* slave2)
+{
+  netlink_add_device_impl(nlmsg, "hsr", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  int ifindex1 = if_nametoindex(slave1);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE1, &ifindex1, sizeof(ifindex1));
+  int ifindex2 = if_nametoindex(slave2);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE2, &ifindex2, sizeof(ifindex2));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
+                            const void* addr, int addrsize)
+{
+  struct ifaddrmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
+  hdr.ifa_scope = RT_SCOPE_UNIVERSE;
+  hdr.ifa_index = if_nametoindex(dev);
+  netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
+  netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
+  return netlink_send(nlmsg, sock);
+}
+
+static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in_addr in_addr;
+  inet_pton(AF_INET, addr, &in_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
+  (void)err;
+}
+
+static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, addr, &in6_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
+  (void)err;
+}
+
+static void netlink_add_neigh(struct nlmsg* nlmsg, int sock, const char* name,
+                              const void* addr, int addrsize, const void* mac,
+                              int macsize)
+{
+  struct ndmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ndm_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ndm_ifindex = if_nametoindex(name);
+  hdr.ndm_state = NUD_PERMANENT;
+  netlink_init(nlmsg, RTM_NEWNEIGH, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, NDA_DST, addr, addrsize);
+  netlink_attr(nlmsg, NDA_LLADDR, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int tunfd = -1;
+static int tun_frags_enabled;
+
+#define TUN_IFACE "syz_tun"
+
+#define LOCAL_MAC 0xaaaaaaaaaaaa
+#define REMOTE_MAC 0xaaaaaaaaaabb
+
+#define LOCAL_IPV4 "172.20.20.170"
+#define REMOTE_IPV4 "172.20.20.187"
+
+#define LOCAL_IPV6 "fe80::aa"
+#define REMOTE_IPV6 "fe80::bb"
+
+#define IFF_NAPI 0x0010
+#define IFF_NAPI_FRAGS 0x0020
+
+static void initialize_tun(void)
+{
+  tunfd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
+  if (tunfd == -1) {
+    printf("tun: can't open /dev/net/tun: please enable CONFIG_TUN=y\n");
+    printf("otherwise fuzzing or reproducing might not work as intended\n");
+    return;
+  }
+  const int kTunFd = 240;
+  if (dup2(tunfd, kTunFd) < 0)
+    exit(1);
+  close(tunfd);
+  tunfd = kTunFd;
+  struct ifreq ifr;
+  memset(&ifr, 0, sizeof(ifr));
+  strncpy(ifr.ifr_name, TUN_IFACE, IFNAMSIZ);
+  ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_NAPI | IFF_NAPI_FRAGS;
+  if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) {
+    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+    if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0)
+      exit(1);
+  }
+  if (ioctl(tunfd, TUNGETIFF, (void*)&ifr) < 0)
+    exit(1);
+  tun_frags_enabled = (ifr.ifr_flags & IFF_NAPI_FRAGS) != 0;
+  char sysctl[64];
+  sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/accept_dad", TUN_IFACE);
+  write_file(sysctl, "0");
+  sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/router_solicitations", TUN_IFACE);
+  write_file(sysctl, "0");
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  netlink_add_addr4(&nlmsg, sock, TUN_IFACE, LOCAL_IPV4);
+  netlink_add_addr6(&nlmsg, sock, TUN_IFACE, LOCAL_IPV6);
+  uint64_t macaddr = REMOTE_MAC;
+  struct in_addr in_addr;
+  inet_pton(AF_INET, REMOTE_IPV4, &in_addr);
+  netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in_addr, sizeof(in_addr),
+                    &macaddr, ETH_ALEN);
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, REMOTE_IPV6, &in6_addr);
+  netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in6_addr, sizeof(in6_addr),
+                    &macaddr, ETH_ALEN);
+  macaddr = LOCAL_MAC;
+  netlink_device_change(&nlmsg, sock, TUN_IFACE, true, 0, &macaddr, ETH_ALEN,
+                        NULL);
+  close(sock);
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+#define DEV_IPV4 "172.20.20.%d"
+#define DEV_IPV6 "fe80::%02x"
+#define DEV_MAC 0x00aaaaaaaaaa
+
+static void netdevsim_add(unsigned int addr, unsigned int port_count)
+{
+  char buf[16];
+  sprintf(buf, "%u %u", addr, port_count);
+  if (write_file("/sys/bus/netdevsim/new_device", buf)) {
+    snprintf(buf, sizeof(buf), "netdevsim%d", addr);
+    initialize_devlink_ports("netdevsim", buf, "netdevsim");
+  }
+}
+static void initialize_netdevices(void)
+{
+  char netdevsim[16];
+  sprintf(netdevsim, "netdevsim%d", (int)procid);
+  struct {
+    const char* type;
+    const char* dev;
+  } devtypes[] = {
+      {"ip6gretap", "ip6gretap0"}, {"bridge", "bridge0"},
+      {"vcan", "vcan0"},           {"bond", "bond0"},
+      {"team", "team0"},           {"dummy", "dummy0"},
+      {"nlmon", "nlmon0"},         {"caif", "caif0"},
+      {"batadv", "batadv0"},       {"vxcan", "vxcan1"},
+      {"netdevsim", netdevsim},    {"veth", 0},
+  };
+  const char* devmasters[] = {"bridge", "bond", "team"};
+  struct {
+    const char* name;
+    int macsize;
+    bool noipv6;
+  } devices[] = {
+      {"lo", ETH_ALEN},
+      {"sit0", 0},
+      {"bridge0", ETH_ALEN},
+      {"vcan0", 0, true},
+      {"tunl0", 0},
+      {"gre0", 0},
+      {"gretap0", ETH_ALEN},
+      {"ip_vti0", 0},
+      {"ip6_vti0", 0},
+      {"ip6tnl0", 0},
+      {"ip6gre0", 0},
+      {"ip6gretap0", ETH_ALEN},
+      {"erspan0", ETH_ALEN},
+      {"bond0", ETH_ALEN},
+      {"veth0", ETH_ALEN},
+      {"veth1", ETH_ALEN},
+      {"team0", ETH_ALEN},
+      {"veth0_to_bridge", ETH_ALEN},
+      {"veth1_to_bridge", ETH_ALEN},
+      {"veth0_to_bond", ETH_ALEN},
+      {"veth1_to_bond", ETH_ALEN},
+      {"veth0_to_team", ETH_ALEN},
+      {"veth1_to_team", ETH_ALEN},
+      {"veth0_to_hsr", ETH_ALEN},
+      {"veth1_to_hsr", ETH_ALEN},
+      {"hsr0", 0},
+      {"dummy0", ETH_ALEN},
+      {"nlmon0", 0},
+      {"vxcan0", 0, true},
+      {"vxcan1", 0, true},
+      {"caif0", ETH_ALEN},
+      {"batadv0", ETH_ALEN},
+      {netdevsim, ETH_ALEN},
+  };
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++)
+    netlink_add_device(&nlmsg, sock, devtypes[i].type, devtypes[i].dev);
+  for (i = 0; i < sizeof(devmasters) / (sizeof(devmasters[0])); i++) {
+    char master[32], slave0[32], veth0[32], slave1[32], veth1[32];
+    sprintf(slave0, "%s_slave_0", devmasters[i]);
+    sprintf(veth0, "veth0_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave0, veth0);
+    sprintf(slave1, "%s_slave_1", devmasters[i]);
+    sprintf(veth1, "veth1_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave1, veth1);
+    sprintf(master, "%s0", devmasters[i]);
+    netlink_device_change(&nlmsg, sock, slave0, false, master, 0, 0, NULL);
+    netlink_device_change(&nlmsg, sock, slave1, false, master, 0, 0, NULL);
+  }
+  netlink_device_change(&nlmsg, sock, "bridge_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "bridge_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_0", "veth0_to_hsr");
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_1", "veth1_to_hsr");
+  netlink_add_hsr(&nlmsg, sock, "hsr0", "hsr_slave_0", "hsr_slave_1");
+  netlink_device_change(&nlmsg, sock, "hsr_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "hsr_slave_1", true, 0, 0, 0, NULL);
+  netdevsim_add((int)procid, 4);
+  for (i = 0; i < sizeof(devices) / (sizeof(devices[0])); i++) {
+    char addr[32];
+    sprintf(addr, DEV_IPV4, i + 10);
+    netlink_add_addr4(&nlmsg, sock, devices[i].name, addr);
+    if (!devices[i].noipv6) {
+      sprintf(addr, DEV_IPV6, i + 10);
+      netlink_add_addr6(&nlmsg, sock, devices[i].name, addr);
+    }
+    uint64_t macaddr = DEV_MAC + ((i + 10ull) << 40);
+    netlink_device_change(&nlmsg, sock, devices[i].name, true, 0, &macaddr,
+                          devices[i].macsize, NULL);
+  }
+  close(sock);
+}
+static void initialize_netdevices_init(void)
+{
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  struct {
+    const char* type;
+    int macsize;
+    bool noipv6;
+    bool noup;
+  } devtypes[] = {
+      {"nr", 7, true},
+      {"rose", 5, true, true},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++) {
+    char dev[32], addr[32];
+    sprintf(dev, "%s%d", devtypes[i].type, (int)procid);
+    sprintf(addr, "172.30.%d.%d", i, (int)procid + 1);
+    netlink_add_addr4(&nlmsg, sock, dev, addr);
+    if (!devtypes[i].noipv6) {
+      sprintf(addr, "fe88::%02x:%02x", i, (int)procid + 1);
+      netlink_add_addr6(&nlmsg, sock, dev, addr);
+    }
+    int macsize = devtypes[i].macsize;
+    uint64_t macaddr = 0xbbbbbb +
+                       ((unsigned long long)i << (8 * (macsize - 2))) +
+                       (procid << (8 * (macsize - 1)));
+    netlink_device_change(&nlmsg, sock, dev, !devtypes[i].noup, 0, &macaddr,
+                          macsize, NULL);
+  }
+  close(sock);
+}
+
+#define MAX_FDS 30
+
+static long syz_init_net_socket(volatile long domain, volatile long type,
+                                volatile long proto)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    return netns;
+  if (setns(kInitNetNsFd, 0))
+    return -1;
+  int sock = syscall(__NR_socket, domain, type, proto);
+  int err = errno;
+  if (setns(netns, 0))
+    exit(1);
+  close(netns);
+  errno = err;
+  return sock;
+}
+
+static void setup_common()
+{
+  if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
+  }
+}
+
+static void loop();
+
+static void sandbox_common()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setsid();
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  if (dup2(netns, kInitNetNsFd) < 0)
+    exit(1);
+  close(netns);
+  struct rlimit rlim;
+  rlim.rlim_cur = rlim.rlim_max = (200 << 20);
+  setrlimit(RLIMIT_AS, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 32 << 20;
+  setrlimit(RLIMIT_MEMLOCK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 136 << 20;
+  setrlimit(RLIMIT_FSIZE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+  setrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 0;
+  setrlimit(RLIMIT_CORE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 256;
+  setrlimit(RLIMIT_NOFILE, &rlim);
+  if (unshare(CLONE_NEWNS)) {
+  }
+  if (unshare(CLONE_NEWIPC)) {
+  }
+  if (unshare(0x02000000)) {
+  }
+  if (unshare(CLONE_NEWUTS)) {
+  }
+  if (unshare(CLONE_SYSVSEM)) {
+  }
+  typedef struct {
+    const char* name;
+    const char* value;
+  } sysctl_t;
+  static const sysctl_t sysctls[] = {
+      {"/proc/sys/kernel/shmmax", "16777216"},
+      {"/proc/sys/kernel/shmall", "536870912"},
+      {"/proc/sys/kernel/shmmni", "1024"},
+      {"/proc/sys/kernel/msgmax", "8192"},
+      {"/proc/sys/kernel/msgmni", "1024"},
+      {"/proc/sys/kernel/msgmnb", "1024"},
+      {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
+    write_file(sysctls[i].name, sysctls[i].value);
+}
+
+int wait_for_loop(int pid)
+{
+  if (pid < 0)
+    exit(1);
+  int status = 0;
+  while (waitpid(-1, &status, __WALL) != pid) {
+  }
+  return WEXITSTATUS(status);
+}
+
+static void drop_caps(void)
+{
+  struct __user_cap_header_struct cap_hdr = {};
+  struct __user_cap_data_struct cap_data[2] = {};
+  cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
+  cap_hdr.pid = getpid();
+  if (syscall(SYS_capget, &cap_hdr, &cap_data))
+    exit(1);
+  const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
+  cap_data[0].effective &= ~drop;
+  cap_data[0].permitted &= ~drop;
+  cap_data[0].inheritable &= ~drop;
+  if (syscall(SYS_capset, &cap_hdr, &cap_data))
+    exit(1);
+}
+
+static int do_sandbox_none(void)
+{
+  if (unshare(CLONE_NEWPID)) {
+  }
+  int pid = fork();
+  if (pid != 0)
+    return wait_for_loop(pid);
+  setup_common();
+  sandbox_common();
+  drop_caps();
+  initialize_netdevices_init();
+  if (unshare(CLONE_NEWNET)) {
+  }
+  initialize_devlink_pci();
+  initialize_tun();
+  initialize_netdevices();
+  loop();
+  exit(1);
+}
+
+static void close_fds()
+{
+  int fd;
+  for (fd = 3; fd < MAX_FDS; fd++)
+    close(fd);
+}
+
+static void setup_binfmt_misc()
+{
+  if (mount(0, "/proc/sys/fs/binfmt_misc", "binfmt_misc", 0, 0)) {
+  }
+  write_file("/proc/sys/fs/binfmt_misc/register", ":syz0:M:0:\x01::./file0:");
+  write_file("/proc/sys/fs/binfmt_misc/register",
+             ":syz1:M:1:\x02::./file0:POC");
+}
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+void loop(void)
+{
+  intptr_t res = 0;
+  res = syz_init_net_socket(9, 5, 0);
+  if (res != -1)
+    r[0] = res;
+  memcpy(
+      (void*)0x20000180,
+      "eth0\000\000\000\000\000\000\000\000\000\000\r\273?\211\000\000\000 "
+      "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+      "\001\000\000\000\000\000\000\000\032\000\000\000\000\000\000\000\000\000"
+      "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+      "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+      "\000\000\000\000\000\000\000\000\000\000\000\000$"
+      "\000\000\000\000\000\000\000\000\000\000\377\027\000\000\000\000\000\000"
+      "\000\000\000\002\000\000S0\000\000\000\000\000\000\000\000\000\000_/"
+      "0\304\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000"
+      "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+      "\000\000\000\000\000\000\000\000\000\000\000",
+      192);
+  *(uint64_t*)0x20000240 = 0;
+  *(uint32_t*)0x20000248 = 0;
+  syscall(__NR_ioctl, r[0], 0x8949ul, 0x20000180ul);
+  res = syz_init_net_socket(0x1a, 2, 0);
+  if (res != -1)
+    r[1] = res;
+  *(uint32_t*)0x200000c0 = 7;
+  syscall(__NR_setsockopt, r[1], 1ul, 0x3eul, 0x200000c0ul, 4ul);
+  *(uint16_t*)0x20000040 = 0x1a;
+  *(uint16_t*)0x20000042 = 0;
+  *(uint8_t*)0x20000044 = 0;
+  *(uint8_t*)0x20000045 = 0;
+  *(uint8_t*)0x20000046 = 0;
+  *(uint8_t*)0x20000047 = 0;
+  *(uint8_t*)0x20000048 = 0;
+  *(uint8_t*)0x20000049 = 0;
+  *(uint8_t*)0x2000004a = 0;
+  *(uint8_t*)0x2000004b = 0;
+  *(uint8_t*)0x2000004c = 0;
+  *(uint8_t*)0x2000004d = 0;
+  syscall(__NR_bind, r[1], 0x20000040ul, 0x10ul);
+  syscall(__NR_sendmmsg, r[1], 0x20001380ul, 0x3fffffffffffeedul, 0ul);
+  close_fds();
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  setup_binfmt_misc();
+  do_sandbox_none();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0401d67c3c0ebbc0a5dbe2167c81376013a31fe4.c b/syzkaller-repros/linux/0401d67c3c0ebbc0a5dbe2167c81376013a31fe4.c
new file mode 100644
index 0000000..90a0c75
--- /dev/null
+++ b/syzkaller-repros/linux/0401d67c3c0ebbc0a5dbe2167c81376013a31fe4.c
@@ -0,0 +1,294 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <endian.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
+#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
+  *(type*)(addr) =                                                             \
+      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
+            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[0] = res;
+  *(uint64_t*)0x20001080 = 0;
+  *(uint32_t*)0x20001088 = 0;
+  *(uint64_t*)0x20001090 = 0x20001040;
+  *(uint64_t*)0x20001040 = 0x200002c0;
+  *(uint32_t*)0x200002c0 = 0x48;
+  *(uint8_t*)0x200002c4 = 2;
+  *(uint8_t*)0x200002c5 = 6;
+  *(uint16_t*)0x200002c6 = 1;
+  *(uint32_t*)0x200002c8 = 0;
+  *(uint32_t*)0x200002cc = 0;
+  *(uint8_t*)0x200002d0 = 0;
+  *(uint8_t*)0x200002d1 = 0;
+  *(uint16_t*)0x200002d2 = htobe16(0);
+  *(uint16_t*)0x200002d4 = 0xd;
+  *(uint16_t*)0x200002d6 = 3;
+  memcpy((void*)0x200002d8, "list:set\000", 9);
+  *(uint16_t*)0x200002e4 = 5;
+  *(uint16_t*)0x200002e6 = 4;
+  *(uint8_t*)0x200002e8 = 0;
+  *(uint16_t*)0x200002ec = 5;
+  *(uint16_t*)0x200002ee = 5;
+  *(uint8_t*)0x200002f0 = 0;
+  *(uint16_t*)0x200002f4 = 9;
+  *(uint16_t*)0x200002f6 = 2;
+  memcpy((void*)0x200002f8, "syz1\000", 5);
+  *(uint16_t*)0x20000300 = 5;
+  *(uint16_t*)0x20000302 = 1;
+  *(uint8_t*)0x20000304 = 7;
+  *(uint64_t*)0x20001048 = 0x48;
+  *(uint64_t*)0x20001098 = 1;
+  *(uint64_t*)0x200010a0 = 0;
+  *(uint64_t*)0x200010a8 = 0;
+  *(uint32_t*)0x200010b0 = 0;
+  syscall(__NR_sendmsg, r[0], 0x20001080ul, 0ul);
+  syscall(__NR_sendmsg, -1, 0ul, 0ul);
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[1] = res;
+  *(uint64_t*)0x20000340 = 0;
+  *(uint32_t*)0x20000348 = 0;
+  *(uint64_t*)0x20000350 = 0x20000300;
+  *(uint64_t*)0x20000300 = 0x20000140;
+  *(uint32_t*)0x20000140 = 0x1a4;
+  *(uint8_t*)0x20000144 = 0xb;
+  *(uint8_t*)0x20000145 = 6;
+  *(uint16_t*)0x20000146 = 1;
+  *(uint32_t*)0x20000148 = 0x70bd27;
+  *(uint32_t*)0x2000014c = 0x25dfdbfb;
+  *(uint8_t*)0x20000150 = 0xa;
+  *(uint8_t*)0x20000151 = 0;
+  *(uint16_t*)0x20000152 = htobe16(8);
+  *(uint16_t*)0x20000154 = 0x54;
+  STORE_BY_BITMASK(uint16_t, , 0x20000156, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000157, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000157, 1, 7, 1);
+  *(uint16_t*)0x20000158 = 0x18;
+  STORE_BY_BITMASK(uint16_t, , 0x2000015a, 1, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000015b, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000015b, 1, 7, 1);
+  *(uint16_t*)0x2000015c = 0x14;
+  *(uint16_t*)0x2000015e = 2;
+  memcpy((void*)0x20000160,
+         "\xae\x14\x6d\x52\x25\xc9\x52\x45\x57\x98\xc3\xce\x32\x1f\xe8\x6a",
+         16);
+  *(uint16_t*)0x20000170 = 9;
+  *(uint16_t*)0x20000172 = 0x13;
+  memcpy((void*)0x20000174, "syz1\000", 5);
+  *(uint16_t*)0x2000017c = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x2000017e, 0xb, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000017f, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000017f, 0, 7, 1);
+  *(uint32_t*)0x20000180 = htobe32(4);
+  *(uint16_t*)0x20000184 = 6;
+  STORE_BY_BITMASK(uint16_t, , 0x20000186, 5, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000187, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000187, 0, 7, 1);
+  *(uint16_t*)0x20000188 = htobe16(0x4e24);
+  *(uint16_t*)0x2000018c = 0x14;
+  *(uint16_t*)0x2000018e = 0x17;
+  memcpy((void*)0x20000190, "bond_slave_0\000\000\000\000", 16);
+  *(uint16_t*)0x200001a0 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x200001a2, 6, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001a3, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001a3, 0, 7, 1);
+  *(uint32_t*)0x200001a4 = htobe32(3);
+  *(uint16_t*)0x200001a8 = 0x54;
+  STORE_BY_BITMASK(uint16_t, , 0x200001aa, 8, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001ab, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001ab, 1, 7, 1);
+  *(uint16_t*)0x200001ac = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200001ae, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001af, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001af, 1, 7, 1);
+  *(uint16_t*)0x200001b0 = 6;
+  STORE_BY_BITMASK(uint16_t, , 0x200001b2, 0x1d, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001b3, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001b3, 0, 7, 1);
+  *(uint16_t*)0x200001b4 = htobe16(0xaf);
+  *(uint16_t*)0x200001b8 = 0x10;
+  STORE_BY_BITMASK(uint16_t, , 0x200001ba, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001bb, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001bb, 1, 7, 1);
+  *(uint16_t*)0x200001bc = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200001be, 0x18, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001bf, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001bf, 0, 7, 1);
+  *(uint64_t*)0x200001c0 = htobe64(1);
+  *(uint16_t*)0x200001c8 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200001ca, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001cb, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001cb, 1, 7, 1);
+  *(uint16_t*)0x200001cc = 5;
+  *(uint16_t*)0x200001ce = 0x1a;
+  memcpy((void*)0x200001d0, "\000", 1);
+  *(uint16_t*)0x200001d4 = 0x10;
+  STORE_BY_BITMASK(uint16_t, , 0x200001d6, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001d7, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001d7, 1, 7, 1);
+  *(uint16_t*)0x200001d8 = 9;
+  *(uint16_t*)0x200001da = 0x12;
+  memcpy((void*)0x200001dc, "syz2\000", 5);
+  *(uint16_t*)0x200001e4 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200001e6, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001e7, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001e7, 1, 7, 1);
+  *(uint16_t*)0x200001e8 = 6;
+  STORE_BY_BITMASK(uint16_t, , 0x200001ea, 0x1d, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001eb, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001eb, 0, 7, 1);
+  *(uint16_t*)0x200001ec = htobe16(5);
+  *(uint16_t*)0x200001f0 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200001f2, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001f3, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001f3, 1, 7, 1);
+  *(uint16_t*)0x200001f4 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x200001f6, 0x1c, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001f7, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001f7, 0, 7, 1);
+  *(uint32_t*)0x200001f8 = htobe32(2);
+  *(uint16_t*)0x200001fc = 9;
+  *(uint16_t*)0x200001fe = 2;
+  memcpy((void*)0x20000200, "syz0\000", 5);
+  *(uint16_t*)0x20000208 = 0x24;
+  STORE_BY_BITMASK(uint16_t, , 0x2000020a, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000020b, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000020b, 1, 7, 1);
+  *(uint16_t*)0x2000020c = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x2000020e, 0x14, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000020f, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000020f, 1, 7, 1);
+  *(uint16_t*)0x20000210 = 8;
+  *(uint16_t*)0x20000212 = 1;
+  *(uint32_t*)0x20000214 = htobe32(0x7f000001);
+  *(uint16_t*)0x20000218 = 0xa;
+  *(uint16_t*)0x2000021a = 0x11;
+  *(uint8_t*)0x2000021c = 0xaa;
+  *(uint8_t*)0x2000021d = 0xaa;
+  *(uint8_t*)0x2000021e = 0xaa;
+  *(uint8_t*)0x2000021f = 0xaa;
+  *(uint8_t*)0x20000220 = 0xaa;
+  *(uint8_t*)0x20000221 = 0xbb;
+  *(uint16_t*)0x20000224 = 6;
+  STORE_BY_BITMASK(uint16_t, , 0x20000226, 5, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000227, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000227, 0, 7, 1);
+  *(uint16_t*)0x20000228 = htobe16(0x4e20);
+  *(uint16_t*)0x2000022c = 0x60;
+  STORE_BY_BITMASK(uint16_t, , 0x2000022e, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000022f, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000022f, 1, 7, 1);
+  *(uint16_t*)0x20000230 = 5;
+  *(uint16_t*)0x20000232 = 0x15;
+  *(uint8_t*)0x20000234 = 0x20;
+  *(uint16_t*)0x20000238 = 0x18;
+  STORE_BY_BITMASK(uint16_t, , 0x2000023a, 0x16, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000023b, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000023b, 1, 7, 1);
+  *(uint16_t*)0x2000023c = 0x14;
+  *(uint16_t*)0x2000023e = 2;
+  *(uint64_t*)0x20000240 = htobe64(0);
+  *(uint64_t*)0x20000248 = htobe64(1);
+  *(uint16_t*)0x20000250 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x20000252, 0x18, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000253, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000253, 0, 7, 1);
+  *(uint64_t*)0x20000254 = htobe64(8);
+  *(uint16_t*)0x2000025c = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x2000025e, 0xb, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000025f, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000025f, 0, 7, 1);
+  *(uint32_t*)0x20000260 = htobe32(0x401);
+  *(uint16_t*)0x20000264 = 5;
+  *(uint16_t*)0x20000266 = 3;
+  *(uint8_t*)0x20000268 = 0xf7;
+  *(uint16_t*)0x2000026c = 0x18;
+  STORE_BY_BITMASK(uint16_t, , 0x2000026e, 1, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000026f, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000026f, 1, 7, 1);
+  *(uint16_t*)0x20000270 = 0x14;
+  *(uint16_t*)0x20000272 = 2;
+  *(uint8_t*)0x20000274 = 0xfe;
+  *(uint8_t*)0x20000275 = 0x88;
+  *(uint8_t*)0x20000276 = 0;
+  *(uint8_t*)0x20000277 = 0;
+  *(uint8_t*)0x20000278 = 0;
+  *(uint8_t*)0x20000279 = 0;
+  *(uint8_t*)0x2000027a = 0;
+  *(uint8_t*)0x2000027b = 0;
+  *(uint8_t*)0x2000027c = 0;
+  *(uint8_t*)0x2000027d = 0;
+  *(uint8_t*)0x2000027e = 0;
+  *(uint8_t*)0x2000027f = 0;
+  *(uint8_t*)0x20000280 = 0;
+  *(uint8_t*)0x20000281 = 0;
+  *(uint8_t*)0x20000282 = 1;
+  *(uint8_t*)0x20000283 = 1;
+  *(uint16_t*)0x20000284 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x20000286, 0xb, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000287, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000287, 0, 7, 1);
+  *(uint32_t*)0x20000288 = htobe32(0);
+  *(uint16_t*)0x2000028c = 5;
+  *(uint16_t*)0x2000028e = 1;
+  *(uint8_t*)0x20000290 = 7;
+  *(uint16_t*)0x20000294 = 0x2c;
+  STORE_BY_BITMASK(uint16_t, , 0x20000296, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000297, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000297, 1, 7, 1);
+  *(uint16_t*)0x20000298 = 0x14;
+  *(uint16_t*)0x2000029a = 0x1a;
+  memcpy((void*)0x2000029c, "^[wlan0vboxnet0\000", 16);
+  *(uint16_t*)0x200002ac = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x200002ae, 0x1c, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200002af, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200002af, 0, 7, 1);
+  *(uint32_t*)0x200002b0 = htobe32(0x7f);
+  *(uint16_t*)0x200002b4 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200002b6, 0x1b, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200002b7, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200002b7, 0, 7, 1);
+  *(uint64_t*)0x200002b8 = htobe64(9);
+  *(uint16_t*)0x200002c0 = 0x18;
+  STORE_BY_BITMASK(uint16_t, , 0x200002c2, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200002c3, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200002c3, 1, 7, 1);
+  *(uint16_t*)0x200002c4 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x200002c6, 9, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200002c7, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200002c7, 0, 7, 1);
+  *(uint32_t*)0x200002c8 = htobe32(9);
+  *(uint16_t*)0x200002cc = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200002ce, 0x1b, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200002cf, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200002cf, 0, 7, 1);
+  *(uint64_t*)0x200002d0 = htobe64(1);
+  *(uint16_t*)0x200002d8 = 9;
+  *(uint16_t*)0x200002da = 2;
+  memcpy((void*)0x200002dc, "syz1\000", 5);
+  *(uint64_t*)0x20000308 = 0x1a4;
+  *(uint64_t*)0x20000358 = 1;
+  *(uint64_t*)0x20000360 = 0;
+  *(uint64_t*)0x20000368 = 0;
+  *(uint32_t*)0x20000370 = 0x88000;
+  syscall(__NR_sendmsg, r[1], 0x20000340ul, 0x40000000ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/04169338416ff83f7e44c503d9cc93b31c152876.c b/syzkaller-repros/linux/04169338416ff83f7e44c503d9cc93b31c152876.c
new file mode 100644
index 0000000..d27e722
--- /dev/null
+++ b/syzkaller-repros/linux/04169338416ff83f7e44c503d9cc93b31c152876.c
@@ -0,0 +1,933 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <sched.h>
+#include <signal.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/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/uio.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/capability.h>
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/if_tun.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/tcp.h>
+#include <linux/veth.h>
+
+unsigned long long procid;
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static void netlink_nest(struct nlmsg* nlmsg, int typ)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_type = typ;
+  nlmsg->pos += sizeof(*attr);
+  nlmsg->nested[nlmsg->nesting++] = attr;
+}
+
+static void netlink_done(struct nlmsg* nlmsg)
+{
+  struct nlattr* attr = nlmsg->nested[--nlmsg->nesting];
+  attr->nla_len = nlmsg->pos - (char*)attr;
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_add_device_impl(struct nlmsg* nlmsg, const char* type,
+                                    const char* name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  if (name)
+    netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name));
+  netlink_nest(nlmsg, IFLA_LINKINFO);
+  netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type));
+}
+
+static void netlink_add_device(struct nlmsg* nlmsg, int sock, const char* type,
+                               const char* name)
+{
+  netlink_add_device_impl(nlmsg, type, name);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_veth(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* peer)
+{
+  netlink_add_device_impl(nlmsg, "veth", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_nest(nlmsg, VETH_INFO_PEER);
+  nlmsg->pos += sizeof(struct ifinfomsg);
+  netlink_attr(nlmsg, IFLA_IFNAME, peer, strlen(peer));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_hsr(struct nlmsg* nlmsg, int sock, const char* name,
+                            const char* slave1, const char* slave2)
+{
+  netlink_add_device_impl(nlmsg, "hsr", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  int ifindex1 = if_nametoindex(slave1);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE1, &ifindex1, sizeof(ifindex1));
+  int ifindex2 = if_nametoindex(slave2);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE2, &ifindex2, sizeof(ifindex2));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_virt_wifi(struct nlmsg* nlmsg, int sock,
+                                  const char* name, const char* link)
+{
+  netlink_add_device_impl(nlmsg, "virt_wifi", name);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_vlan(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* link, uint16_t id, uint16_t proto)
+{
+  netlink_add_device_impl(nlmsg, "vlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_VLAN_ID, &id, sizeof(id));
+  netlink_attr(nlmsg, IFLA_VLAN_PROTOCOL, &proto, sizeof(proto));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_macvlan(struct nlmsg* nlmsg, int sock, const char* name,
+                                const char* link)
+{
+  netlink_add_device_impl(nlmsg, "macvlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  uint32_t mode = MACVLAN_MODE_BRIDGE;
+  netlink_attr(nlmsg, IFLA_MACVLAN_MODE, &mode, sizeof(mode));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+#define IFLA_IPVLAN_FLAGS 2
+#define IPVLAN_MODE_L3S 2
+#undef IPVLAN_F_VEPA
+#define IPVLAN_F_VEPA 2
+
+static void netlink_add_ipvlan(struct nlmsg* nlmsg, int sock, const char* name,
+                               const char* link, uint16_t mode, uint16_t flags)
+{
+  netlink_add_device_impl(nlmsg, "ipvlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_IPVLAN_MODE, &mode, sizeof(mode));
+  netlink_attr(nlmsg, IFLA_IPVLAN_FLAGS, &flags, sizeof(flags));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
+                            const void* addr, int addrsize)
+{
+  struct ifaddrmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
+  hdr.ifa_scope = RT_SCOPE_UNIVERSE;
+  hdr.ifa_index = if_nametoindex(dev);
+  netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
+  netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
+  return netlink_send(nlmsg, sock);
+}
+
+static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in_addr in_addr;
+  inet_pton(AF_INET, addr, &in_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
+  (void)err;
+}
+
+static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, addr, &in6_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+#define DEV_IPV4 "172.20.20.%d"
+#define DEV_IPV6 "fe80::%02x"
+#define DEV_MAC 0x00aaaaaaaaaa
+
+static void netdevsim_add(unsigned int addr, unsigned int port_count)
+{
+  char buf[16];
+  sprintf(buf, "%u %u", addr, port_count);
+  if (write_file("/sys/bus/netdevsim/new_device", buf)) {
+    snprintf(buf, sizeof(buf), "netdevsim%d", addr);
+    initialize_devlink_ports("netdevsim", buf, "netdevsim");
+  }
+}
+static void initialize_netdevices(void)
+{
+  char netdevsim[16];
+  sprintf(netdevsim, "netdevsim%d", (int)procid);
+  struct {
+    const char* type;
+    const char* dev;
+  } devtypes[] = {
+      {"ip6gretap", "ip6gretap0"}, {"bridge", "bridge0"},
+      {"vcan", "vcan0"},           {"bond", "bond0"},
+      {"team", "team0"},           {"dummy", "dummy0"},
+      {"nlmon", "nlmon0"},         {"caif", "caif0"},
+      {"batadv", "batadv0"},       {"vxcan", "vxcan1"},
+      {"netdevsim", netdevsim},    {"veth", 0},
+      {"xfrm", "xfrm0"},
+  };
+  const char* devmasters[] = {"bridge", "bond", "team"};
+  struct {
+    const char* name;
+    int macsize;
+    bool noipv6;
+  } devices[] = {
+      {"lo", ETH_ALEN},
+      {"sit0", 0},
+      {"bridge0", ETH_ALEN},
+      {"vcan0", 0, true},
+      {"tunl0", 0},
+      {"gre0", 0},
+      {"gretap0", ETH_ALEN},
+      {"ip_vti0", 0},
+      {"ip6_vti0", 0},
+      {"ip6tnl0", 0},
+      {"ip6gre0", 0},
+      {"ip6gretap0", ETH_ALEN},
+      {"erspan0", ETH_ALEN},
+      {"bond0", ETH_ALEN},
+      {"veth0", ETH_ALEN},
+      {"veth1", ETH_ALEN},
+      {"team0", ETH_ALEN},
+      {"veth0_to_bridge", ETH_ALEN},
+      {"veth1_to_bridge", ETH_ALEN},
+      {"veth0_to_bond", ETH_ALEN},
+      {"veth1_to_bond", ETH_ALEN},
+      {"veth0_to_team", ETH_ALEN},
+      {"veth1_to_team", ETH_ALEN},
+      {"veth0_to_hsr", ETH_ALEN},
+      {"veth1_to_hsr", ETH_ALEN},
+      {"hsr0", 0},
+      {"dummy0", ETH_ALEN},
+      {"nlmon0", 0},
+      {"vxcan0", 0, true},
+      {"vxcan1", 0, true},
+      {"caif0", ETH_ALEN},
+      {"batadv0", ETH_ALEN},
+      {netdevsim, ETH_ALEN},
+      {"xfrm0", ETH_ALEN},
+      {"veth0_virt_wifi", ETH_ALEN},
+      {"veth1_virt_wifi", ETH_ALEN},
+      {"virt_wifi0", ETH_ALEN},
+      {"veth0_vlan", ETH_ALEN},
+      {"veth1_vlan", ETH_ALEN},
+      {"vlan0", ETH_ALEN},
+      {"vlan1", ETH_ALEN},
+      {"macvlan0", ETH_ALEN},
+      {"macvlan1", ETH_ALEN},
+      {"ipvlan0", ETH_ALEN},
+      {"ipvlan1", ETH_ALEN},
+  };
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++)
+    netlink_add_device(&nlmsg, sock, devtypes[i].type, devtypes[i].dev);
+  for (i = 0; i < sizeof(devmasters) / (sizeof(devmasters[0])); i++) {
+    char master[32], slave0[32], veth0[32], slave1[32], veth1[32];
+    sprintf(slave0, "%s_slave_0", devmasters[i]);
+    sprintf(veth0, "veth0_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave0, veth0);
+    sprintf(slave1, "%s_slave_1", devmasters[i]);
+    sprintf(veth1, "veth1_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave1, veth1);
+    sprintf(master, "%s0", devmasters[i]);
+    netlink_device_change(&nlmsg, sock, slave0, false, master, 0, 0, NULL);
+    netlink_device_change(&nlmsg, sock, slave1, false, master, 0, 0, NULL);
+  }
+  netlink_device_change(&nlmsg, sock, "bridge_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "bridge_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_0", "veth0_to_hsr");
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_1", "veth1_to_hsr");
+  netlink_add_hsr(&nlmsg, sock, "hsr0", "hsr_slave_0", "hsr_slave_1");
+  netlink_device_change(&nlmsg, sock, "hsr_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "hsr_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "veth0_virt_wifi", "veth1_virt_wifi");
+  netlink_add_virt_wifi(&nlmsg, sock, "virt_wifi0", "veth1_virt_wifi");
+  netlink_add_veth(&nlmsg, sock, "veth0_vlan", "veth1_vlan");
+  netlink_add_vlan(&nlmsg, sock, "vlan0", "veth0_vlan", 0, htons(ETH_P_8021Q));
+  netlink_add_vlan(&nlmsg, sock, "vlan1", "veth0_vlan", 1, htons(ETH_P_8021AD));
+  netlink_add_macvlan(&nlmsg, sock, "macvlan0", "veth1_vlan");
+  netlink_add_macvlan(&nlmsg, sock, "macvlan1", "veth1_vlan");
+  netlink_add_ipvlan(&nlmsg, sock, "ipvlan0", "veth0_vlan", IPVLAN_MODE_L2, 0);
+  netlink_add_ipvlan(&nlmsg, sock, "ipvlan1", "veth0_vlan", IPVLAN_MODE_L3S,
+                     IPVLAN_F_VEPA);
+  netdevsim_add((int)procid, 4);
+  for (i = 0; i < sizeof(devices) / (sizeof(devices[0])); i++) {
+    char addr[32];
+    sprintf(addr, DEV_IPV4, i + 10);
+    netlink_add_addr4(&nlmsg, sock, devices[i].name, addr);
+    if (!devices[i].noipv6) {
+      sprintf(addr, DEV_IPV6, i + 10);
+      netlink_add_addr6(&nlmsg, sock, devices[i].name, addr);
+    }
+    uint64_t macaddr = DEV_MAC + ((i + 10ull) << 40);
+    netlink_device_change(&nlmsg, sock, devices[i].name, true, 0, &macaddr,
+                          devices[i].macsize, NULL);
+  }
+  close(sock);
+}
+static void initialize_netdevices_init(void)
+{
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  struct {
+    const char* type;
+    int macsize;
+    bool noipv6;
+    bool noup;
+  } devtypes[] = {
+      {"nr", 7, true},
+      {"rose", 5, true, true},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++) {
+    char dev[32], addr[32];
+    sprintf(dev, "%s%d", devtypes[i].type, (int)procid);
+    sprintf(addr, "172.30.%d.%d", i, (int)procid + 1);
+    netlink_add_addr4(&nlmsg, sock, dev, addr);
+    if (!devtypes[i].noipv6) {
+      sprintf(addr, "fe88::%02x:%02x", i, (int)procid + 1);
+      netlink_add_addr6(&nlmsg, sock, dev, addr);
+    }
+    int macsize = devtypes[i].macsize;
+    uint64_t macaddr = 0xbbbbbb +
+                       ((unsigned long long)i << (8 * (macsize - 2))) +
+                       (procid << (8 * (macsize - 1)));
+    netlink_device_change(&nlmsg, sock, dev, !devtypes[i].noup, 0, &macaddr,
+                          macsize, NULL);
+  }
+  close(sock);
+}
+
+#define MAX_FDS 30
+
+static void setup_common()
+{
+  if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
+  }
+}
+
+static void loop();
+
+static void sandbox_common()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setsid();
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  if (dup2(netns, kInitNetNsFd) < 0)
+    exit(1);
+  close(netns);
+  struct rlimit rlim;
+  rlim.rlim_cur = rlim.rlim_max = (200 << 20);
+  setrlimit(RLIMIT_AS, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 32 << 20;
+  setrlimit(RLIMIT_MEMLOCK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 136 << 20;
+  setrlimit(RLIMIT_FSIZE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+  setrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 0;
+  setrlimit(RLIMIT_CORE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 256;
+  setrlimit(RLIMIT_NOFILE, &rlim);
+  if (unshare(CLONE_NEWNS)) {
+  }
+  if (unshare(CLONE_NEWIPC)) {
+  }
+  if (unshare(0x02000000)) {
+  }
+  if (unshare(CLONE_NEWUTS)) {
+  }
+  if (unshare(CLONE_SYSVSEM)) {
+  }
+  typedef struct {
+    const char* name;
+    const char* value;
+  } sysctl_t;
+  static const sysctl_t sysctls[] = {
+      {"/proc/sys/kernel/shmmax", "16777216"},
+      {"/proc/sys/kernel/shmall", "536870912"},
+      {"/proc/sys/kernel/shmmni", "1024"},
+      {"/proc/sys/kernel/msgmax", "8192"},
+      {"/proc/sys/kernel/msgmni", "1024"},
+      {"/proc/sys/kernel/msgmnb", "1024"},
+      {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
+    write_file(sysctls[i].name, sysctls[i].value);
+}
+
+int wait_for_loop(int pid)
+{
+  if (pid < 0)
+    exit(1);
+  int status = 0;
+  while (waitpid(-1, &status, __WALL) != pid) {
+  }
+  return WEXITSTATUS(status);
+}
+
+static void drop_caps(void)
+{
+  struct __user_cap_header_struct cap_hdr = {};
+  struct __user_cap_data_struct cap_data[2] = {};
+  cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
+  cap_hdr.pid = getpid();
+  if (syscall(SYS_capget, &cap_hdr, &cap_data))
+    exit(1);
+  const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
+  cap_data[0].effective &= ~drop;
+  cap_data[0].permitted &= ~drop;
+  cap_data[0].inheritable &= ~drop;
+  if (syscall(SYS_capset, &cap_hdr, &cap_data))
+    exit(1);
+}
+
+static int do_sandbox_none(void)
+{
+  if (unshare(CLONE_NEWPID)) {
+  }
+  int pid = fork();
+  if (pid != 0)
+    return wait_for_loop(pid);
+  setup_common();
+  sandbox_common();
+  drop_caps();
+  initialize_netdevices_init();
+  if (unshare(CLONE_NEWNET)) {
+  }
+  initialize_devlink_pci();
+  initialize_netdevices();
+  loop();
+  exit(1);
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+}
+
+static void close_fds()
+{
+  int fd;
+  for (fd = 3; fd < MAX_FDS; fd++)
+    close(fd);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  int iter;
+  for (iter = 0;; iter++) {
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      setup_test();
+      execute_one();
+      close_fds();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+  }
+}
+
+uint64_t r[7] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+                 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+                 0xffffffffffffffff};
+
+void execute_one(void)
+{
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0ul);
+  if (res != -1)
+    r[0] = res;
+  syscall(__NR_getsockname, -1, 0ul, 0ul);
+  res = syscall(__NR_socketpair, 1ul, 1ul, 0ul, 0x20000000ul);
+  if (res != -1)
+    r[1] = *(uint32_t*)0x20000004;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0ul);
+  if (res != -1)
+    r[2] = res;
+  memcpy((void*)0x20000340, "erspan0\000\000\000\000\000\000\000\000\000", 16);
+  *(uint32_t*)0x20000350 = 0;
+  res = syscall(__NR_ioctl, r[1], 0x8933ul, 0x20000340ul);
+  if (res != -1)
+    r[3] = *(uint32_t*)0x20000350;
+  syscall(__NR_socket, 0x10ul, 3ul, 0ul);
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0ul);
+  if (res != -1)
+    r[4] = res;
+  res = syscall(__NR_socket, 0x10ul, 0x803ul, 0);
+  if (res != -1)
+    r[5] = res;
+  *(uint64_t*)0x200001c0 = 0;
+  *(uint32_t*)0x200001c8 = 0;
+  *(uint64_t*)0x200001d0 = 0x20000180;
+  *(uint64_t*)0x20000180 = 0;
+  *(uint64_t*)0x20000188 = 0;
+  *(uint64_t*)0x200001d8 = 1;
+  *(uint64_t*)0x200001e0 = 0;
+  *(uint64_t*)0x200001e8 = 0;
+  *(uint32_t*)0x200001f0 = 0;
+  syscall(__NR_sendmsg, r[5], 0x200001c0ul, 0ul);
+  *(uint32_t*)0x20000200 = 0x14;
+  res = syscall(__NR_getsockname, r[5], 0x20000100ul, 0x20000200ul);
+  if (res != -1)
+    r[6] = *(uint32_t*)0x20000104;
+  *(uint64_t*)0x20000180 = 0;
+  *(uint32_t*)0x20000188 = 0;
+  *(uint64_t*)0x20000190 = 0x200000c0;
+  *(uint64_t*)0x200000c0 = 0x20000380;
+  *(uint32_t*)0x20000380 = 0x3c;
+  *(uint16_t*)0x20000384 = 0x10;
+  *(uint16_t*)0x20000386 = 0x401;
+  *(uint32_t*)0x20000388 = 0;
+  *(uint32_t*)0x2000038c = 0;
+  *(uint8_t*)0x20000390 = 0;
+  *(uint8_t*)0x20000391 = 0;
+  *(uint16_t*)0x20000392 = 0;
+  *(uint32_t*)0x20000394 = r[6];
+  *(uint32_t*)0x20000398 = 0;
+  *(uint32_t*)0x2000039c = 0;
+  *(uint16_t*)0x200003a0 = 0x1c;
+  *(uint16_t*)0x200003a2 = 0x12;
+  *(uint16_t*)0x200003a4 = 0xc;
+  *(uint16_t*)0x200003a6 = 1;
+  memcpy((void*)0x200003a8, "bridge\000", 7);
+  *(uint16_t*)0x200003b0 = 0xc;
+  *(uint16_t*)0x200003b2 = 2;
+  *(uint16_t*)0x200003b4 = 8;
+  *(uint16_t*)0x200003b6 = 7;
+  *(uint8_t*)0x200003b8 = 5;
+  *(uint64_t*)0x200000c8 = 0x3c;
+  *(uint64_t*)0x20000198 = 1;
+  *(uint64_t*)0x200001a0 = 0;
+  *(uint64_t*)0x200001a8 = 0;
+  *(uint32_t*)0x200001b0 = 0;
+  syscall(__NR_sendmsg, r[4], 0x20000180ul, 0ul);
+  *(uint64_t*)0x20000140 = 0;
+  *(uint32_t*)0x20000148 = 0;
+  *(uint64_t*)0x20000150 = 0x200006c0;
+  *(uint64_t*)0x200006c0 = 0x200000c0;
+  memcpy((void*)0x200000c0,
+         "\x28\x00\x00\x00\x10\x00\x01\x04\x00\x00\x40\x00\x00\x00\x00\x00\x00"
+         "\x00\x1e\xa6",
+         20);
+  *(uint32_t*)0x200000d4 = r[3];
+  memcpy((void*)0x200000d8, "\000\000\000\000\000\000\000\000\b\000\n\000", 12);
+  *(uint32_t*)0x200000e4 = r[6];
+  *(uint64_t*)0x200006c8 = 0x28;
+  *(uint64_t*)0x20000158 = 1;
+  *(uint64_t*)0x20000160 = 0;
+  *(uint64_t*)0x20000168 = 0;
+  *(uint32_t*)0x20000170 = 0;
+  syscall(__NR_sendmsg, r[2], 0x20000140ul, 0ul);
+  syscall(__NR_sendmsg, r[0], 0ul, 0ul);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  do_sandbox_none();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/048b731781ec88911e03f32b90d91298f040263d.c b/syzkaller-repros/linux/048b731781ec88911e03f32b90d91298f040263d.c
new file mode 100644
index 0000000..da9b3cc
--- /dev/null
+++ b/syzkaller-repros/linux/048b731781ec88911e03f32b90d91298f040263d.c
@@ -0,0 +1,132 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <endian.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
+#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
+  *(type*)(addr) =                                                             \
+      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
+            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[0] = res;
+  *(uint64_t*)0x20000280 = 0;
+  *(uint32_t*)0x20000288 = 8;
+  *(uint64_t*)0x20000290 = 0x20000240;
+  *(uint64_t*)0x20000240 = 0x20000100;
+  memcpy((void*)0x20000100,
+         "\x14\x00\x00\x00\x10\x00\x00\x00\x1e\x6c\x00\x00\x00\x00\x00\x00\x00"
+         "\x00\x00\x0a\x20\x00\x00\x00\x00\x0a\x01\x00\x00\x00\x00\x00\x00\x00"
+         "\x00\x00\x00\x00\x00\x00\x09\x00\x01\x00\x73\x79\x7a\x30\x00\x00\x00"
+         "\x00\x38\x00\x00\x00\x12\x0a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+         "\x00\x00\x00\x00\x04\x00\x04\x80\x09\x00\x02\x00\x00\x39\x7d\x00\x00"
+         "\x00\x00\x00\x09\x00\x01\x00\x73\x79\x7a\x30\x00\x00\x00\x00\x08\x00"
+         "\x03\x40\x00\x00\x00\x01\x14\x00\x00\x00\x11\x00\xdf\x00\x00\x00\x00"
+         "\x00\x00\x00\x00\x00\x00\x00\x00\x0a",
+         128);
+  *(uint64_t*)0x20000248 = 0x80;
+  *(uint64_t*)0x20000298 = 1;
+  *(uint64_t*)0x200002a0 = 0;
+  *(uint64_t*)0x200002a8 = 0;
+  *(uint32_t*)0x200002b0 = 0;
+  syscall(__NR_sendmsg, r[0], 0x20000280ul, 0ul);
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[1] = res;
+  *(uint64_t*)0x20000140 = 0;
+  *(uint32_t*)0x20000148 = 0;
+  *(uint64_t*)0x20000150 = 0x20000100;
+  *(uint64_t*)0x20000100 = 0x20000040;
+  *(uint32_t*)0x20000040 = 0x14;
+  *(uint16_t*)0x20000044 = 0x10;
+  *(uint16_t*)0x20000046 = 1;
+  *(uint32_t*)0x20000048 = 0;
+  *(uint32_t*)0x2000004c = 0;
+  *(uint8_t*)0x20000050 = 0;
+  *(uint8_t*)0x20000051 = 0;
+  *(uint16_t*)0x20000052 = htobe16(0xa);
+  *(uint32_t*)0x20000054 = 0x34;
+  *(uint8_t*)0x20000058 = 0x14;
+  *(uint8_t*)0x20000059 = 0xa;
+  *(uint16_t*)0x2000005a = 3;
+  *(uint32_t*)0x2000005c = 0;
+  *(uint32_t*)0x20000060 = 0;
+  *(uint8_t*)0x20000064 = 0;
+  *(uint8_t*)0x20000065 = 0;
+  *(uint16_t*)0x20000066 = htobe16(2);
+  *(uint16_t*)0x20000068 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x2000006a, 3, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000006b, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000006b, 0, 7, 1);
+  *(uint32_t*)0x2000006c = htobe32(1);
+  *(uint16_t*)0x20000070 = 9;
+  *(uint16_t*)0x20000072 = 1;
+  memcpy((void*)0x20000074, "syz0\000", 5);
+  *(uint16_t*)0x2000007c = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x2000007e, 6, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000007f, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000007f, 0, 7, 1);
+  *(uint64_t*)0x20000080 = htobe64(1);
+  *(uint32_t*)0x20000088 = 0x58;
+  *(uint8_t*)0x2000008c = 2;
+  *(uint8_t*)0x2000008d = 0xa;
+  *(uint16_t*)0x2000008e = 0x603;
+  *(uint32_t*)0x20000090 = 0;
+  *(uint32_t*)0x20000094 = 0;
+  *(uint8_t*)0x20000098 = 0;
+  *(uint8_t*)0x20000099 = 0;
+  *(uint16_t*)0x2000009a = htobe16(6);
+  *(uint16_t*)0x2000009c = 9;
+  *(uint16_t*)0x2000009e = 1;
+  memcpy((void*)0x200000a0, "syz1\000", 5);
+  *(uint16_t*)0x200000a8 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x200000aa, 2, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200000ab, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200000ab, 0, 7, 1);
+  *(uint32_t*)0x200000ac = htobe32(1);
+  *(uint16_t*)0x200000b0 = 9;
+  *(uint16_t*)0x200000b2 = 1;
+  memcpy((void*)0x200000b4, "syz0\000", 5);
+  *(uint16_t*)0x200000bc = 9;
+  *(uint16_t*)0x200000be = 1;
+  memcpy((void*)0x200000c0, "syz1\000", 5);
+  *(uint16_t*)0x200000c8 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200000ca, 4, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200000cb, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200000cb, 0, 7, 1);
+  *(uint64_t*)0x200000cc = htobe64(3);
+  *(uint16_t*)0x200000d4 = 9;
+  *(uint16_t*)0x200000d6 = 1;
+  memcpy((void*)0x200000d8, "syz0\000", 5);
+  *(uint32_t*)0x200000e0 = 0x14;
+  *(uint16_t*)0x200000e4 = 0x11;
+  *(uint16_t*)0x200000e6 = 1;
+  *(uint32_t*)0x200000e8 = 0;
+  *(uint32_t*)0x200000ec = 0;
+  *(uint8_t*)0x200000f0 = 0;
+  *(uint8_t*)0x200000f1 = 0;
+  *(uint16_t*)0x200000f2 = htobe16(0xa);
+  *(uint64_t*)0x20000108 = 0xb4;
+  *(uint64_t*)0x20000158 = 1;
+  *(uint64_t*)0x20000160 = 0;
+  *(uint64_t*)0x20000168 = 0;
+  *(uint32_t*)0x20000170 = 0x4000004;
+  syscall(__NR_sendmsg, r[1], 0x20000140ul, 0x42000ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/04969b1fecdf47ff3849f7fce737fd1ef12b8e4f.c b/syzkaller-repros/linux/04969b1fecdf47ff3849f7fce737fd1ef12b8e4f.c
new file mode 100644
index 0000000..dadd3dd
--- /dev/null
+++ b/syzkaller-repros/linux/04969b1fecdf47ff3849f7fce737fd1ef12b8e4f.c
@@ -0,0 +1,176 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <endian.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
+#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
+  *(type*)(addr) =                                                             \
+      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
+            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[0] = res;
+  *(uint64_t*)0x20000300 = 0;
+  *(uint32_t*)0x20000308 = 0;
+  *(uint64_t*)0x20000310 = 0x200002c0;
+  *(uint64_t*)0x200002c0 = 0x20000080;
+  *(uint32_t*)0x20000080 = 0x5c;
+  *(uint8_t*)0x20000084 = 2;
+  *(uint8_t*)0x20000085 = 6;
+  *(uint16_t*)0x20000086 = 1;
+  *(uint32_t*)0x20000088 = 0;
+  *(uint32_t*)0x2000008c = 0;
+  *(uint8_t*)0x20000090 = 0;
+  *(uint8_t*)0x20000091 = 0;
+  *(uint16_t*)0x20000092 = htobe16(0);
+  *(uint16_t*)0x20000094 = 9;
+  *(uint16_t*)0x20000096 = 2;
+  memcpy((void*)0x20000098, "syz2\000", 5);
+  *(uint16_t*)0x200000a0 = 0x15;
+  *(uint16_t*)0x200000a2 = 3;
+  memcpy((void*)0x200000a4, "hash:ip,port,net\000", 17);
+  *(uint16_t*)0x200000b8 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200000ba, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200000bb, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200000bb, 1, 7, 1);
+  *(uint16_t*)0x200000bc = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x200000be, 0x13, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200000bf, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200000bf, 0, 7, 1);
+  *(uint32_t*)0x200000c0 = htobe32(0x1000);
+  *(uint16_t*)0x200000c4 = 5;
+  *(uint16_t*)0x200000c6 = 1;
+  *(uint8_t*)0x200000c8 = 7;
+  *(uint16_t*)0x200000cc = 5;
+  *(uint16_t*)0x200000ce = 4;
+  *(uint8_t*)0x200000d0 = 0;
+  *(uint16_t*)0x200000d4 = 5;
+  *(uint16_t*)0x200000d6 = 5;
+  *(uint8_t*)0x200000d8 = 2;
+  *(uint64_t*)0x200002c8 = 0x5c;
+  *(uint64_t*)0x20000318 = 1;
+  *(uint64_t*)0x20000320 = 0;
+  *(uint64_t*)0x20000328 = 0;
+  *(uint32_t*)0x20000330 = 0;
+  syscall(__NR_sendmsg, r[0], 0x20000300ul, 0ul);
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[1] = res;
+  *(uint64_t*)0x20000280 = 0;
+  *(uint32_t*)0x20000288 = 0;
+  *(uint64_t*)0x20000290 = 0x20000240;
+  *(uint64_t*)0x20000240 = 0x20000180;
+  *(uint32_t*)0x20000180 = 0xb0;
+  *(uint8_t*)0x20000184 = 0xb;
+  *(uint8_t*)0x20000185 = 6;
+  *(uint16_t*)0x20000186 = 1;
+  *(uint32_t*)0x20000188 = 0x70bd27;
+  *(uint32_t*)0x2000018c = 0x25dfdbfb;
+  *(uint8_t*)0x20000190 = 0xc;
+  *(uint8_t*)0x20000191 = 0;
+  *(uint16_t*)0x20000192 = htobe16(0xa);
+  *(uint16_t*)0x20000194 = 0x14;
+  STORE_BY_BITMASK(uint16_t, , 0x20000196, 8, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000197, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000197, 1, 7, 1);
+  *(uint16_t*)0x20000198 = 0x10;
+  STORE_BY_BITMASK(uint16_t, , 0x2000019a, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000019b, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000019b, 1, 7, 1);
+  *(uint16_t*)0x2000019c = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x2000019e, 0x14, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000019f, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000019f, 1, 7, 1);
+  *(uint16_t*)0x200001a0 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x200001a2, 1, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001a3, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001a3, 0, 7, 1);
+  *(uint32_t*)0x200001a4 = htobe32(0x7f000001);
+  *(uint16_t*)0x200001a8 = 5;
+  *(uint16_t*)0x200001aa = 1;
+  *(uint8_t*)0x200001ac = 7;
+  *(uint16_t*)0x200001b0 = 9;
+  *(uint16_t*)0x200001b2 = 2;
+  memcpy((void*)0x200001b4, "syz2\000", 5);
+  *(uint16_t*)0x200001bc = 0x50;
+  STORE_BY_BITMASK(uint16_t, , 0x200001be, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001bf, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001bf, 1, 7, 1);
+  *(uint16_t*)0x200001c0 = 0x14;
+  *(uint16_t*)0x200001c2 = 0x17;
+  memcpy((void*)0x200001c4, "rose0\000\000\000\000\000\000\000\000\000\000\000",
+         16);
+  *(uint16_t*)0x200001d4 = 0xa;
+  *(uint16_t*)0x200001d6 = 0x11;
+  *(uint8_t*)0x200001d8 = 0xaa;
+  *(uint8_t*)0x200001d9 = 0xaa;
+  *(uint8_t*)0x200001da = 0xaa;
+  *(uint8_t*)0x200001db = 0xaa;
+  *(uint8_t*)0x200001dc = 0xaa;
+  *(uint8_t*)0x200001dd = 0x2d;
+  *(uint16_t*)0x200001e0 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x200001e2, 6, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001e3, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001e3, 0, 7, 1);
+  *(uint32_t*)0x200001e4 = htobe32(0x6dc);
+  *(uint16_t*)0x200001e8 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x200001ea, 0x19, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x200001eb, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x200001eb, 0, 7, 1);
+  *(uint64_t*)0x200001ec = htobe64(0xc2fb);
+  *(uint16_t*)0x200001f4 = 5;
+  *(uint16_t*)0x200001f6 = 7;
+  *(uint8_t*)0x200001f8 = 0x30;
+  *(uint16_t*)0x200001fc = 5;
+  *(uint16_t*)0x200001fe = 0x15;
+  *(uint8_t*)0x20000200 = 0x3f;
+  *(uint16_t*)0x20000204 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x20000206, 6, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000207, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000207, 0, 7, 1);
+  *(uint32_t*)0x20000208 = htobe32(8);
+  *(uint16_t*)0x2000020c = 9;
+  *(uint16_t*)0x2000020e = 2;
+  memcpy((void*)0x20000210, "syz2\000", 5);
+  *(uint16_t*)0x20000218 = 0x18;
+  STORE_BY_BITMASK(uint16_t, , 0x2000021a, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000021b, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000021b, 1, 7, 1);
+  *(uint16_t*)0x2000021c = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x2000021e, 9, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000021f, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000021f, 0, 7, 1);
+  *(uint32_t*)0x20000220 = htobe32(4);
+  *(uint16_t*)0x20000224 = 0xc;
+  STORE_BY_BITMASK(uint16_t, , 0x20000226, 1, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000227, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000227, 1, 7, 1);
+  *(uint16_t*)0x20000228 = 8;
+  STORE_BY_BITMASK(uint16_t, , 0x2000022a, 1, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000022b, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000022b, 0, 7, 1);
+  *(uint32_t*)0x2000022c = htobe32(0x7f000001);
+  *(uint64_t*)0x20000248 = 0xb0;
+  *(uint64_t*)0x20000298 = 1;
+  *(uint64_t*)0x200002a0 = 0;
+  *(uint64_t*)0x200002a8 = 0;
+  *(uint32_t*)0x200002b0 = 0x8000;
+  syscall(__NR_sendmsg, r[1], 0x20000280ul, 0xc0000c4ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/05505cdef9d15919d3ef0128391540db21272c98.c b/syzkaller-repros/linux/05505cdef9d15919d3ef0128391540db21272c98.c
new file mode 100644
index 0000000..c4dbf7b
--- /dev/null
+++ b/syzkaller-repros/linux/05505cdef9d15919d3ef0128391540db21272c98.c
@@ -0,0 +1,386 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+#include <linux/in6.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/veth.h>
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+static long syz_open_dev(volatile long a0, volatile long a1, volatile long a2)
+{
+  if (a0 == 0xc || a0 == 0xb) {
+    char buf[128];
+    sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block", (uint8_t)a1,
+            (uint8_t)a2);
+    return open(buf, O_RDWR, 0);
+  } else {
+    char buf[1024];
+    char* hash;
+    strncpy(buf, (char*)a0, sizeof(buf) - 1);
+    buf[sizeof(buf) - 1] = 0;
+    while ((hash = strchr(buf, '#'))) {
+      *hash = '0' + (char)(a1 % 10);
+      a1 /= 10;
+    }
+    return open(buf, a2, 0);
+  }
+}
+
+uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+                 0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  res = syz_open_dev(0xc, 4, 1);
+  if (res != -1)
+    r[0] = res;
+  *(uint32_t*)0x20000000 = 0;
+  *(uint32_t*)0x20000004 = 0;
+  *(uint32_t*)0x20000008 = 1;
+  *(uint32_t*)0x2000000c = 3;
+  *(uint32_t*)0x20000010 = 0x100;
+  *(uint64_t*)0x20000018 = 0x200003c0;
+  memcpy(
+      (void*)0x200003c0,
+      "\xcb\xb6\x2c\x7c\x7e\x12\x72\x7d\x60\xc5\xdb\x26\x5c\x1d\x8b\x3f\x75\x25"
+      "\x50\xd4\xea\xc7\xaf\xf1\x02\x13\x26\xe1\x5d\xfd\xad\x91\x1d\x57\xa8\x53"
+      "\x41\x4b\x19\x47\x02\xa4\x1a\x75\x60\x56\x8b\xe1\x11\x1d\xac\x9f\xf2\x58"
+      "\x6d\x67\xdc\x8e\xf3\xe9\xd3\x66\x94\xc5\xea\x96\xd8\x98\x5a\x99\x53\xe8"
+      "\x77\x5c\xbf\x7a\xe1\x51\xea\x1f\xd6\x1f\xbc\x2d\x44\xe7\x60\x31\x83\x3d"
+      "\xff\xb4\x47\xc4\x25\xc9\x74\x9c\x7d\xe7\xfb\xe2\xe5\x65\xb4\xa2\x5f\x7b"
+      "\x2a\xc0\x13\x92\xce\x04\xec\x8d\x6d\x21\x0e\x0a\x23\xae\x3a\x5f\xd8\x1c"
+      "\x3c\x89\xc9\x28\x74\x70\x9f\xcd\xd4\xd4\xc3\xff\xe7\xfa\x05\x2a\xc6\x8f"
+      "\xb6\xdf\x7e\x48\x2e\x24\xbe\x6a\xc8\x19\x10\x39\xb4\x34\xaa\x0e\x9f\x97"
+      "\x39\xae\xdf\x30\xc0\xfa\x9c\x42\xcd\xa4\x11\x02\x5c\xa2\x0c\x42\xbf\x88"
+      "\x68\x56\x03\x99\x87\x3f\x4d\x1b\x28\xed\x71\x3e\x41\x1b\x34\xec\x02\x63"
+      "\x21\xc8\xcd\x9a\xd1\x7c\xbc\x95\x70\x4c\x14\x2d\x7c\x71\x06\x3b\x4a\x0b"
+      "\x52\xe2\x20\x73\xf8\x59\xd6\x32\x89\x92\x12\x6e\x5f\x50\x57\xad\x1d\x02"
+      "\x29\xba\xde\xc1\xe0\x88\x0f\x47\x6f\x18\xce\x68\x55\x60\x78\xa0\x06\x7d"
+      "\x8e\x90\x05\x7f\x56\x0b\x51\x51\xc4\x50\xe6\x55\x89\x81\x2f\x77\x9b\x50"
+      "\xe4\xde\xd6\x60\xee\x4a\xa6\x1e\x7f\x84\xa9\xb4\xb7\x91\x83\x71\x14\x09"
+      "\x55\x39\xfb\x55\x73\xe4\x7c\xce\x26\xdc\x38\x31\x19\x13\x99\x51\x81\xe7"
+      "\x28\xfd\x4d\x6d\x33\x4e\x62\xfd\x0a\x82\x2f\x93\x71\xbc\xdc\x43\xc8\xa6"
+      "\x96\x88\xa1\x1f\xc9\xf4\x3a\xfe\x64\x2c\x30\xdd\xf3\x94\x65\xb1\x3c\xf1"
+      "\xdd\xad\xd7\x89\x70\x77\x18\x27\xf4\x45\xf0\xd4\x56\x1e\x8e\x2b\xb6\xcf"
+      "\x22\x44\x63\x4b\xcd\x72\xd1\x24\xf3\xca\xa1\x52\xc6\xfd\x6d\x47\xbb\x00"
+      "\x4b\x97\x97\x5d\x4a\x46\xb2\xee\x12\x9b\x88\x9d\xc5\x9c\x1c\x71\x62\xff"
+      "\xf2\x2c\x42\x95\x54\x52\x95\xea\x72\xfe\x14\xc6\xb2\xba\xb3\x5a\xb5\x45"
+      "\x51\x73\x98\xb0\x03\xb6\xd3\xb8\x9c\x5c\x64\xb4\x49\xf7\xd5\x60\xdd\xe2"
+      "\x0f\xc1\x3b\x3e\xc8\x8d\xc0\x52\x42\xa1\x60\x07\x6c\xcb\xff\x3e\x32\xb8"
+      "\x78\x0b\xd1\x91\xa0\xb1\x2a\x6f\x99\x00\xa9\x3f\xa1\x2d\x9f\xb5\xed\x34"
+      "\x88\xd5\xcd\x0a\xa3\x29\x58\x3f\x2c\x47\xc4\xfd\x47\x26\x46\x9c\x98\xe0"
+      "\xb6\x6d\x74\xc3\x1d\x0a\x1f\x7f\xc1\x0c\xc1\x94\x4d\x25\x26\x7e\xff\x7a"
+      "\x74\x0c\xc4\x30\x06\x9b\x58\x47\x9c\xa6\x96\x00\x63\x6a\x0f\x22\xa4\x70"
+      "\xa6\x9b\x46\xc1\xcc\x1b\x95\xcf\x32\xdd\x7b\x73\xad\x67\x41\x61\xca\x39"
+      "\x25\x83\xaa\x83\x4a\xaa\xde\x88\xa4\x39\x33\x89\xb7\x6d\x58\x8a\x60\x81"
+      "\x91\xdb\x7c\xa7\x5d\xd0\x09\x38\x2a\x45\x83\xe8\x78\x1e\xb0\x9f\x48\xa4"
+      "\x4d\x06\xb4\x17\x56\xeb\x3f\x1b\x7e\xea\x18\xad\xf2\x97\x83\x22\xd0\xb3"
+      "\x84\xdf\x03\x07\x98\x91\xe1\x0f\x09\x2c\x57\x33\x20\xfb\x94\x1f\x10\xe3"
+      "\xc3\xaf\x6f\x3e\x72\xb2\xaf\xcd\x95\xa3\x66\x6a\x6a\x40\xa8\x40\xe6\x3d"
+      "\x1c\xb9\xe2\x49\x25\xc0\x49\x7a\x04\xef\x7b\x9b\x1e\xe3\x9d\xe0\x45\x6f"
+      "\xec\xd6\x76\xac\xee\x23\x3f\x5b\x64\x5e\x8d\x05\xf3\xf5\x05\xa1\x2a\x0f"
+      "\x5b\x35\x65\x86\xf2\x2c\x2c\x2c\xeb\xef\x83\xc5\xe6\x8c\x22\x72\x34\x95"
+      "\xab\xa0\x64\x27\x92\x55\xde\x48\x9e\x33\xe9\x20\x9a\x63\x68\x90\xbc\xfb"
+      "\x2a\x52\x7e\x8d\xa8\x36\x21\xae\xf3\x74\xf5\xa1\x1d\x8a\xc7\x7f\x5d\xcd"
+      "\x42\x1f\x45\xe5\x2d\xdf\x9b\xc3\x5f\x64\xcf\x72\x1c\xe6\xc9\x6b\x56\x13"
+      "\x26\x8c\x02\x5c\xa9\x91\x0a\x8a\x23\x5e\x6a\xf3\xd6\x7a\xdd\xc6\x6e\x75"
+      "\xc1\x56\x4a\x7f\x86\x84\xfc\xd2\x3e\xc9\x8d\x61\xa4\xfa\x42\x2c\x55\xe6"
+      "\x78\x9c\xbc\x42\xb1\xd5\x32\x63\x3e\x65\x8a\x5c\x2f\xfe\x57\x67\x03\x97"
+      "\x62\xf1\x8c\xce\x89\xb8\x00\x0e\x37\xca\xbc\x35\x40\x9d\x3c\x7a\x02\x13"
+      "\xde\x87\xce\x95\xcf\xbf\xb0\xc7\x1b\xe4\xc4\xef\x44\x86\x6b\xd8\xe0\x50"
+      "\xe3\x36\xb3\x1a\x6e\x8f\x15\xbd\x21\x60\xe5\x48\x48\xad\xa2\x56\xdf\x90"
+      "\x27\x58\xeb\xbc\x1e\x83\x7f\xab\x4c\xb8\xbb\x84\x67\xa7\x3d\xf7\x17\xd9"
+      "\x2e\x22\x04\x48\x2f\xe9\x5c\x21\x12\x11\x86\xa5\x7c\x3b\x12\xf7\x5c\x83"
+      "\x6a\xb7\x02\x43\x34\x18\xf3\x29\x44\x32\x3e\xaa\xad\xbc\xa3\x66\x96\x1c"
+      "\x25\x62\x0c\x43\x95\x1a\x7a\x3f\xd3\xe3\xcc\x85\xd6\xa3\x99\x6b\x50\xd1"
+      "\x2e\xa7\x6d\xf6\x58\xa6\x40\x5f\xdf\x1c\x9f\x2c\x05\x24\x8d\x95\x15\xce"
+      "\x96\x65\x0e\xbf\x62\x96\x64\xe6\xc1\x92\xdd\x28\xe1\x61\x72\xbe\x15\x93"
+      "\xe9\x4d\xbc\xa0\xe5\x54\xfc\xe9\x73\x6c\x73\x54\x03\x0c\x64\xfd\xaf\x35"
+      "\x03\x8e\x1f\x1e\x1d\x20\xe0\x6f\x34\x8e\xf5\xae\x75\x41\x39\xb4\xe8\x12"
+      "\xc6\x0f\xbc\x55\xba\xce\x83\xf2\x7b\xb8\x35\xc1\x64\xc2\x9f\x5f\x7c\x1d"
+      "\xbe\xeb\xfd\x98\x8a\x16\x23\x5c\x4b\xbe\xe4\xd9\xa3\xbc\x66\x6f",
+      1024);
+  syscall(__NR_ioctl, r[0], 0x4b72ul, 0x20000000ul);
+  res = syz_open_dev(0xc, 4, 0x15);
+  if (res != -1)
+    r[1] = res;
+  *(uint16_t*)0x20000000 = 0;
+  *(uint16_t*)0x20000002 = 0;
+  *(uint16_t*)0x20000004 = 0;
+  *(uint16_t*)0x20000006 = 5;
+  *(uint16_t*)0x20000008 = 5;
+  *(uint16_t*)0x2000000a = 0;
+  syscall(__NR_ioctl, r[1], 0x560aul, 0x20000000ul);
+  syscall(__NR_ioctl, r[1], 0x4b48ul, 0ul);
+  res = syscall(__NR_openat, 0xffffffffffffff9cul, 0ul, 0x67514c7366170adeul,
+                0ul);
+  if (res != -1)
+    r[2] = res;
+  syscall(__NR_write, r[2], 0ul, 0ul);
+  syscall(__NR_ioctl, -1, 0x460ful, 0ul);
+  syscall(__NR_mmap, 0x20000000ul, 0x3000ul, 0x2000002ul, 0x11ul, -1, 0ul);
+  res = syz_open_dev(0xc, 4, 1);
+  if (res != -1)
+    r[3] = res;
+  memcpy((void*)0x20000100, "\xe0\x9b\x3d", 3);
+  syscall(__NR_write, r[3], 0x20000100ul, 0x567ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/063f4f68ef32f5cae06ea84e5fb8d58f2dacab2a.c b/syzkaller-repros/linux/063f4f68ef32f5cae06ea84e5fb8d58f2dacab2a.c
new file mode 100644
index 0000000..8b73232
--- /dev/null
+++ b/syzkaller-repros/linux/063f4f68ef32f5cae06ea84e5fb8d58f2dacab2a.c
@@ -0,0 +1,795 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+#include <linux/in6.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/veth.h>
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 2ul, 2ul, 0x88ul);
+  if (res != -1)
+    r[0] = res;
+  memcpy((void*)0x20000880,
+         "filter\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+         "\000\000\000\000\000\000\000\000\000\000\000",
+         32);
+  *(uint32_t*)0x200008a0 = 4;
+  *(uint32_t*)0x200008a4 = 4;
+  *(uint32_t*)0x200008a8 = 0x3c8;
+  *(uint32_t*)0x200008ac = 0;
+  *(uint32_t*)0x200008b0 = 0;
+  *(uint32_t*)0x200008b4 = 0;
+  *(uint32_t*)0x200008b8 = 0x2e0;
+  *(uint32_t*)0x200008bc = 0x2e0;
+  *(uint32_t*)0x200008c0 = 0x2e0;
+  *(uint32_t*)0x200008c4 = 4;
+  *(uint64_t*)0x200008c8 = 0;
+  *(uint8_t*)0x200008d0 = 0;
+  *(uint8_t*)0x200008d1 = 0;
+  *(uint8_t*)0x200008d2 = 0;
+  *(uint8_t*)0x200008d3 = 0;
+  *(uint8_t*)0x200008d4 = 0;
+  *(uint8_t*)0x200008d5 = 0;
+  *(uint8_t*)0x200008d6 = 0;
+  *(uint8_t*)0x200008d7 = 0;
+  *(uint8_t*)0x200008d8 = 0;
+  *(uint8_t*)0x200008d9 = 0;
+  *(uint8_t*)0x200008da = 0;
+  *(uint8_t*)0x200008db = 0;
+  *(uint8_t*)0x200008dc = 0;
+  *(uint8_t*)0x200008dd = 0;
+  *(uint8_t*)0x200008de = 0;
+  *(uint8_t*)0x200008df = 0;
+  *(uint8_t*)0x200008e0 = 0;
+  *(uint8_t*)0x200008e1 = 0;
+  *(uint8_t*)0x200008e2 = 0;
+  *(uint8_t*)0x200008e3 = 0;
+  *(uint8_t*)0x200008e4 = 0;
+  *(uint8_t*)0x200008e5 = 0;
+  *(uint8_t*)0x200008e6 = 0;
+  *(uint8_t*)0x200008e7 = 0;
+  *(uint8_t*)0x200008e8 = 0;
+  *(uint8_t*)0x200008e9 = 0;
+  *(uint8_t*)0x200008ea = 0;
+  *(uint8_t*)0x200008eb = 0;
+  *(uint8_t*)0x200008ec = 0;
+  *(uint8_t*)0x200008ed = 0;
+  *(uint8_t*)0x200008ee = 0;
+  *(uint8_t*)0x200008ef = 0;
+  *(uint8_t*)0x200008f0 = 0;
+  *(uint8_t*)0x200008f1 = 0;
+  *(uint8_t*)0x200008f2 = 0;
+  *(uint8_t*)0x200008f3 = 0;
+  *(uint8_t*)0x200008f4 = 0;
+  *(uint8_t*)0x200008f5 = 0;
+  *(uint8_t*)0x200008f6 = 0;
+  *(uint8_t*)0x200008f7 = 0;
+  *(uint8_t*)0x200008f8 = 0;
+  *(uint8_t*)0x200008f9 = 0;
+  *(uint8_t*)0x200008fa = 0;
+  *(uint8_t*)0x200008fb = 0;
+  *(uint8_t*)0x200008fc = 0;
+  *(uint8_t*)0x200008fd = 0;
+  *(uint8_t*)0x200008fe = 0;
+  *(uint8_t*)0x200008ff = 0;
+  *(uint8_t*)0x20000900 = 0;
+  *(uint8_t*)0x20000901 = 0;
+  *(uint8_t*)0x20000902 = 0;
+  *(uint8_t*)0x20000903 = 0;
+  *(uint8_t*)0x20000904 = 0;
+  *(uint8_t*)0x20000905 = 0;
+  *(uint8_t*)0x20000906 = 0;
+  *(uint8_t*)0x20000907 = 0;
+  *(uint8_t*)0x20000908 = 0;
+  *(uint8_t*)0x20000909 = 0;
+  *(uint8_t*)0x2000090a = 0;
+  *(uint8_t*)0x2000090b = 0;
+  *(uint8_t*)0x2000090c = 0;
+  *(uint8_t*)0x2000090d = 0;
+  *(uint8_t*)0x2000090e = 0;
+  *(uint8_t*)0x2000090f = 0;
+  *(uint8_t*)0x20000910 = 0;
+  *(uint8_t*)0x20000911 = 0;
+  *(uint8_t*)0x20000912 = 0;
+  *(uint8_t*)0x20000913 = 0;
+  *(uint8_t*)0x20000914 = 0;
+  *(uint8_t*)0x20000915 = 0;
+  *(uint8_t*)0x20000916 = 0;
+  *(uint8_t*)0x20000917 = 0;
+  *(uint8_t*)0x20000918 = 0;
+  *(uint8_t*)0x20000919 = 0;
+  *(uint8_t*)0x2000091a = 0;
+  *(uint8_t*)0x2000091b = 0;
+  *(uint8_t*)0x2000091c = 0;
+  *(uint8_t*)0x2000091d = 0;
+  *(uint8_t*)0x2000091e = 0;
+  *(uint8_t*)0x2000091f = 0;
+  *(uint8_t*)0x20000920 = 0;
+  *(uint8_t*)0x20000921 = 0;
+  *(uint8_t*)0x20000922 = 0;
+  *(uint8_t*)0x20000923 = 0;
+  *(uint8_t*)0x20000924 = 0;
+  *(uint8_t*)0x20000925 = 0;
+  *(uint8_t*)0x20000926 = 0;
+  *(uint8_t*)0x20000927 = 0;
+  *(uint8_t*)0x20000928 = 0;
+  *(uint8_t*)0x20000929 = 0;
+  *(uint8_t*)0x2000092a = 0;
+  *(uint8_t*)0x2000092b = 0;
+  *(uint8_t*)0x2000092c = 0;
+  *(uint8_t*)0x2000092d = 0;
+  *(uint8_t*)0x2000092e = 0;
+  *(uint8_t*)0x2000092f = 0;
+  *(uint8_t*)0x20000930 = 0;
+  *(uint8_t*)0x20000931 = 0;
+  *(uint8_t*)0x20000932 = 0;
+  *(uint8_t*)0x20000933 = 0;
+  *(uint8_t*)0x20000934 = 0;
+  *(uint8_t*)0x20000935 = 0;
+  *(uint8_t*)0x20000936 = 0;
+  *(uint8_t*)0x20000937 = 0;
+  *(uint8_t*)0x20000938 = 0;
+  *(uint8_t*)0x20000939 = 0;
+  *(uint8_t*)0x2000093a = 0;
+  *(uint8_t*)0x2000093b = 0;
+  *(uint8_t*)0x2000093c = 0;
+  *(uint8_t*)0x2000093d = 0;
+  *(uint8_t*)0x2000093e = 0;
+  *(uint8_t*)0x2000093f = 0;
+  *(uint8_t*)0x20000940 = 0;
+  *(uint8_t*)0x20000941 = 0;
+  *(uint8_t*)0x20000942 = 0;
+  *(uint8_t*)0x20000943 = 0;
+  *(uint8_t*)0x20000944 = 0;
+  *(uint8_t*)0x20000945 = 0;
+  *(uint8_t*)0x20000946 = 0;
+  *(uint8_t*)0x20000947 = 0;
+  *(uint8_t*)0x20000948 = 0;
+  *(uint8_t*)0x20000949 = 0;
+  *(uint8_t*)0x2000094a = 0;
+  *(uint8_t*)0x2000094b = 0;
+  *(uint8_t*)0x2000094c = 0;
+  *(uint8_t*)0x2000094d = 0;
+  *(uint8_t*)0x2000094e = 0;
+  *(uint8_t*)0x2000094f = 0;
+  *(uint8_t*)0x20000950 = 0;
+  *(uint8_t*)0x20000951 = 0;
+  *(uint8_t*)0x20000952 = 0;
+  *(uint8_t*)0x20000953 = 0;
+  *(uint8_t*)0x20000954 = 0;
+  *(uint8_t*)0x20000955 = 0;
+  *(uint8_t*)0x20000956 = 0;
+  *(uint8_t*)0x20000957 = 0;
+  *(uint8_t*)0x20000958 = 0;
+  *(uint8_t*)0x20000959 = 0;
+  *(uint8_t*)0x2000095a = 0;
+  *(uint8_t*)0x2000095b = 0;
+  *(uint8_t*)0x2000095c = 0;
+  *(uint8_t*)0x2000095d = 0;
+  *(uint8_t*)0x2000095e = 0;
+  *(uint8_t*)0x2000095f = 0;
+  *(uint8_t*)0x20000960 = 0;
+  *(uint8_t*)0x20000961 = 0;
+  *(uint8_t*)0x20000962 = 0;
+  *(uint8_t*)0x20000963 = 0;
+  *(uint8_t*)0x20000964 = 0;
+  *(uint8_t*)0x20000965 = 0;
+  *(uint8_t*)0x20000966 = 0;
+  *(uint8_t*)0x20000967 = 0;
+  *(uint8_t*)0x20000968 = 0;
+  *(uint8_t*)0x20000969 = 0;
+  *(uint8_t*)0x2000096a = 0;
+  *(uint8_t*)0x2000096b = 0;
+  *(uint8_t*)0x2000096c = 0;
+  *(uint8_t*)0x2000096d = 0;
+  *(uint8_t*)0x2000096e = 0;
+  *(uint8_t*)0x2000096f = 0;
+  *(uint8_t*)0x20000970 = 0;
+  *(uint8_t*)0x20000971 = 0;
+  *(uint8_t*)0x20000972 = 0;
+  *(uint8_t*)0x20000973 = 0;
+  *(uint16_t*)0x20000974 = 0xc0;
+  *(uint16_t*)0x20000976 = 0xf0;
+  *(uint32_t*)0x20000978 = 0;
+  *(uint64_t*)0x20000980 = 0;
+  *(uint64_t*)0x20000988 = 0;
+  *(uint16_t*)0x20000990 = 0x30;
+  memcpy((void*)0x20000992,
+         "CONNMARK\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+         "\000\000\000\000\000\000",
+         29);
+  *(uint8_t*)0x200009af = 1;
+  *(uint32_t*)0x200009b0 = 0x80000000;
+  *(uint32_t*)0x200009b4 = 0x20;
+  *(uint32_t*)0x200009b8 = 0x80004;
+  *(uint8_t*)0x200009bc = 0;
+  *(uint32_t*)0x200009c0 = htobe32(0x7f000001);
+  *(uint8_t*)0x200009c4 = 0xac;
+  *(uint8_t*)0x200009c5 = 0x1e;
+  *(uint8_t*)0x200009c6 = 0;
+  *(uint8_t*)0x200009c7 = 1;
+  *(uint32_t*)0x200009c8 = htobe32(0);
+  *(uint32_t*)0x200009cc = htobe32(0);
+  *(uint8_t*)0x200009d0 = 0;
+  *(uint8_t*)0x200009d1 = 7;
+  *(uint8_t*)0x200009d2 = 0;
+  *(uint8_t*)0x200009d3 = 0;
+  *(uint8_t*)0x200009d4 = 0;
+  *(uint8_t*)0x200009d5 = 0;
+  *(uint8_t*)0x200009d6 = 0;
+  *(uint8_t*)0x200009d7 = 0;
+  *(uint8_t*)0x200009d8 = 0;
+  *(uint8_t*)0x200009d9 = 0;
+  *(uint8_t*)0x200009da = 0;
+  *(uint8_t*)0x200009db = 0;
+  *(uint8_t*)0x200009dc = 0;
+  *(uint8_t*)0x200009dd = 0;
+  *(uint8_t*)0x200009de = 0;
+  *(uint8_t*)0x200009df = 0;
+  *(uint8_t*)0x200009e0 = 0;
+  *(uint8_t*)0x200009e1 = 0;
+  *(uint8_t*)0x200009e2 = 0;
+  *(uint8_t*)0x200009e3 = 0;
+  *(uint8_t*)0x200009e4 = 0;
+  *(uint8_t*)0x200009e5 = 0;
+  *(uint8_t*)0x200009e6 = 0;
+  *(uint8_t*)0x200009e7 = 0;
+  *(uint8_t*)0x200009f2 = 0;
+  *(uint8_t*)0x200009f3 = 0;
+  *(uint8_t*)0x200009f4 = 0;
+  *(uint8_t*)0x200009f5 = 0;
+  *(uint8_t*)0x200009f6 = 0;
+  *(uint8_t*)0x200009f7 = 0;
+  *(uint8_t*)0x200009f8 = 0;
+  *(uint8_t*)0x200009f9 = 0;
+  *(uint8_t*)0x200009fa = 0;
+  *(uint8_t*)0x200009fb = 0;
+  *(uint8_t*)0x200009fc = 0;
+  *(uint8_t*)0x200009fd = 0;
+  *(uint8_t*)0x200009fe = 0;
+  *(uint8_t*)0x200009ff = 0;
+  *(uint8_t*)0x20000a00 = 0;
+  *(uint8_t*)0x20000a01 = 0;
+  *(uint8_t*)0x20000a02 = 0;
+  *(uint8_t*)0x20000a03 = 0;
+  *(uint8_t*)0x20000a04 = 0;
+  *(uint8_t*)0x20000a05 = 0;
+  *(uint8_t*)0x20000a06 = 0;
+  *(uint8_t*)0x20000a07 = 0;
+  *(uint16_t*)0x20000a12 = htobe16(0);
+  *(uint16_t*)0x20000a14 = htobe16(0);
+  *(uint16_t*)0x20000a16 = htobe16(0);
+  *(uint16_t*)0x20000a18 = htobe16(0);
+  *(uint16_t*)0x20000a1a = htobe16(0);
+  *(uint16_t*)0x20000a1c = htobe16(0);
+  memcpy((void*)0x20000a1e,
+         "yam\371\377\377\377\000\000\000\000\000\000\000\000\000", 16);
+  memcpy((void*)0x20000a2e,
+         "lo\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16);
+  *(uint8_t*)0x20000a3e = 0;
+  *(uint8_t*)0x20000a4e = 0;
+  *(uint8_t*)0x20000a5e = 0;
+  *(uint16_t*)0x20000a60 = 0;
+  *(uint16_t*)0x20000a64 = 0xc0;
+  *(uint16_t*)0x20000a66 = 0xe8;
+  *(uint32_t*)0x20000a68 = 0;
+  *(uint64_t*)0x20000a70 = 0;
+  *(uint64_t*)0x20000a78 = 0;
+  *(uint16_t*)0x20000a80 = 0x28;
+  memcpy((void*)0x20000a82,
+         "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+         "\000\000\000\000\000\000\000\000\000\000\000\000",
+         29);
+  *(uint8_t*)0x20000a9f = 0;
+  *(uint32_t*)0x20000aa0 = 0xfffffffe;
+  *(uint32_t*)0x20000aa8 = htobe32(0xe0000002);
+  *(uint32_t*)0x20000aac = htobe32(0x7f000001);
+  *(uint32_t*)0x20000ab0 = htobe32(0);
+  *(uint32_t*)0x20000ab4 = htobe32(0);
+  *(uint8_t*)0x20000ab8 = 0;
+  *(uint8_t*)0x20000ab9 = 0;
+  *(uint8_t*)0x20000aba = 0;
+  *(uint8_t*)0x20000abb = 0;
+  *(uint8_t*)0x20000abc = 0;
+  *(uint8_t*)0x20000abd = 0;
+  *(uint8_t*)0x20000abe = 0;
+  *(uint8_t*)0x20000abf = 0;
+  *(uint8_t*)0x20000ac0 = 0;
+  *(uint8_t*)0x20000ac1 = 0;
+  *(uint8_t*)0x20000ac2 = 0;
+  *(uint8_t*)0x20000ac3 = 0;
+  *(uint8_t*)0x20000ac4 = 0;
+  *(uint8_t*)0x20000ac5 = 0;
+  *(uint8_t*)0x20000ac6 = 0;
+  *(uint8_t*)0x20000ac7 = 0;
+  *(uint8_t*)0x20000ac8 = 0;
+  *(uint8_t*)0x20000ac9 = 0;
+  *(uint8_t*)0x20000aca = 0;
+  *(uint8_t*)0x20000acb = 0;
+  *(uint8_t*)0x20000acc = 0;
+  *(uint8_t*)0x20000acd = 0;
+  *(uint8_t*)0x20000ace = 0;
+  *(uint8_t*)0x20000acf = -1;
+  *(uint8_t*)0x20000ada = 1;
+  *(uint8_t*)0x20000adb = 0x80;
+  *(uint8_t*)0x20000adc = 0xc2;
+  *(uint8_t*)0x20000add = 0;
+  *(uint8_t*)0x20000ade = 0;
+  *(uint8_t*)0x20000adf = 0;
+  *(uint8_t*)0x20000aea = 0;
+  *(uint8_t*)0x20000aeb = 0;
+  *(uint8_t*)0x20000aec = 0;
+  *(uint8_t*)0x20000aed = 0;
+  *(uint8_t*)0x20000aee = 0;
+  *(uint8_t*)0x20000aef = 0;
+  *(uint16_t*)0x20000afa = htobe16(0);
+  *(uint16_t*)0x20000afc = htobe16(0);
+  *(uint16_t*)0x20000afe = htobe16(0);
+  *(uint16_t*)0x20000b00 = htobe16(0);
+  *(uint16_t*)0x20000b02 = htobe16(0);
+  *(uint16_t*)0x20000b04 = htobe16(0x94);
+  memcpy((void*)0x20000b06, "team0\000\000\000\000\000\000\000\000\000\000\000",
+         16);
+  memcpy((void*)0x20000b16, "syzkaller0\000\000\000\000\000\000", 16);
+  *(uint8_t*)0x20000b26 = 0;
+  *(uint8_t*)0x20000b36 = 0;
+  *(uint8_t*)0x20000b46 = 0;
+  *(uint16_t*)0x20000b48 = 0;
+  *(uint16_t*)0x20000b4c = 0xc0;
+  *(uint16_t*)0x20000b4e = 0x108;
+  *(uint32_t*)0x20000b50 = 0;
+  *(uint64_t*)0x20000b58 = 0;
+  *(uint64_t*)0x20000b60 = 0;
+  *(uint16_t*)0x20000b68 = 0x48;
+  memcpy((void*)0x20000b6a,
+         "IDLETIMER\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+         "\000\000\000\000\000",
+         29);
+  *(uint8_t*)0x20000b87 = 0;
+  *(uint32_t*)0x20000b88 = 5;
+  memcpy((void*)0x20000b8c,
+         "syz0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+         "\000\000\000\000\000\000\000\000",
+         28);
+  *(uint64_t*)0x20000ba8 = 0;
+  *(uint8_t*)0x20000bb0 = 0;
+  *(uint8_t*)0x20000bb1 = 0;
+  *(uint8_t*)0x20000bb2 = 0;
+  *(uint8_t*)0x20000bb3 = 0;
+  *(uint8_t*)0x20000bb4 = 0;
+  *(uint8_t*)0x20000bb5 = 0;
+  *(uint8_t*)0x20000bb6 = 0;
+  *(uint8_t*)0x20000bb7 = 0;
+  *(uint8_t*)0x20000bb8 = 0;
+  *(uint8_t*)0x20000bb9 = 0;
+  *(uint8_t*)0x20000bba = 0;
+  *(uint8_t*)0x20000bbb = 0;
+  *(uint8_t*)0x20000bbc = 0;
+  *(uint8_t*)0x20000bbd = 0;
+  *(uint8_t*)0x20000bbe = 0;
+  *(uint8_t*)0x20000bbf = 0;
+  *(uint8_t*)0x20000bc0 = 0;
+  *(uint8_t*)0x20000bc1 = 0;
+  *(uint8_t*)0x20000bc2 = 0;
+  *(uint8_t*)0x20000bc3 = 0;
+  *(uint8_t*)0x20000bc4 = 0;
+  *(uint8_t*)0x20000bc5 = 0;
+  *(uint8_t*)0x20000bc6 = 0;
+  *(uint8_t*)0x20000bc7 = 0;
+  *(uint8_t*)0x20000bc8 = 0;
+  *(uint8_t*)0x20000bc9 = 0;
+  *(uint8_t*)0x20000bca = 0;
+  *(uint8_t*)0x20000bcb = 0;
+  *(uint8_t*)0x20000bcc = 0;
+  *(uint8_t*)0x20000bcd = 0;
+  *(uint8_t*)0x20000bce = 0;
+  *(uint8_t*)0x20000bcf = 0;
+  *(uint8_t*)0x20000bd0 = 0;
+  *(uint8_t*)0x20000bd1 = 0;
+  *(uint8_t*)0x20000bd2 = 0;
+  *(uint8_t*)0x20000bd3 = 0;
+  *(uint8_t*)0x20000bd4 = 0;
+  *(uint8_t*)0x20000bd5 = 0;
+  *(uint8_t*)0x20000bd6 = 0;
+  *(uint8_t*)0x20000bd7 = 0;
+  *(uint8_t*)0x20000bd8 = 0;
+  *(uint8_t*)0x20000bd9 = 0;
+  *(uint8_t*)0x20000bda = 0;
+  *(uint8_t*)0x20000bdb = 0;
+  *(uint8_t*)0x20000bdc = 0;
+  *(uint8_t*)0x20000bdd = 0;
+  *(uint8_t*)0x20000bde = 0;
+  *(uint8_t*)0x20000bdf = 0;
+  *(uint8_t*)0x20000be0 = 0;
+  *(uint8_t*)0x20000be1 = 0;
+  *(uint8_t*)0x20000be2 = 0;
+  *(uint8_t*)0x20000be3 = 0;
+  *(uint8_t*)0x20000be4 = 0;
+  *(uint8_t*)0x20000be5 = 0;
+  *(uint8_t*)0x20000be6 = 0;
+  *(uint8_t*)0x20000be7 = 0;
+  *(uint8_t*)0x20000be8 = 0;
+  *(uint8_t*)0x20000be9 = 0;
+  *(uint8_t*)0x20000bea = 0;
+  *(uint8_t*)0x20000beb = 0;
+  *(uint8_t*)0x20000bec = 0;
+  *(uint8_t*)0x20000bed = 0;
+  *(uint8_t*)0x20000bee = 0;
+  *(uint8_t*)0x20000bef = 0;
+  *(uint8_t*)0x20000bf0 = 0;
+  *(uint8_t*)0x20000bf1 = 0;
+  *(uint8_t*)0x20000bf2 = 0;
+  *(uint8_t*)0x20000bf3 = 0;
+  *(uint8_t*)0x20000bf4 = 0;
+  *(uint8_t*)0x20000bf5 = 0;
+  *(uint8_t*)0x20000bf6 = 0;
+  *(uint8_t*)0x20000bf7 = 0;
+  *(uint8_t*)0x20000bf8 = 0;
+  *(uint8_t*)0x20000bf9 = 0;
+  *(uint8_t*)0x20000bfa = 0;
+  *(uint8_t*)0x20000bfb = 0;
+  *(uint8_t*)0x20000bfc = 0;
+  *(uint8_t*)0x20000bfd = 0;
+  *(uint8_t*)0x20000bfe = 0;
+  *(uint8_t*)0x20000bff = 0;
+  *(uint8_t*)0x20000c00 = 0;
+  *(uint8_t*)0x20000c01 = 0;
+  *(uint8_t*)0x20000c02 = 0;
+  *(uint8_t*)0x20000c03 = 0;
+  *(uint8_t*)0x20000c04 = 0;
+  *(uint8_t*)0x20000c05 = 0;
+  *(uint8_t*)0x20000c06 = 0;
+  *(uint8_t*)0x20000c07 = 0;
+  *(uint8_t*)0x20000c08 = 0;
+  *(uint8_t*)0x20000c09 = 0;
+  *(uint8_t*)0x20000c0a = 0;
+  *(uint8_t*)0x20000c0b = 0;
+  *(uint8_t*)0x20000c0c = 0;
+  *(uint8_t*)0x20000c0d = 0;
+  *(uint8_t*)0x20000c0e = 0;
+  *(uint8_t*)0x20000c0f = 0;
+  *(uint8_t*)0x20000c10 = 0;
+  *(uint8_t*)0x20000c11 = 0;
+  *(uint8_t*)0x20000c12 = 0;
+  *(uint8_t*)0x20000c13 = 0;
+  *(uint8_t*)0x20000c14 = 0;
+  *(uint8_t*)0x20000c15 = 0;
+  *(uint8_t*)0x20000c16 = 0;
+  *(uint8_t*)0x20000c17 = 0;
+  *(uint8_t*)0x20000c18 = 0;
+  *(uint8_t*)0x20000c19 = 0;
+  *(uint8_t*)0x20000c1a = 0;
+  *(uint8_t*)0x20000c1b = 0;
+  *(uint8_t*)0x20000c1c = 0;
+  *(uint8_t*)0x20000c1d = 0;
+  *(uint8_t*)0x20000c1e = 0;
+  *(uint8_t*)0x20000c1f = 0;
+  *(uint8_t*)0x20000c20 = 0;
+  *(uint8_t*)0x20000c21 = 0;
+  *(uint8_t*)0x20000c22 = 0;
+  *(uint8_t*)0x20000c23 = 0;
+  *(uint8_t*)0x20000c24 = 0;
+  *(uint8_t*)0x20000c25 = 0;
+  *(uint8_t*)0x20000c26 = 0;
+  *(uint8_t*)0x20000c27 = 0;
+  *(uint8_t*)0x20000c28 = 0;
+  *(uint8_t*)0x20000c29 = 0;
+  *(uint8_t*)0x20000c2a = 0;
+  *(uint8_t*)0x20000c2b = 0;
+  *(uint8_t*)0x20000c2c = 0;
+  *(uint8_t*)0x20000c2d = 0;
+  *(uint8_t*)0x20000c2e = 0;
+  *(uint8_t*)0x20000c2f = 0;
+  *(uint8_t*)0x20000c30 = 0;
+  *(uint8_t*)0x20000c31 = 0;
+  *(uint8_t*)0x20000c32 = 0;
+  *(uint8_t*)0x20000c33 = 0;
+  *(uint8_t*)0x20000c34 = 0;
+  *(uint8_t*)0x20000c35 = 0;
+  *(uint8_t*)0x20000c36 = 0;
+  *(uint8_t*)0x20000c37 = 0;
+  *(uint8_t*)0x20000c38 = 0;
+  *(uint8_t*)0x20000c39 = 0;
+  *(uint8_t*)0x20000c3a = 0;
+  *(uint8_t*)0x20000c3b = 0;
+  *(uint8_t*)0x20000c3c = 0;
+  *(uint8_t*)0x20000c3d = 0;
+  *(uint8_t*)0x20000c3e = 0;
+  *(uint8_t*)0x20000c3f = 0;
+  *(uint8_t*)0x20000c40 = 0;
+  *(uint8_t*)0x20000c41 = 0;
+  *(uint8_t*)0x20000c42 = 0;
+  *(uint8_t*)0x20000c43 = 0;
+  *(uint8_t*)0x20000c44 = 0;
+  *(uint8_t*)0x20000c45 = 0;
+  *(uint8_t*)0x20000c46 = 0;
+  *(uint8_t*)0x20000c47 = 0;
+  *(uint8_t*)0x20000c48 = 0;
+  *(uint8_t*)0x20000c49 = 0;
+  *(uint8_t*)0x20000c4a = 0;
+  *(uint8_t*)0x20000c4b = 0;
+  *(uint8_t*)0x20000c4c = 0;
+  *(uint8_t*)0x20000c4d = 0;
+  *(uint8_t*)0x20000c4e = 0;
+  *(uint8_t*)0x20000c4f = 0;
+  *(uint8_t*)0x20000c50 = 0;
+  *(uint8_t*)0x20000c51 = 0;
+  *(uint8_t*)0x20000c52 = 0;
+  *(uint8_t*)0x20000c53 = 0;
+  *(uint16_t*)0x20000c54 = 0xc0;
+  *(uint16_t*)0x20000c56 = 0xe8;
+  *(uint32_t*)0x20000c58 = 0;
+  *(uint64_t*)0x20000c60 = 0;
+  *(uint64_t*)0x20000c68 = 0;
+  *(uint16_t*)0x20000c70 = 0x28;
+  memcpy((void*)0x20000c72,
+         "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+         "\000\000\000\000\000\000\000\000\000\000\000\000",
+         29);
+  *(uint8_t*)0x20000c8f = 0;
+  *(uint32_t*)0x20000c90 = 0xfffffffe;
+  syscall(__NR_setsockopt, r[0], 0xa02000000000000ul, 0x60ul, 0x20000880ul,
+          0x418ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/07804ed067fcaa4c8967003831699a24e9b634ed.c b/syzkaller-repros/linux/07804ed067fcaa4c8967003831699a24e9b634ed.c
new file mode 100644
index 0000000..a1b1cf9
--- /dev/null
+++ b/syzkaller-repros/linux/07804ed067fcaa4c8967003831699a24e9b634ed.c
@@ -0,0 +1,736 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <setjmp.h>
+#include <signal.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/mount.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/futex.h>
+#include <linux/loop.h>
+
+unsigned long long procid;
+
+static __thread int skip_segv;
+static __thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* ctx)
+{
+  uintptr_t addr = (uintptr_t)info->si_addr;
+  const uintptr_t prog_start = 1 << 20;
+  const uintptr_t prog_end = 100 << 20;
+  if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) &&
+      (addr < prog_start || addr > prog_end)) {
+    _longjmp(segv_env, 1);
+  }
+  exit(sig);
+}
+
+static void install_segv_handler(void)
+{
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = SIG_IGN;
+  syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
+  syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_sigaction = segv_handler;
+  sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+  sigaction(SIGSEGV, &sa, NULL);
+  sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...)                                                        \
+  {                                                                            \
+    __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
+    if (_setjmp(segv_env) == 0) {                                              \
+      __VA_ARGS__;                                                             \
+    }                                                                          \
+    __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
+  }
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+  pthread_t th;
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setstacksize(&attr, 128 << 10);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (pthread_create(&th, &attr, fn, arg) == 0) {
+      pthread_attr_destroy(&attr);
+      return;
+    }
+    if (errno == EAGAIN) {
+      usleep(50);
+      continue;
+    }
+    break;
+  }
+  exit(1);
+}
+
+#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
+#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
+  *(type*)(addr) =                                                             \
+      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
+            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))
+
+typedef struct {
+  int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+  if (ev->state)
+    exit(1);
+  __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
+  syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
+}
+
+static void event_wait(event_t* ev)
+{
+  while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
+}
+
+static int event_isset(event_t* ev)
+{
+  return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+  uint64_t start = current_time_ms();
+  uint64_t now = start;
+  for (;;) {
+    uint64_t remain = timeout - (now - start);
+    struct timespec ts;
+    ts.tv_sec = remain / 1000;
+    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
+    if (__atomic_load_n(&ev->state, __ATOMIC_RELAXED))
+      return 1;
+    now = current_time_ms();
+    if (now - start > timeout)
+      return 0;
+  }
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+static long syz_open_dev(volatile long a0, volatile long a1, volatile long a2)
+{
+  if (a0 == 0xc || a0 == 0xb) {
+    char buf[128];
+    sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block", (uint8_t)a1,
+            (uint8_t)a2);
+    return open(buf, O_RDWR, 0);
+  } else {
+    char buf[1024];
+    char* hash;
+    NONFAILING(strncpy(buf, (char*)a0, sizeof(buf) - 1));
+    buf[sizeof(buf) - 1] = 0;
+    while ((hash = strchr(buf, '#'))) {
+      *hash = '0' + (char)(a1 % 10);
+      a1 /= 10;
+    }
+    return open(buf, a2, 0);
+  }
+}
+
+struct fs_image_segment {
+  void* data;
+  uintptr_t size;
+  uintptr_t offset;
+};
+
+#define IMAGE_MAX_SEGMENTS 4096
+#define IMAGE_MAX_SIZE (129 << 20)
+
+#define sys_memfd_create 319
+
+static unsigned long fs_image_segment_check(unsigned long size,
+                                            unsigned long nsegs, long segments)
+{
+  unsigned long i;
+  struct fs_image_segment* segs = (struct fs_image_segment*)segments;
+  if (nsegs > IMAGE_MAX_SEGMENTS)
+    nsegs = IMAGE_MAX_SEGMENTS;
+  for (i = 0; i < nsegs; i++) {
+    if (segs[i].size > IMAGE_MAX_SIZE)
+      segs[i].size = IMAGE_MAX_SIZE;
+    segs[i].offset %= IMAGE_MAX_SIZE;
+    if (segs[i].offset > IMAGE_MAX_SIZE - segs[i].size)
+      segs[i].offset = IMAGE_MAX_SIZE - segs[i].size;
+    if (size < segs[i].offset + segs[i].offset)
+      size = segs[i].offset + segs[i].offset;
+  }
+  if (size > IMAGE_MAX_SIZE)
+    size = IMAGE_MAX_SIZE;
+  return size;
+}
+
+static long syz_mount_image(volatile long fsarg, volatile long dir,
+                            volatile unsigned long size,
+                            volatile unsigned long nsegs,
+                            volatile long segments, volatile long flags,
+                            volatile long optsarg)
+{
+  char loopname[64], fs[32], opts[256];
+  int loopfd, err = 0, res = -1;
+  unsigned long i;
+  NONFAILING(size = fs_image_segment_check(size, nsegs, segments));
+  int memfd = syscall(sys_memfd_create, "syz_mount_image", 0);
+  if (memfd == -1) {
+    err = errno;
+    goto error;
+  }
+  if (ftruncate(memfd, size)) {
+    err = errno;
+    goto error_close_memfd;
+  }
+  for (i = 0; i < nsegs; i++) {
+    struct fs_image_segment* segs = (struct fs_image_segment*)segments;
+    int res1 = 0;
+    NONFAILING(res1 =
+                   pwrite(memfd, segs[i].data, segs[i].size, segs[i].offset));
+    if (res1 < 0) {
+    }
+  }
+  snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid);
+  loopfd = open(loopname, O_RDWR);
+  if (loopfd == -1) {
+    err = errno;
+    goto error_close_memfd;
+  }
+  if (ioctl(loopfd, LOOP_SET_FD, memfd)) {
+    if (errno != EBUSY) {
+      err = errno;
+      goto error_close_loop;
+    }
+    ioctl(loopfd, LOOP_CLR_FD, 0);
+    usleep(1000);
+    if (ioctl(loopfd, LOOP_SET_FD, memfd)) {
+      err = errno;
+      goto error_close_loop;
+    }
+  }
+  mkdir((char*)dir, 0777);
+  memset(fs, 0, sizeof(fs));
+  NONFAILING(strncpy(fs, (char*)fsarg, sizeof(fs) - 1));
+  memset(opts, 0, sizeof(opts));
+  NONFAILING(strncpy(opts, (char*)optsarg, sizeof(opts) - 32));
+  if (strcmp(fs, "iso9660") == 0) {
+    flags |= MS_RDONLY;
+  } else if (strncmp(fs, "ext", 3) == 0) {
+    if (strstr(opts, "errors=panic") || strstr(opts, "errors=remount-ro") == 0)
+      strcat(opts, ",errors=continue");
+  } else if (strcmp(fs, "xfs") == 0) {
+    strcat(opts, ",nouuid");
+  }
+  if (mount(loopname, (char*)dir, fs, flags, opts)) {
+    err = errno;
+    goto error_clear_loop;
+  }
+  res = 0;
+error_clear_loop:
+  ioctl(loopfd, LOOP_CLR_FD, 0);
+error_close_loop:
+  close(loopfd);
+error_close_memfd:
+  close(memfd);
+error:
+  errno = err;
+  return res;
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void reset_loop()
+{
+  char buf[64];
+  snprintf(buf, sizeof(buf), "/dev/loop%llu", procid);
+  int loopfd = open(buf, O_RDWR);
+  if (loopfd != -1) {
+    ioctl(loopfd, LOOP_CLR_FD, 0);
+    close(loopfd);
+  }
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+}
+
+struct thread_t {
+  int created, call;
+  event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+  struct thread_t* th = (struct thread_t*)arg;
+  for (;;) {
+    event_wait(&th->ready);
+    event_reset(&th->ready);
+    execute_call(th->call);
+    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+    event_set(&th->done);
+  }
+  return 0;
+}
+
+static void execute_one(void)
+{
+  int i, call, thread;
+  int collide = 0;
+again:
+  for (call = 0; call < 26; call++) {
+    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+         thread++) {
+      struct thread_t* th = &threads[thread];
+      if (!th->created) {
+        th->created = 1;
+        event_init(&th->ready);
+        event_init(&th->done);
+        event_set(&th->done);
+        thread_start(thr, th);
+      }
+      if (!event_isset(&th->done))
+        continue;
+      event_reset(&th->done);
+      th->call = call;
+      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+      event_set(&th->ready);
+      if (collide && (call % 2) == 0)
+        break;
+      event_timedwait(&th->done, 45 + (call == 9 ? 100 : 0));
+      break;
+    }
+  }
+  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+    sleep_ms(1);
+  if (!collide) {
+    collide = 1;
+    goto again;
+  }
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  int iter;
+  for (iter = 0;; iter++) {
+    reset_loop();
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      setup_test();
+      execute_one();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+  }
+}
+
+uint64_t r[8] = {0xffffffffffffffff, 0xffffffffffffffff,
+                 0xffffffffffffffff, 0x0,
+                 0xffffffffffffffff, 0xffffffffffffffff,
+                 0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_call(int call)
+{
+  intptr_t res;
+  switch (call) {
+  case 0:
+    NONFAILING(*(uint32_t*)0x20000200 = 0);
+    NONFAILING(*(uint32_t*)0x20000204 = 0x70);
+    NONFAILING(*(uint8_t*)0x20000208 = 3);
+    NONFAILING(*(uint8_t*)0x20000209 = 0);
+    NONFAILING(*(uint8_t*)0x2000020a = 0);
+    NONFAILING(*(uint8_t*)0x2000020b = 0);
+    NONFAILING(*(uint32_t*)0x2000020c = 0);
+    NONFAILING(*(uint64_t*)0x20000210 = 0xa);
+    NONFAILING(*(uint64_t*)0x20000218 = 0);
+    NONFAILING(*(uint64_t*)0x20000220 = 0);
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 0, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 1, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 2, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 3, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 4, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 5, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 6, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 7, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 8, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 9, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 10, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 11, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 12, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 13, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 14, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 15, 2));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 17, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 18, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 19, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 20, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 21, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 22, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 23, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 24, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 25, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 26, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 27, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 28, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 29, 35));
+    NONFAILING(*(uint32_t*)0x20000230 = 0);
+    NONFAILING(*(uint32_t*)0x20000234 = 0);
+    NONFAILING(*(uint64_t*)0x20000238 = 0);
+    NONFAILING(*(uint64_t*)0x20000240 = 0);
+    NONFAILING(*(uint64_t*)0x20000248 = 0);
+    NONFAILING(*(uint64_t*)0x20000250 = 0);
+    NONFAILING(*(uint32_t*)0x20000258 = 0);
+    NONFAILING(*(uint32_t*)0x2000025c = 0);
+    NONFAILING(*(uint64_t*)0x20000260 = 0);
+    NONFAILING(*(uint32_t*)0x20000268 = 0);
+    NONFAILING(*(uint16_t*)0x2000026c = 0);
+    NONFAILING(*(uint16_t*)0x2000026e = 0);
+    syscall(__NR_perf_event_open, 0x20000200ul, 0, -1ul, -1, 0ul);
+    break;
+  case 1:
+    syscall(__NR_clock_getres, 0ul, 0ul);
+    break;
+  case 2:
+    syscall(__NR_ioctl, -1, 0xae03ul, 0ul);
+    break;
+  case 3:
+    NONFAILING(*(uint32_t*)0x20000200 = 0);
+    NONFAILING(*(uint32_t*)0x20000204 = 0x70);
+    NONFAILING(*(uint8_t*)0x20000208 = 3);
+    NONFAILING(*(uint8_t*)0x20000209 = 0);
+    NONFAILING(*(uint8_t*)0x2000020a = 0);
+    NONFAILING(*(uint8_t*)0x2000020b = 0);
+    NONFAILING(*(uint32_t*)0x2000020c = 0);
+    NONFAILING(*(uint64_t*)0x20000210 = 8);
+    NONFAILING(*(uint64_t*)0x20000218 = 0);
+    NONFAILING(*(uint64_t*)0x20000220 = 0);
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 0, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 1, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 2, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 3, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 4, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 5, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 6, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 7, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 8, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 9, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 10, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 11, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 12, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 13, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 14, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 15, 2));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 17, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 18, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 19, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 20, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 21, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 22, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 23, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 24, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 25, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 26, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 27, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 28, 1));
+    NONFAILING(STORE_BY_BITMASK(uint64_t, , 0x20000228, 0, 29, 35));
+    NONFAILING(*(uint32_t*)0x20000230 = 0);
+    NONFAILING(*(uint32_t*)0x20000234 = 0);
+    NONFAILING(*(uint64_t*)0x20000238 = 0x20000000);
+    NONFAILING(*(uint64_t*)0x20000240 = 0);
+    NONFAILING(*(uint64_t*)0x20000248 = 0);
+    NONFAILING(*(uint64_t*)0x20000250 = 0);
+    NONFAILING(*(uint32_t*)0x20000258 = 0);
+    NONFAILING(*(uint32_t*)0x2000025c = 0);
+    NONFAILING(*(uint64_t*)0x20000260 = 0);
+    NONFAILING(*(uint32_t*)0x20000268 = 0);
+    NONFAILING(*(uint16_t*)0x2000026c = 0);
+    NONFAILING(*(uint16_t*)0x2000026e = 0);
+    res = syscall(__NR_perf_event_open, 0x20000200ul, 0, -1ul, -1, 0ul);
+    if (res != -1)
+      r[0] = res;
+    break;
+  case 4:
+    res = syscall(__NR_fcntl, r[0], 0ul, -1);
+    if (res != -1)
+      r[1] = res;
+    break;
+  case 5:
+    NONFAILING(memcpy((void*)0x20000000, "/dev/dmmidi#\000", 13));
+    res = syz_open_dev(0x20000000, 0x40, 0x22000);
+    if (res != -1)
+      r[2] = res;
+    break;
+  case 6:
+    res = syscall(__NR_ioctl, -1, 0xc0086420ul, 0x20000040ul);
+    if (res != -1)
+      NONFAILING(r[3] = *(uint32_t*)0x20000040);
+    break;
+  case 7:
+    NONFAILING(*(uint32_t*)0x20000080 = r[3]);
+    NONFAILING(*(uint32_t*)0x20000084 = 1);
+    syscall(__NR_ioctl, r[2], 0xc0086423ul, 0x20000080ul);
+    break;
+  case 8:
+    NONFAILING(*(uint32_t*)0x20000440 = r[3]);
+    NONFAILING(*(uint32_t*)0x20000444 = 6);
+    NONFAILING(*(uint64_t*)0x20000448 = 0x200002c0);
+    NONFAILING(*(uint32_t*)0x200002c0 = 0x7ff);
+    NONFAILING(*(uint32_t*)0x200002c4 = 2);
+    NONFAILING(*(uint32_t*)0x200002c8 = 9);
+    NONFAILING(*(uint32_t*)0x200002cc = 0xf1);
+    NONFAILING(*(uint32_t*)0x200002d0 = 0);
+    NONFAILING(*(uint32_t*)0x200002d4 = 6);
+    NONFAILING(*(uint64_t*)0x20000450 = 0x20000300);
+    NONFAILING(*(uint32_t*)0x20000300 = 9);
+    NONFAILING(*(uint32_t*)0x20000458 = 4);
+    NONFAILING(*(uint32_t*)0x2000045c = 5);
+    NONFAILING(*(uint32_t*)0x20000460 = 0x600);
+    NONFAILING(*(uint64_t*)0x20000468 = 0x20000380);
+    NONFAILING(*(uint32_t*)0x20000380 = 8);
+    NONFAILING(*(uint32_t*)0x20000384 = 0x70);
+    NONFAILING(*(uint32_t*)0x20000388 = 0x1f);
+    NONFAILING(*(uint32_t*)0x2000038c = 0xffffffc6);
+    NONFAILING(*(uint32_t*)0x20000390 = 0x7e5);
+    NONFAILING(*(uint64_t*)0x20000470 = 0x20000400);
+    NONFAILING(*(uint32_t*)0x20000400 = 1);
+    NONFAILING(*(uint32_t*)0x20000404 = 0x1fe000);
+    NONFAILING(*(uint32_t*)0x20000408 = 5);
+    NONFAILING(*(uint32_t*)0x2000040c = 0xeb8);
+    NONFAILING(*(uint32_t*)0x20000478 = 0);
+    syscall(__NR_ioctl, r[1], 0xc0406429ul, 0x20000440ul);
+    break;
+  case 9:
+    NONFAILING(*(uint64_t*)0x200001c0 = 0x20000000);
+    NONFAILING(memcpy((void*)0x20000000,
+                      "\xeb\x3c\x90\x6d\x6b\x66\x73\x2e\x66\x61\x74\x00\x02\x04"
+                      "\x01\x00\x02\x00\x02\x74\x00\xf8",
+                      22));
+    NONFAILING(*(uint64_t*)0x200001c8 = 0x16);
+    NONFAILING(*(uint64_t*)0x200001d0 = 0);
+    syz_mount_image(0, 0, 0xe800, 1, 0x200001c0, 0, 0x20000240);
+    break;
+  case 10:
+    NONFAILING(memcpy((void*)0x20021000, "./file0\000", 8));
+    res = syscall(__NR_open, 0x20021000ul, 0ul, 0ul);
+    if (res != -1)
+      r[4] = res;
+    break;
+  case 11:
+    syscall(__NR_getdents, -1, 0x20000000ul, 0xd6147cbb6f273a13ul);
+    break;
+  case 12:
+    syscall(__NR_ioctl, -1, 0x7002ul, 0);
+    break;
+  case 13:
+    res = syscall(__NR_socket, 0x29ul, 5ul, 0ul);
+    if (res != -1)
+      r[5] = res;
+    break;
+  case 14:
+    syscall(__NR_sendfile, r[5], -1, 0ul, 0xfffffffful);
+    break;
+  case 15:
+    res = syscall(__NR_socket, 0x10ul, 3ul, 0x10ul);
+    if (res != -1)
+      r[6] = res;
+    break;
+  case 16:
+    syscall(__NR_sendmsg, r[6], 0ul, 0ul);
+    break;
+  case 17:
+    syscall(__NR_ioctl, -1, 0x400454cdul, 0x305ul);
+    break;
+  case 18:
+    syscall(__NR_fchdir, r[4]);
+    break;
+  case 19:
+    NONFAILING(memcpy((void*)0x200001c0, "./bus\000", 6));
+    res = syscall(__NR_open, 0x200001c0ul, 0x141042ul, 0ul);
+    if (res != -1)
+      r[7] = res;
+    break;
+  case 20:
+    NONFAILING(*(uint32_t*)0x20000340 = 0xc);
+    syscall(__NR_getsockopt, -1, 0ul, 0x11ul, 0x20000280ul, 0x20000340ul);
+    break;
+  case 21:
+    NONFAILING(*(uint64_t*)0x200003c0 = 5);
+    syscall(__NR_fcntl, -1, 0x40eul, 0x200003c0ul);
+    break;
+  case 22:
+    syscall(__NR_sched_yield);
+    break;
+  case 23:
+    NONFAILING(*(uint32_t*)0x200000c0 = 0);
+    NONFAILING(*(uint16_t*)0x200000c4 = 0x18);
+    NONFAILING(*(uint16_t*)0x200000c6 = 0xfa00);
+    NONFAILING(*(uint64_t*)0x200000c8 = 0);
+    NONFAILING(*(uint64_t*)0x200000d0 = 0);
+    NONFAILING(*(uint16_t*)0x200000d8 = 0);
+    NONFAILING(*(uint8_t*)0x200000da = 9);
+    NONFAILING(*(uint8_t*)0x200000db = 0);
+    NONFAILING(*(uint8_t*)0x200000dc = 0);
+    NONFAILING(*(uint8_t*)0x200000dd = 0);
+    NONFAILING(*(uint8_t*)0x200000de = 0);
+    NONFAILING(*(uint8_t*)0x200000df = 0);
+    syscall(__NR_write, r[7], 0x200000c0ul, 0x20ul);
+    break;
+  case 24:
+    NONFAILING(*(uint32_t*)0x20000140 = 0);
+    NONFAILING(*(uint16_t*)0x20000144 = 0x18);
+    NONFAILING(*(uint16_t*)0x20000146 = 0xfa00);
+    NONFAILING(*(uint64_t*)0x20000148 = 0);
+    NONFAILING(*(uint64_t*)0x20000150 = 0);
+    NONFAILING(*(uint16_t*)0x20000158 = 0);
+    NONFAILING(*(uint8_t*)0x2000015a = 0);
+    NONFAILING(*(uint8_t*)0x2000015b = 0);
+    NONFAILING(*(uint8_t*)0x2000015c = 0);
+    NONFAILING(*(uint8_t*)0x2000015d = 0);
+    NONFAILING(*(uint8_t*)0x2000015e = 0);
+    NONFAILING(*(uint8_t*)0x2000015f = 0);
+    syscall(__NR_write, r[7], 0x20000140ul, 0x20ul);
+    break;
+  case 25:
+    NONFAILING(*(uint64_t*)0x20000040 = 0);
+    syscall(__NR_sendfile, r[7], r[7], 0x20000040ul, 0x8080fffffffeul);
+    break;
+  }
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  install_segv_handler();
+  for (procid = 0; procid < 6; procid++) {
+    if (fork() == 0) {
+      loop();
+    }
+  }
+  sleep(1000000);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0882292577b73fb3a92d45780882a121aa896b83.c b/syzkaller-repros/linux/0882292577b73fb3a92d45780882a121aa896b83.c
new file mode 100644
index 0000000..4e9917c
--- /dev/null
+++ b/syzkaller-repros/linux/0882292577b73fb3a92d45780882a121aa896b83.c
@@ -0,0 +1,317 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+#include <linux/in6.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/veth.h>
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+static long syz_open_dev(volatile long a0, volatile long a1, volatile long a2)
+{
+  if (a0 == 0xc || a0 == 0xb) {
+    char buf[128];
+    sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block", (uint8_t)a1,
+            (uint8_t)a2);
+    return open(buf, O_RDWR, 0);
+  } else {
+    char buf[1024];
+    char* hash;
+    strncpy(buf, (char*)a0, sizeof(buf) - 1);
+    buf[sizeof(buf) - 1] = 0;
+    while ((hash = strchr(buf, '#'))) {
+      *hash = '0' + (char)(a1 % 10);
+      a1 /= 10;
+    }
+    return open(buf, a2, 0);
+  }
+}
+
+uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+                 0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  memcpy((void*)0x200000c0, "/dev/dri/card#\000", 15);
+  res = syz_open_dev(0x200000c0, 0x200, 0x101000);
+  if (res != -1)
+    r[0] = res;
+  memcpy((void*)0x20000000, "/dev/ion\000", 9);
+  res =
+      syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000000ul, 0x141080ul, 0ul);
+  if (res != -1)
+    r[1] = res;
+  *(uint64_t*)0x20000040 = 0xa925;
+  *(uint32_t*)0x20000048 = 0x2b;
+  *(uint32_t*)0x2000004c = 0;
+  *(uint32_t*)0x20000050 = -1;
+  *(uint32_t*)0x20000054 = 0;
+  res = syscall(__NR_ioctl, r[1], 0xc0184900ul, 0x20000040ul);
+  if (res != -1)
+    r[2] = *(uint32_t*)0x20000050;
+  res = syscall(__NR_dup, r[2]);
+  if (res != -1)
+    r[3] = res;
+  *(uint32_t*)0x20000080 = 0;
+  *(uint32_t*)0x20000084 = 0;
+  *(uint32_t*)0x20000088 = r[3];
+  syscall(__NR_ioctl, r[0], 0xc00c642eul, 0x20000080ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/08cce7d51dda77c5900eaedcc3a6acf2f5ad0d3e.c b/syzkaller-repros/linux/08cce7d51dda77c5900eaedcc3a6acf2f5ad0d3e.c
new file mode 100644
index 0000000..9aac60e
--- /dev/null
+++ b/syzkaller-repros/linux/08cce7d51dda77c5900eaedcc3a6acf2f5ad0d3e.c
@@ -0,0 +1,280 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/futex.h>
+
+static __thread int skip_segv;
+static __thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* ctx)
+{
+  uintptr_t addr = (uintptr_t)info->si_addr;
+  const uintptr_t prog_start = 1 << 20;
+  const uintptr_t prog_end = 100 << 20;
+  if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) &&
+      (addr < prog_start || addr > prog_end)) {
+    _longjmp(segv_env, 1);
+  }
+  exit(sig);
+}
+
+static void install_segv_handler(void)
+{
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = SIG_IGN;
+  syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
+  syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_sigaction = segv_handler;
+  sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+  sigaction(SIGSEGV, &sa, NULL);
+  sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...)                                                        \
+  {                                                                            \
+    __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
+    if (_setjmp(segv_env) == 0) {                                              \
+      __VA_ARGS__;                                                             \
+    }                                                                          \
+    __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
+  }
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+  pthread_t th;
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setstacksize(&attr, 128 << 10);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (pthread_create(&th, &attr, fn, arg) == 0) {
+      pthread_attr_destroy(&attr);
+      return;
+    }
+    if (errno == EAGAIN) {
+      usleep(50);
+      continue;
+    }
+    break;
+  }
+  exit(1);
+}
+
+typedef struct {
+  int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+  if (ev->state)
+    exit(1);
+  __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
+  syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG);
+}
+
+static void event_wait(event_t* ev)
+{
+  while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
+}
+
+static int event_isset(event_t* ev)
+{
+  return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+  uint64_t start = current_time_ms();
+  uint64_t now = start;
+  for (;;) {
+    uint64_t remain = timeout - (now - start);
+    struct timespec ts;
+    ts.tv_sec = remain / 1000;
+    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
+    if (__atomic_load_n(&ev->state, __ATOMIC_RELAXED))
+      return 1;
+    now = current_time_ms();
+    if (now - start > timeout)
+      return 0;
+  }
+}
+
+static long syz_open_dev(volatile long a0, volatile long a1, volatile long a2)
+{
+  if (a0 == 0xc || a0 == 0xb) {
+    char buf[128];
+    sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block", (uint8_t)a1,
+            (uint8_t)a2);
+    return open(buf, O_RDWR, 0);
+  } else {
+    char buf[1024];
+    char* hash;
+    NONFAILING(strncpy(buf, (char*)a0, sizeof(buf) - 1));
+    buf[sizeof(buf) - 1] = 0;
+    while ((hash = strchr(buf, '#'))) {
+      *hash = '0' + (char)(a1 % 10);
+      a1 /= 10;
+    }
+    return open(buf, a2, 0);
+  }
+}
+
+struct thread_t {
+  int created, call;
+  event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+  struct thread_t* th = (struct thread_t*)arg;
+  for (;;) {
+    event_wait(&th->ready);
+    event_reset(&th->ready);
+    execute_call(th->call);
+    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+    event_set(&th->done);
+  }
+  return 0;
+}
+
+static void loop(void)
+{
+  int i, call, thread;
+  int collide = 0;
+again:
+  for (call = 0; call < 3; call++) {
+    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+         thread++) {
+      struct thread_t* th = &threads[thread];
+      if (!th->created) {
+        th->created = 1;
+        event_init(&th->ready);
+        event_init(&th->done);
+        event_set(&th->done);
+        thread_start(thr, th);
+      }
+      if (!event_isset(&th->done))
+        continue;
+      event_reset(&th->done);
+      th->call = call;
+      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+      event_set(&th->ready);
+      if (collide && (call % 2) == 0)
+        break;
+      event_timedwait(&th->done, 45);
+      break;
+    }
+  }
+  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+    sleep_ms(1);
+  if (!collide) {
+    collide = 1;
+    goto again;
+  }
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void execute_call(int call)
+{
+  intptr_t res;
+  switch (call) {
+  case 0:
+    syz_open_dev(0, 0, 0);
+    break;
+  case 1:
+    NONFAILING(memcpy((void*)0x20000000, "/dev/fd#\000", 9));
+    res = syz_open_dev(0x20000000, 0, 0x841);
+    if (res != -1)
+      r[0] = res;
+    break;
+  case 2:
+    NONFAILING(*(uint8_t*)0x20000040 = 0x8a);
+    NONFAILING(*(uint64_t*)0x20000048 = 6);
+    NONFAILING(*(uint64_t*)0x20000050 = 5);
+    NONFAILING(*(uint64_t*)0x20000058 = 0x10001);
+    NONFAILING(*(uint64_t*)0x20000060 = 0);
+    NONFAILING(*(uint64_t*)0x20000068 = 9);
+    NONFAILING(*(uint64_t*)0x20000070 = 0x1000);
+    NONFAILING(*(uint8_t*)0x20000078 = 8);
+    NONFAILING(*(uint8_t*)0x20000079 = 1);
+    NONFAILING(*(uint8_t*)0x2000007a = 0x40);
+    NONFAILING(*(uint8_t*)0x2000007b = 2);
+    NONFAILING(*(uint64_t*)0x20000080 = 0x10001);
+    NONFAILING(*(uint8_t*)0x20000088 = 9);
+    NONFAILING(*(uint32_t*)0x2000008c = 0x51);
+    NONFAILING(*(uint32_t*)0x20000090 = 0x7f);
+    NONFAILING(*(uint32_t*)0x20000094 = 0);
+    NONFAILING(*(uint32_t*)0x20000098 = 0x200);
+    NONFAILING(*(uint32_t*)0x2000009c = 1);
+    NONFAILING(*(uint8_t*)0x200000a0 = 2);
+    NONFAILING(*(uint8_t*)0x200000a1 = 3);
+    NONFAILING(*(uint16_t*)0x200000a2 = 0x2529);
+    NONFAILING(*(uint16_t*)0x200000a4 = 0xf344);
+    NONFAILING(*(uint16_t*)0x200000a6 = 8);
+    NONFAILING(*(uint16_t*)0x200000a8 = 0x405b);
+    NONFAILING(*(uint16_t*)0x200000aa = 2);
+    NONFAILING(*(uint16_t*)0x200000ac = 0xae6);
+    NONFAILING(*(uint16_t*)0x200000ae = 0);
+    NONFAILING(*(uint16_t*)0x200000b0 = 0);
+    NONFAILING(*(uint32_t*)0x200000b4 = 0);
+    NONFAILING(*(uint32_t*)0x200000b8 = 1);
+    syscall(__NR_ioctl, r[0], 0x40800290, 0x20000040);
+    break;
+  }
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+  install_segv_handler();
+  loop();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/08e23caab6df4fcf8d6e276eeb4e76b2593478f4.c b/syzkaller-repros/linux/08e23caab6df4fcf8d6e276eeb4e76b2593478f4.c
new file mode 100644
index 0000000..3535174
--- /dev/null
+++ b/syzkaller-repros/linux/08e23caab6df4fcf8d6e276eeb4e76b2593478f4.c
@@ -0,0 +1,806 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <sched.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/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/uio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <linux/capability.h>
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/if_tun.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/tcp.h>
+#include <linux/veth.h>
+
+unsigned long long procid;
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static void netlink_nest(struct nlmsg* nlmsg, int typ)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_type = typ;
+  nlmsg->pos += sizeof(*attr);
+  nlmsg->nested[nlmsg->nesting++] = attr;
+}
+
+static void netlink_done(struct nlmsg* nlmsg)
+{
+  struct nlattr* attr = nlmsg->nested[--nlmsg->nesting];
+  attr->nla_len = nlmsg->pos - (char*)attr;
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_add_device_impl(struct nlmsg* nlmsg, const char* type,
+                                    const char* name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  if (name)
+    netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name));
+  netlink_nest(nlmsg, IFLA_LINKINFO);
+  netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type));
+}
+
+static void netlink_add_device(struct nlmsg* nlmsg, int sock, const char* type,
+                               const char* name)
+{
+  netlink_add_device_impl(nlmsg, type, name);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_veth(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* peer)
+{
+  netlink_add_device_impl(nlmsg, "veth", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_nest(nlmsg, VETH_INFO_PEER);
+  nlmsg->pos += sizeof(struct ifinfomsg);
+  netlink_attr(nlmsg, IFLA_IFNAME, peer, strlen(peer));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_hsr(struct nlmsg* nlmsg, int sock, const char* name,
+                            const char* slave1, const char* slave2)
+{
+  netlink_add_device_impl(nlmsg, "hsr", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  int ifindex1 = if_nametoindex(slave1);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE1, &ifindex1, sizeof(ifindex1));
+  int ifindex2 = if_nametoindex(slave2);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE2, &ifindex2, sizeof(ifindex2));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_virt_wifi(struct nlmsg* nlmsg, int sock,
+                                  const char* name, const char* link)
+{
+  netlink_add_device_impl(nlmsg, "virt_wifi", name);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_vlan(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* link, uint16_t id, uint16_t proto)
+{
+  netlink_add_device_impl(nlmsg, "vlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_VLAN_ID, &id, sizeof(id));
+  netlink_attr(nlmsg, IFLA_VLAN_PROTOCOL, &proto, sizeof(proto));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_macvlan(struct nlmsg* nlmsg, int sock, const char* name,
+                                const char* link)
+{
+  netlink_add_device_impl(nlmsg, "macvlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  uint32_t mode = MACVLAN_MODE_BRIDGE;
+  netlink_attr(nlmsg, IFLA_MACVLAN_MODE, &mode, sizeof(mode));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+#define IFLA_IPVLAN_FLAGS 2
+#define IPVLAN_MODE_L3S 2
+#undef IPVLAN_F_VEPA
+#define IPVLAN_F_VEPA 2
+
+static void netlink_add_ipvlan(struct nlmsg* nlmsg, int sock, const char* name,
+                               const char* link, uint16_t mode, uint16_t flags)
+{
+  netlink_add_device_impl(nlmsg, "ipvlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_IPVLAN_MODE, &mode, sizeof(mode));
+  netlink_attr(nlmsg, IFLA_IPVLAN_FLAGS, &flags, sizeof(flags));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
+                            const void* addr, int addrsize)
+{
+  struct ifaddrmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
+  hdr.ifa_scope = RT_SCOPE_UNIVERSE;
+  hdr.ifa_index = if_nametoindex(dev);
+  netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
+  netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
+  return netlink_send(nlmsg, sock);
+}
+
+static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in_addr in_addr;
+  inet_pton(AF_INET, addr, &in_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
+  (void)err;
+}
+
+static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, addr, &in6_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+#define DEV_IPV4 "172.20.20.%d"
+#define DEV_IPV6 "fe80::%02x"
+#define DEV_MAC 0x00aaaaaaaaaa
+
+static void netdevsim_add(unsigned int addr, unsigned int port_count)
+{
+  char buf[16];
+  sprintf(buf, "%u %u", addr, port_count);
+  if (write_file("/sys/bus/netdevsim/new_device", buf)) {
+    snprintf(buf, sizeof(buf), "netdevsim%d", addr);
+    initialize_devlink_ports("netdevsim", buf, "netdevsim");
+  }
+}
+static void initialize_netdevices(void)
+{
+  char netdevsim[16];
+  sprintf(netdevsim, "netdevsim%d", (int)procid);
+  struct {
+    const char* type;
+    const char* dev;
+  } devtypes[] = {
+      {"ip6gretap", "ip6gretap0"}, {"bridge", "bridge0"},
+      {"vcan", "vcan0"},           {"bond", "bond0"},
+      {"team", "team0"},           {"dummy", "dummy0"},
+      {"nlmon", "nlmon0"},         {"caif", "caif0"},
+      {"batadv", "batadv0"},       {"vxcan", "vxcan1"},
+      {"netdevsim", netdevsim},    {"veth", 0},
+      {"xfrm", "xfrm0"},
+  };
+  const char* devmasters[] = {"bridge", "bond", "team"};
+  struct {
+    const char* name;
+    int macsize;
+    bool noipv6;
+  } devices[] = {
+      {"lo", ETH_ALEN},
+      {"sit0", 0},
+      {"bridge0", ETH_ALEN},
+      {"vcan0", 0, true},
+      {"tunl0", 0},
+      {"gre0", 0},
+      {"gretap0", ETH_ALEN},
+      {"ip_vti0", 0},
+      {"ip6_vti0", 0},
+      {"ip6tnl0", 0},
+      {"ip6gre0", 0},
+      {"ip6gretap0", ETH_ALEN},
+      {"erspan0", ETH_ALEN},
+      {"bond0", ETH_ALEN},
+      {"veth0", ETH_ALEN},
+      {"veth1", ETH_ALEN},
+      {"team0", ETH_ALEN},
+      {"veth0_to_bridge", ETH_ALEN},
+      {"veth1_to_bridge", ETH_ALEN},
+      {"veth0_to_bond", ETH_ALEN},
+      {"veth1_to_bond", ETH_ALEN},
+      {"veth0_to_team", ETH_ALEN},
+      {"veth1_to_team", ETH_ALEN},
+      {"veth0_to_hsr", ETH_ALEN},
+      {"veth1_to_hsr", ETH_ALEN},
+      {"hsr0", 0},
+      {"dummy0", ETH_ALEN},
+      {"nlmon0", 0},
+      {"vxcan0", 0, true},
+      {"vxcan1", 0, true},
+      {"caif0", ETH_ALEN},
+      {"batadv0", ETH_ALEN},
+      {netdevsim, ETH_ALEN},
+      {"xfrm0", ETH_ALEN},
+      {"veth0_virt_wifi", ETH_ALEN},
+      {"veth1_virt_wifi", ETH_ALEN},
+      {"virt_wifi0", ETH_ALEN},
+      {"veth0_vlan", ETH_ALEN},
+      {"veth1_vlan", ETH_ALEN},
+      {"vlan0", ETH_ALEN},
+      {"vlan1", ETH_ALEN},
+      {"macvlan0", ETH_ALEN},
+      {"macvlan1", ETH_ALEN},
+      {"ipvlan0", ETH_ALEN},
+      {"ipvlan1", ETH_ALEN},
+  };
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++)
+    netlink_add_device(&nlmsg, sock, devtypes[i].type, devtypes[i].dev);
+  for (i = 0; i < sizeof(devmasters) / (sizeof(devmasters[0])); i++) {
+    char master[32], slave0[32], veth0[32], slave1[32], veth1[32];
+    sprintf(slave0, "%s_slave_0", devmasters[i]);
+    sprintf(veth0, "veth0_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave0, veth0);
+    sprintf(slave1, "%s_slave_1", devmasters[i]);
+    sprintf(veth1, "veth1_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave1, veth1);
+    sprintf(master, "%s0", devmasters[i]);
+    netlink_device_change(&nlmsg, sock, slave0, false, master, 0, 0, NULL);
+    netlink_device_change(&nlmsg, sock, slave1, false, master, 0, 0, NULL);
+  }
+  netlink_device_change(&nlmsg, sock, "bridge_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "bridge_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_0", "veth0_to_hsr");
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_1", "veth1_to_hsr");
+  netlink_add_hsr(&nlmsg, sock, "hsr0", "hsr_slave_0", "hsr_slave_1");
+  netlink_device_change(&nlmsg, sock, "hsr_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "hsr_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "veth0_virt_wifi", "veth1_virt_wifi");
+  netlink_add_virt_wifi(&nlmsg, sock, "virt_wifi0", "veth1_virt_wifi");
+  netlink_add_veth(&nlmsg, sock, "veth0_vlan", "veth1_vlan");
+  netlink_add_vlan(&nlmsg, sock, "vlan0", "veth0_vlan", 0, htons(ETH_P_8021Q));
+  netlink_add_vlan(&nlmsg, sock, "vlan1", "veth0_vlan", 1, htons(ETH_P_8021AD));
+  netlink_add_macvlan(&nlmsg, sock, "macvlan0", "veth1_vlan");
+  netlink_add_macvlan(&nlmsg, sock, "macvlan1", "veth1_vlan");
+  netlink_add_ipvlan(&nlmsg, sock, "ipvlan0", "veth0_vlan", IPVLAN_MODE_L2, 0);
+  netlink_add_ipvlan(&nlmsg, sock, "ipvlan1", "veth0_vlan", IPVLAN_MODE_L3S,
+                     IPVLAN_F_VEPA);
+  netdevsim_add((int)procid, 4);
+  for (i = 0; i < sizeof(devices) / (sizeof(devices[0])); i++) {
+    char addr[32];
+    sprintf(addr, DEV_IPV4, i + 10);
+    netlink_add_addr4(&nlmsg, sock, devices[i].name, addr);
+    if (!devices[i].noipv6) {
+      sprintf(addr, DEV_IPV6, i + 10);
+      netlink_add_addr6(&nlmsg, sock, devices[i].name, addr);
+    }
+    uint64_t macaddr = DEV_MAC + ((i + 10ull) << 40);
+    netlink_device_change(&nlmsg, sock, devices[i].name, true, 0, &macaddr,
+                          devices[i].macsize, NULL);
+  }
+  close(sock);
+}
+static void initialize_netdevices_init(void)
+{
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  struct {
+    const char* type;
+    int macsize;
+    bool noipv6;
+    bool noup;
+  } devtypes[] = {
+      {"nr", 7, true},
+      {"rose", 5, true, true},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++) {
+    char dev[32], addr[32];
+    sprintf(dev, "%s%d", devtypes[i].type, (int)procid);
+    sprintf(addr, "172.30.%d.%d", i, (int)procid + 1);
+    netlink_add_addr4(&nlmsg, sock, dev, addr);
+    if (!devtypes[i].noipv6) {
+      sprintf(addr, "fe88::%02x:%02x", i, (int)procid + 1);
+      netlink_add_addr6(&nlmsg, sock, dev, addr);
+    }
+    int macsize = devtypes[i].macsize;
+    uint64_t macaddr = 0xbbbbbb +
+                       ((unsigned long long)i << (8 * (macsize - 2))) +
+                       (procid << (8 * (macsize - 1)));
+    netlink_device_change(&nlmsg, sock, dev, !devtypes[i].noup, 0, &macaddr,
+                          macsize, NULL);
+  }
+  close(sock);
+}
+
+static void setup_common()
+{
+  if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
+  }
+}
+
+static void loop();
+
+static void sandbox_common()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setsid();
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  if (dup2(netns, kInitNetNsFd) < 0)
+    exit(1);
+  close(netns);
+  struct rlimit rlim;
+  rlim.rlim_cur = rlim.rlim_max = (200 << 20);
+  setrlimit(RLIMIT_AS, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 32 << 20;
+  setrlimit(RLIMIT_MEMLOCK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 136 << 20;
+  setrlimit(RLIMIT_FSIZE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+  setrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 0;
+  setrlimit(RLIMIT_CORE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 256;
+  setrlimit(RLIMIT_NOFILE, &rlim);
+  if (unshare(CLONE_NEWNS)) {
+  }
+  if (unshare(CLONE_NEWIPC)) {
+  }
+  if (unshare(0x02000000)) {
+  }
+  if (unshare(CLONE_NEWUTS)) {
+  }
+  if (unshare(CLONE_SYSVSEM)) {
+  }
+  typedef struct {
+    const char* name;
+    const char* value;
+  } sysctl_t;
+  static const sysctl_t sysctls[] = {
+      {"/proc/sys/kernel/shmmax", "16777216"},
+      {"/proc/sys/kernel/shmall", "536870912"},
+      {"/proc/sys/kernel/shmmni", "1024"},
+      {"/proc/sys/kernel/msgmax", "8192"},
+      {"/proc/sys/kernel/msgmni", "1024"},
+      {"/proc/sys/kernel/msgmnb", "1024"},
+      {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
+    write_file(sysctls[i].name, sysctls[i].value);
+}
+
+int wait_for_loop(int pid)
+{
+  if (pid < 0)
+    exit(1);
+  int status = 0;
+  while (waitpid(-1, &status, __WALL) != pid) {
+  }
+  return WEXITSTATUS(status);
+}
+
+static void drop_caps(void)
+{
+  struct __user_cap_header_struct cap_hdr = {};
+  struct __user_cap_data_struct cap_data[2] = {};
+  cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
+  cap_hdr.pid = getpid();
+  if (syscall(SYS_capget, &cap_hdr, &cap_data))
+    exit(1);
+  const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
+  cap_data[0].effective &= ~drop;
+  cap_data[0].permitted &= ~drop;
+  cap_data[0].inheritable &= ~drop;
+  if (syscall(SYS_capset, &cap_hdr, &cap_data))
+    exit(1);
+}
+
+static int do_sandbox_none(void)
+{
+  if (unshare(CLONE_NEWPID)) {
+  }
+  int pid = fork();
+  if (pid != 0)
+    return wait_for_loop(pid);
+  setup_common();
+  sandbox_common();
+  drop_caps();
+  initialize_netdevices_init();
+  if (unshare(CLONE_NEWNET)) {
+  }
+  initialize_devlink_pci();
+  initialize_netdevices();
+  loop();
+  exit(1);
+}
+
+uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff};
+
+void loop(void)
+{
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 2ul, 2ul, 0ul);
+  if (res != -1)
+    r[0] = res;
+  memcpy((void*)0x20000600, "bridge_slave_1\000\000", 16);
+  *(uint32_t*)0x20000610 = 0;
+  res = syscall(__NR_ioctl, r[0], 0x8933ul, 0x20000600ul);
+  if (res != -1)
+    r[1] = *(uint32_t*)0x20000610;
+  *(uint64_t*)0x20000240 = 0;
+  *(uint32_t*)0x20000248 = 0;
+  *(uint64_t*)0x20000250 = 0x200000c0;
+  *(uint64_t*)0x200000c0 = 0x20000280;
+  memcpy((void*)0x20000280,
+         "\xcc\x00\x00\x00\x24\x00\x07\x8f\x96\xcd\x03\x37\xcc\xc5\x5e\xb2\x98"
+         "\x92\xa1\x37",
+         20);
+  *(uint32_t*)0x20000294 = r[1];
+  memcpy(
+      (void*)0x20000298,
+      "\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x09\x00\x01\x00\x6e\x65"
+      "\x74\x65\x6d\x00\x00\x00\x4c\x00\x02\x00\x00\x00\x00\x00\x00\x23\x58\x48"
+      "\x48\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x00\x00\x00\x00\x00\x00\x0c\x00"
+      "\x04\x00\x00\x00\xed\x6f\x65\x00\x00\x00\x0c\x00\x05\x00\x05\x22\x02\x00"
+      "\x00\x00\x00\x00\x0c\x00\x0b\x00\x00\x00\x00\x80\x00\x00\x00\x00\x0c\x00"
+      "\x03\x00\x00\x00\x00\x01\x00\x68\x74\xe9\xac\x68\x31\xbd\x62\x5d\x65\x05"
+      "\x00\x08\x00\x00\x00\x00\x00\x05\x00\x36\xba\x51\xa9\xec\xc5\xdd\x7f\xca"
+      "\x93\x66\xa9\xb5\x0c\xe6\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\xf3\xff"
+      "\x04\x02\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+      "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\xd5\xc0\x0e\x37\x12\x26\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00"
+      "\x02\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x00\xcf\xf6"
+      "\xae\x85\xf6\x23\xc1\xc7\x41\x0e\x1c\x94\xe0\xa1\x89\x12\xc2\x39\x89\x3b"
+      "\xa7\xee\x18\xe6\xb8\x7c\xc7\xeb\x42\x53\x57\xf8\x3f\xee\x96\xc9\xc3\x0b"
+      "\x2a\x9b\xde\xb9\x14\x79\xea\xfd\x9d\x18\xe6\x30\xab\xfb\x4a\x80\x9c\x74"
+      "\x26\x4f\x1c\xb2\x8e\xf7\xac\x3d\x3c\x34\xaf\x4a\x07\x9b\xd7\x52\x5e\x67"
+      "\x2a\x53\xa4\xd2\xd3\xe8\xa6\x05\x37\x06\x00\x00\x00\xcd\xea\xca\xa2\x61"
+      "\xe5\x20\x6c\xdd\x3e\xa4\xa8\x90\x5b\xf3\xf5\x9c\x38\x9a\x9f\xba\x15\x18"
+      "\xa2\x2b\xa4\x81\x89\xbf\x31\x36\x94\x41\x58\x78\x2e\x76\x64\x20\x65\xa0"
+      "\xa8\x46\x21\xeb\x10\x5a\xb7\x92\xa1\x86\xdf\x6d\x5d\x5b\xb7\x98\x00\x00"
+      "\x00\x00\x00\x00\x00",
+      383);
+  *(uint64_t*)0x200000c8 = 0xcc;
+  *(uint64_t*)0x20000258 = 1;
+  *(uint64_t*)0x20000260 = 0;
+  *(uint64_t*)0x20000268 = 0;
+  *(uint32_t*)0x20000270 = 0;
+  syscall(__NR_sendmsg, -1, 0x20000240ul, 0ul);
+  res = syscall(__NR_socket, 0x10ul, 0x80002ul, 0);
+  if (res != -1)
+    r[2] = res;
+  *(uint64_t*)0x20000180 = 2;
+  *(uint32_t*)0x20000188 = 0;
+  *(uint64_t*)0x20000190 = 0x20000080;
+  *(uint64_t*)0x20000198 = 0xe;
+  *(uint64_t*)0x200001a0 = 0x20000100;
+  *(uint64_t*)0x200001a8 = 0;
+  *(uint32_t*)0x200001b0 = 0;
+  syscall(__NR_sendmmsg, r[2], 0x20000180ul, 0x492492492492642ul, 0ul);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  do_sandbox_none();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0931801760a41b10cdc222d906b87096dfbc699b.c b/syzkaller-repros/linux/0931801760a41b10cdc222d906b87096dfbc699b.c
new file mode 100644
index 0000000..3801120
--- /dev/null
+++ b/syzkaller-repros/linux/0931801760a41b10cdc222d906b87096dfbc699b.c
@@ -0,0 +1,20 @@
+// autogenerated by syzkaller (http://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+#include <endian.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+void loop()
+{
+  syscall(__NR_shmget, 0, 0, 0, 0x20b39000);
+}
+
+int main()
+{
+  syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+  loop();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/09a650f7fd6360cfe594f52776cd08e4dea82d6f.c b/syzkaller-repros/linux/09a650f7fd6360cfe594f52776cd08e4dea82d6f.c
new file mode 100644
index 0000000..e2c2394
--- /dev/null
+++ b/syzkaller-repros/linux/09a650f7fd6360cfe594f52776cd08e4dea82d6f.c
@@ -0,0 +1,337 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.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/mount.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+unsigned long long procid;
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void use_temporary_dir(void)
+{
+  char tmpdir_template[] = "./syzkaller.XXXXXX";
+  char* tmpdir = mkdtemp(tmpdir_template);
+  if (!tmpdir)
+    exit(1);
+  if (chmod(tmpdir, 0777))
+    exit(1);
+  if (chdir(tmpdir))
+    exit(1);
+}
+
+#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
+#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
+  *(type*)(addr) =                                                             \
+      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
+            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+#define FS_IOC_SETFLAGS _IOW('f', 2, long)
+static void remove_dir(const char* dir)
+{
+  DIR* dp;
+  struct dirent* ep;
+  int iter = 0;
+retry:
+  while (umount2(dir, MNT_DETACH) == 0) {
+  }
+  dp = opendir(dir);
+  if (dp == NULL) {
+    if (errno == EMFILE) {
+      exit(1);
+    }
+    exit(1);
+  }
+  while ((ep = readdir(dp))) {
+    if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+      continue;
+    char filename[FILENAME_MAX];
+    snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
+    while (umount2(filename, MNT_DETACH) == 0) {
+    }
+    struct stat st;
+    if (lstat(filename, &st))
+      exit(1);
+    if (S_ISDIR(st.st_mode)) {
+      remove_dir(filename);
+      continue;
+    }
+    int i;
+    for (i = 0;; i++) {
+      if (unlink(filename) == 0)
+        break;
+      if (errno == EPERM) {
+        int fd = open(filename, O_RDONLY);
+        if (fd != -1) {
+          long flags = 0;
+          if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0)
+            close(fd);
+          continue;
+        }
+      }
+      if (errno == EROFS) {
+        break;
+      }
+      if (errno != EBUSY || i > 100)
+        exit(1);
+      if (umount2(filename, MNT_DETACH))
+        exit(1);
+    }
+  }
+  closedir(dp);
+  int i;
+  for (i = 0;; i++) {
+    if (rmdir(dir) == 0)
+      break;
+    if (i < 100) {
+      if (errno == EPERM) {
+        int fd = open(dir, O_RDONLY);
+        if (fd != -1) {
+          long flags = 0;
+          if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0)
+            close(fd);
+          continue;
+        }
+      }
+      if (errno == EROFS) {
+        break;
+      }
+      if (errno == EBUSY) {
+        if (umount2(dir, MNT_DETACH))
+          exit(1);
+        continue;
+      }
+      if (errno == ENOTEMPTY) {
+        if (iter < 100) {
+          iter++;
+          goto retry;
+        }
+      }
+    }
+    exit(1);
+  }
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  int iter;
+  for (iter = 0;; iter++) {
+    char cwdbuf[32];
+    sprintf(cwdbuf, "./%d", iter);
+    if (mkdir(cwdbuf, 0777))
+      exit(1);
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      if (chdir(cwdbuf))
+        exit(1);
+      setup_test();
+      execute_one();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+    remove_dir(cwdbuf);
+  }
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void execute_one(void)
+{
+  intptr_t res = 0;
+  *(uint32_t*)0x200000c0 = 0;
+  *(uint32_t*)0x200000c4 = 0x70;
+  *(uint8_t*)0x200000c8 = 3;
+  *(uint8_t*)0x200000c9 = 0;
+  *(uint8_t*)0x200000ca = 0;
+  *(uint8_t*)0x200000cb = 0;
+  *(uint32_t*)0x200000cc = 0;
+  *(uint64_t*)0x200000d0 = 8;
+  *(uint64_t*)0x200000d8 = 0;
+  *(uint64_t*)0x200000e0 = 0;
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 0, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 1, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 2, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 3, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 4, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 5, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 6, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 7, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 8, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 9, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 10, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 11, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 12, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 13, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 14, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 15, 2);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 17, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 18, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 19, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 20, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 21, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 22, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 23, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 24, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 25, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 26, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 27, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 28, 1);
+  STORE_BY_BITMASK(uint64_t, , 0x200000e8, 0, 29, 35);
+  *(uint32_t*)0x200000f0 = 0;
+  *(uint32_t*)0x200000f4 = 0;
+  *(uint64_t*)0x200000f8 = 0;
+  *(uint64_t*)0x20000100 = 0;
+  *(uint64_t*)0x20000108 = 0;
+  *(uint64_t*)0x20000110 = 0;
+  *(uint32_t*)0x20000118 = 0;
+  *(uint32_t*)0x2000011c = 0;
+  *(uint64_t*)0x20000120 = 0;
+  *(uint32_t*)0x20000128 = 0;
+  *(uint16_t*)0x2000012c = 0;
+  *(uint16_t*)0x2000012e = 0;
+  syscall(__NR_perf_event_open, 0x200000c0, 0, -1, -1, 0);
+  memcpy((void*)0x20000040, "./file0\000", 8);
+  res = syscall(__NR_open, 0x20000040, 0x141042, 0);
+  if (res != -1)
+    r[0] = res;
+  *(uint32_t*)0x20000140 = 1;
+  *(uint64_t*)0x20000148 = 0;
+  *(uint64_t*)0x20000150 = 0;
+  *(uint64_t*)0x20000158 = 0;
+  *(uint8_t*)0x20000160 = 0;
+  *(uint8_t*)0x20000161 = 1;
+  *(uint64_t*)0x20000168 = 0;
+  *(uint64_t*)0x20000170 = 0;
+  *(uint64_t*)0x20000178 = 0;
+  *(uint64_t*)0x20000180 = 0;
+  *(uint64_t*)0x20000188 = 0;
+  *(uint64_t*)0x20000190 = 0;
+  *(uint64_t*)0x20000198 = 0;
+  *(uint64_t*)0x200001a0 = 0;
+  syscall(__NR_write, r[0], 0x20000140, 0x68);
+  *(uint64_t*)0x200001c0 = 0;
+  syscall(__NR_sendfile, r[0], r[0], 0x200001c0, 0xa198);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+  for (procid = 0; procid < 8; procid++) {
+    if (fork() == 0) {
+      use_temporary_dir();
+      loop();
+    }
+  }
+  sleep(1000000);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/09e1ccbb75f46c836bdb470380be658050e66942.c b/syzkaller-repros/linux/09e1ccbb75f46c836bdb470380be658050e66942.c
new file mode 100644
index 0000000..9f7faa0
--- /dev/null
+++ b/syzkaller-repros/linux/09e1ccbb75f46c836bdb470380be658050e66942.c
@@ -0,0 +1,403 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <sched.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/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 <unistd.h>
+
+#include <linux/capability.h>
+#include <linux/if_addr.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/if_tun.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/tcp.h>
+#include <linux/veth.h>
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
+                            const void* addr, int addrsize)
+{
+  struct ifaddrmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
+  hdr.ifa_scope = RT_SCOPE_UNIVERSE;
+  hdr.ifa_index = if_nametoindex(dev);
+  netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
+  netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
+  return netlink_send(nlmsg, sock);
+}
+
+static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in_addr in_addr;
+  inet_pton(AF_INET, addr, &in_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
+  (void)err;
+}
+
+static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, addr, &in6_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
+  (void)err;
+}
+
+static void netlink_add_neigh(struct nlmsg* nlmsg, int sock, const char* name,
+                              const void* addr, int addrsize, const void* mac,
+                              int macsize)
+{
+  struct ndmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ndm_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ndm_ifindex = if_nametoindex(name);
+  hdr.ndm_state = NUD_PERMANENT;
+  netlink_init(nlmsg, RTM_NEWNEIGH, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, NDA_DST, addr, addrsize);
+  netlink_attr(nlmsg, NDA_LLADDR, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int tunfd = -1;
+static int tun_frags_enabled;
+
+#define TUN_IFACE "syz_tun"
+
+#define LOCAL_MAC 0xaaaaaaaaaaaa
+#define REMOTE_MAC 0xaaaaaaaaaabb
+
+#define LOCAL_IPV4 "172.20.20.170"
+#define REMOTE_IPV4 "172.20.20.187"
+
+#define LOCAL_IPV6 "fe80::aa"
+#define REMOTE_IPV6 "fe80::bb"
+
+#define IFF_NAPI 0x0010
+#define IFF_NAPI_FRAGS 0x0020
+
+static void initialize_tun(void)
+{
+  tunfd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
+  if (tunfd == -1) {
+    printf("tun: can't open /dev/net/tun: please enable CONFIG_TUN=y\n");
+    printf("otherwise fuzzing or reproducing might not work as intended\n");
+    return;
+  }
+  const int kTunFd = 240;
+  if (dup2(tunfd, kTunFd) < 0)
+    exit(1);
+  close(tunfd);
+  tunfd = kTunFd;
+  struct ifreq ifr;
+  memset(&ifr, 0, sizeof(ifr));
+  strncpy(ifr.ifr_name, TUN_IFACE, IFNAMSIZ);
+  ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+  if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) {
+    exit(1);
+  }
+  char sysctl[64];
+  sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/accept_dad", TUN_IFACE);
+  write_file(sysctl, "0");
+  sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/router_solicitations", TUN_IFACE);
+  write_file(sysctl, "0");
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  netlink_add_addr4(&nlmsg, sock, TUN_IFACE, LOCAL_IPV4);
+  netlink_add_addr6(&nlmsg, sock, TUN_IFACE, LOCAL_IPV6);
+  uint64_t macaddr = REMOTE_MAC;
+  struct in_addr in_addr;
+  inet_pton(AF_INET, REMOTE_IPV4, &in_addr);
+  netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in_addr, sizeof(in_addr),
+                    &macaddr, ETH_ALEN);
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, REMOTE_IPV6, &in6_addr);
+  netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in6_addr, sizeof(in6_addr),
+                    &macaddr, ETH_ALEN);
+  macaddr = LOCAL_MAC;
+  netlink_device_change(&nlmsg, sock, TUN_IFACE, true, 0, &macaddr, ETH_ALEN,
+                        NULL);
+  close(sock);
+}
+
+static void setup_common()
+{
+  if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
+  }
+}
+
+static void loop();
+
+static void sandbox_common()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setsid();
+  struct rlimit rlim;
+  rlim.rlim_cur = rlim.rlim_max = (200 << 20);
+  setrlimit(RLIMIT_AS, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 32 << 20;
+  setrlimit(RLIMIT_MEMLOCK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 136 << 20;
+  setrlimit(RLIMIT_FSIZE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+  setrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 0;
+  setrlimit(RLIMIT_CORE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 256;
+  setrlimit(RLIMIT_NOFILE, &rlim);
+  if (unshare(CLONE_NEWNS)) {
+  }
+  if (unshare(CLONE_NEWIPC)) {
+  }
+  if (unshare(0x02000000)) {
+  }
+  if (unshare(CLONE_NEWUTS)) {
+  }
+  if (unshare(CLONE_SYSVSEM)) {
+  }
+  typedef struct {
+    const char* name;
+    const char* value;
+  } sysctl_t;
+  static const sysctl_t sysctls[] = {
+      {"/proc/sys/kernel/shmmax", "16777216"},
+      {"/proc/sys/kernel/shmall", "536870912"},
+      {"/proc/sys/kernel/shmmni", "1024"},
+      {"/proc/sys/kernel/msgmax", "8192"},
+      {"/proc/sys/kernel/msgmni", "1024"},
+      {"/proc/sys/kernel/msgmnb", "1024"},
+      {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
+    write_file(sysctls[i].name, sysctls[i].value);
+}
+
+int wait_for_loop(int pid)
+{
+  if (pid < 0)
+    exit(1);
+  int status = 0;
+  while (waitpid(-1, &status, __WALL) != pid) {
+  }
+  return WEXITSTATUS(status);
+}
+
+static void drop_caps(void)
+{
+  struct __user_cap_header_struct cap_hdr = {};
+  struct __user_cap_data_struct cap_data[2] = {};
+  cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
+  cap_hdr.pid = getpid();
+  if (syscall(SYS_capget, &cap_hdr, &cap_data))
+    exit(1);
+  const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
+  cap_data[0].effective &= ~drop;
+  cap_data[0].permitted &= ~drop;
+  cap_data[0].inheritable &= ~drop;
+  if (syscall(SYS_capset, &cap_hdr, &cap_data))
+    exit(1);
+}
+
+static int do_sandbox_none(void)
+{
+  int pid = fork();
+  if (pid != 0)
+    return wait_for_loop(pid);
+  setup_common();
+  sandbox_common();
+  drop_caps();
+  if (unshare(CLONE_NEWNET)) {
+  }
+  initialize_tun();
+  loop();
+  exit(1);
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void loop(void)
+{
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0x14ul);
+  if (res != -1)
+    r[0] = res;
+  *(uint64_t*)0x20000000 = 0;
+  *(uint32_t*)0x20000008 = 0x500;
+  *(uint64_t*)0x20000010 = 0x200000c0;
+  *(uint64_t*)0x200000c0 = 0x20000100;
+  *(uint32_t*)0x20000100 = 0x38;
+  *(uint16_t*)0x20000104 = 0x1403;
+  *(uint16_t*)0x20000106 = 1;
+  *(uint32_t*)0x20000108 = 0;
+  *(uint32_t*)0x2000010c = 0;
+  *(uint16_t*)0x20000110 = 9;
+  *(uint16_t*)0x20000112 = 2;
+  memcpy((void*)0x20000114, "syz1\000", 5);
+  *(uint16_t*)0x2000011c = 8;
+  *(uint16_t*)0x2000011e = 0x41;
+  memcpy((void*)0x20000120, "rxe\000", 4);
+  *(uint16_t*)0x20000124 = 0x14;
+  *(uint16_t*)0x20000126 = 0x33;
+  memcpy((void*)0x20000128, "syz_tun\000\000\000\000\000\000\000\000\000", 16);
+  *(uint64_t*)0x200000c8 = 0x38;
+  *(uint64_t*)0x20000018 = 1;
+  *(uint64_t*)0x20000020 = 0;
+  *(uint64_t*)0x20000028 = 0;
+  *(uint32_t*)0x20000030 = 0;
+  syscall(__NR_sendmsg, r[0], 0x20000000ul, 0ul);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  do_sandbox_none();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0ab3f49f61f5706bf7883fa10ec9961175f74906.c b/syzkaller-repros/linux/0ab3f49f61f5706bf7883fa10ec9961175f74906.c
new file mode 100644
index 0000000..32ecffb
--- /dev/null
+++ b/syzkaller-repros/linux/0ab3f49f61f5706bf7883fa10ec9961175f74906.c
@@ -0,0 +1,100 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <endian.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 9ul);
+  if (res != -1)
+    r[0] = res;
+  *(uint64_t*)0x200004c0 = 0;
+  *(uint32_t*)0x200004c8 = 0;
+  *(uint64_t*)0x200004d0 = 0x20000480;
+  *(uint64_t*)0x20000480 = 0x20000000;
+  memcpy(
+      (void*)0x20000000,
+      "\x20\x04\x00\x00\xf4\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x08\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5"
+      "\xb9\xff\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4b\xe0"
+      "\x59\x72\x77\x02\xab\x76\x2a\x16\x63\x28\x94\xf9\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6e\x6e\xf9\xc5\xf1\x87"
+      "\x65\xfc\x7c\x8c\xc9\xc7\x07\xb8\x1b\xec\x5b\x72\x0a\xff\xc3\xfd\x54\x1b"
+      "\x90\x97\xd0\x0e\xf5\x0b\x0d\x58\xf3\x76\x09\x9b\xc3\x78\x51\x39\x20\xc9"
+      "\xa0\xf8\x87\x69\x35\x48\xd0\xf7\x7e\xf0\x69\x96\xf2\x1d\x23\x2d\xe5\x38"
+      "\x7f\x2c\x43\xea\xe6\x22\x9f\x61",
+      1124);
+  *(uint64_t*)0x20000488 = 0x420;
+  *(uint64_t*)0x200004d8 = 1;
+  *(uint64_t*)0x200004e0 = 0;
+  *(uint64_t*)0x200004e8 = 0;
+  *(uint32_t*)0x200004f0 = 0;
+  syscall(__NR_sendmsg, r[0], 0x200004c0ul, 0ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0bf321e31faa1d3d4b7c3c8930bc317288d05378.c b/syzkaller-repros/linux/0bf321e31faa1d3d4b7c3c8930bc317288d05378.c
new file mode 100644
index 0000000..0602970
--- /dev/null
+++ b/syzkaller-repros/linux/0bf321e31faa1d3d4b7c3c8930bc317288d05378.c
@@ -0,0 +1,437 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  int iter;
+  for (iter = 0;; iter++) {
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      setup_test();
+      execute_one();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+  }
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void execute_one(void)
+{
+  intptr_t res = 0;
+  memcpy((void*)0x20000080, "/dev/uhid\000", 10);
+  res = syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000080ul, 2ul, 0ul);
+  if (res != -1)
+    r[0] = res;
+  memcpy(
+      (void*)0x20000bc0,
+      "\x0b\x00\x00\x00\x73\x79\x7a\x31\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x01\x00\x73\x8d\x7a\x31\x00\x00\x00\x00\x00\xff\x07\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x79"
+      "\x7a\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\xcf\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x38\xe9\x67\xac\x82\x06\xea"
+      "\xae\x86\xb9\x7e\xec\x0b\x2b\xed\x1e\xe2\x33\x64\xb1\x0d\x6a\xad\x51\x02"
+      "\x00\x00\x00\xe2\xa1\xdb\x3c\x6a\x0d\xee\x4a\xfc\x66\xd2\x44\x28\x05\x20"
+      "\x1c\x39\x38\x9a\x80\x4c\x41\xc2\x99\x3f\xc6\x7e\x8a\x14\x60\x45\xe1\x4a"
+      "\x8a\x08\x00\x55\x0e\x6a\x25\xc0\xef\x65\xf6\xec\x71\xf0\x08\x42\x54\xd1"
+      "\x40\x18\x7f\xaf\xa4\xa1\xee\x6e\xce\x53\xc6\x73\x85\xb8\x83\xa3\x6a\xd2"
+      "\x4a\x04\x00\x00\x00\x00\x00\x00\x00\x6a\x8a\xb1\x1b\x0a\x0b\x00\xe7\x7e"
+      "\x6c\x16\x18\x9c\xfa\x16\xcb\xe0\x1a\x4c\xe4\x11\x37\x8e\xaa\xb7\x37\x2d"
+      "\xab\x5e\xef\x84\xc3\x1b\x2d\xad\x86\x8a\x53\xe6\xf5\xe6\x97\x46\xa7\x1e"
+      "\xc9\x2d\xca\xa9\xa7\xdf\xab\x39\x42\x86\xe5\xc8\x1e\xae\x45\xe3\xa2\x5b"
+      "\x94\x2b\x8d\xa1\x1e\xdb\x57\x8b\x45\x3a\xca\xc0\x3a\x9d\x34\x48\x00\x00"
+      "\x00\x00\x83\xd6\xd5\xfe\x4f\x83\x3d\x4d\x4c\xfb\xee\xf0\xe0\xe6\x2b\xe2"
+      "\x05\x00\x00\x00\x3c\x32\x98\x4c\x6c\x4b\x2b\x9c\x33\xd8\xa6\x24\xce\xa9"
+      "\x5c\x3b\x3c\x6d\xd8\x73\x56\x9c\xf4\x78\x6f\xc5\x16\x6b\x03\x00\x00\x00"
+      "\x00\x00\x1f\xf2\x8d\x3c\xe3\xe3\xb8\xf8\x1e\x34\xcf\x97\xc9\xc8\x41\xcb"
+      "\x2e\xf0\x81\x07\xa9\xa9\x65\x49\xe3\xd2\x59\xdf\x17\xe2\x9e\xd6\x4b\xd6"
+      "\x12\x08\x13\xf9\xf0\x34\x4e\x13\x95\x06\x70\x1e\x8f\xde\xdb\x06\x00\x9b"
+      "\x5e\x4d\x0c\x67\xbd\xa0\xb9\x28\xb7\x32\xcf\xf7\x82\xb0\x68\x40\x75\xf2"
+      "\xcb\x78\x51\xef\xdd\x77\x97\xee\x95\xd2\xac\x28\xa8\xca\xbd\x26\xc1\x56"
+      "\x82\xaa\x58\xd3\x1a\xec\x95\x6b\xd7\xc2\x78\x06\x40\x34\x34\xb3\xc3\x0b"
+      "\x07\x0b\xcc\x82\x66\xe1\x2f\xa6\x66\x02\x05\x62\x56\xf7\x46\x75\xb7\xcb"
+      "\x6a\x2c\xd9\x1a\x59\xde\x4d\x87\xb2\x70\x8d\x70\xc8\xf3\xdf\x53\xca\xf8"
+      "\xfe\x18\x0c\x4d\xea\x3f\x5b\x7a\x87\x1b\x30\xc7\xa5\x75\x3b\x48\xf7\xf0"
+      "\x91\x92\xa3\x4b\x0e\xfa\xab\x02\xdc\xa0\x51\x7e\xee\x10\xff\x30\x20\x6f"
+      "\x78\xec\x82\xc7\x2f\xe0\x08\x30\x83\x1d\xcd\x6e\x9d\xe6\xc6\x20\xa0\xe8"
+      "\xe0\xd0\x57\x0b\x43\x99\x41\x71\x3e\xf2\x8d\xdd\x5f\x84\x47\xbb\xf7\xa7"
+      "\xbc\xdc\x9d\x94\xa5\xdb\x17\x8b\x64\xa5\x5d\xc0\xd3\x73\xad\x4e\xf5\x58"
+      "\x00\x37\xea\x20\xb3\x4b\x2b\x0c\x88\x75\xac\xf8\x90\x9f\xe0\x50\xd6\x2e"
+      "\xe8\x5d\x1b\x3e\xa8\x76\xab\x40\x8e\xd3\xdf\x53\x1e\x79\x82\x3e\xb4\x05"
+      "\x6a\xa3\x3a\xe9\x20\x76\x46\xab\x9b\xa6\xd7\x93\x41\x22\x0d\x7c\x52\xe6"
+      "\x97\xd4\x04\x09\xc0\xb4\x65\x9a\x42\x98\x9d\x56\x79\x92\x71\x44\xa7\x19"
+      "\x68\x1c\x7b\xdf\x46\x1a\x34\x77\x5c\x75\x23\x69\xa1\x63\x6c\x92\xa2\xdf"
+      "\xc8\x68\xed\x0b\x3e\xa8\x49\x6f\xbe\xb1\x80\x8d\x7f\xd3\xa4\xfd\x4d\x52"
+      "\x1b\xc2\x44\x30\x6a\x13\xe3\x04\xf2\x0c\xb0\x3e\x7a\x54\x26\x42\x2f\x9b"
+      "\x91\xf2\xd4\x4c\x99\x9e\x21\xc6\xba\xcf\xf3\xbc\xa0\xd0\x3b\x95\x13\xe8"
+      "\x7f\xee\xf4\xb3\xca\x5c\xc4\x2e\x60\x26\x7a\x47\x8f\xa1\x1a\xb4\x6f\xc3"
+      "\x81\x2f\x75\xba\x64\x0d",
+      924);
+  syscall(__NR_write, r[0], 0x20000bc0ul, 0x12eul);
+  *(uint32_t*)0x20000300 = 8;
+  memcpy(
+      (void*)0x20000304,
+      "\xed\x4d\x2b\x70\x42\x8a\x2f\x63\x9e\xa9\xd5\x21\xe6\xff\x44\xdb\x2b\xc3"
+      "\x09\xbf\x0c\xd1\x00\x7c\x83\x31\xc0\xb0\xf4\x6e\x2e\xa0\xd8\xa9\xe8\xbb"
+      "\xcc\x4e\x8a\xf5\x3d\x63\xef\x9b\xdc\xe3\x8c\x83\xf4\x9d\xc1\x7e\xe9\xf2"
+      "\x55\x0f\x5a\x1b\x5d\x21\x62\x86\x9a\x7c\x72\x27\x51\x54\xfb\xa2\x9d\x0e"
+      "\x18\x61\x12\x6a\xe7\xa6\x66\xd1\xd0\xf0\x65\x6b\xbe\xd7\xf8\x5a\xbe\x1d"
+      "\x5b\x67\x97\x38\x0f\xb4\x7b\x47\x0c\xcb\x0b\x62\xc4\xe2\xf7\x45\xba\x6d"
+      "\x39\x95\x8e\xfe\xcd\xf2\x72\xec\x25\x48\x0f\xad\xc0\xb4\xd7\xe0\x6e\x27"
+      "\xe0\x61\x42\xa9\xc8\x32\xbd\x47\xb0\x3e\xf5\x19\x35\x2e\x5c\x67\xcd\x2a"
+      "\x0c\xd5\x31\x09\x59\x7f\xd0\xad\x07\x6c\x22\x3c\x69\x13\x75\x5f\x2c\x66"
+      "\x1a\x13\xc9\xbb\x95\x6d\x6a\xf4\x7c\xfd\x35\x78\x76\x9d\xeb\xbc\x99\xc8"
+      "\xbf\xf7\x06\x9e\xc7\x20\x4a\x00\x75\xcb\x7d\xb6\x90\x7b\x47\x47\xcb\x4b"
+      "\x66\x4c\x66\x4b\xb3\x77\x81\xf6\x37\x7b\xc3\x0d\x8a\x3c\xe0\x97\x9a\x6e"
+      "\xc0\x09\x73\xdb\x0d\x0d\x14\x76\xb2\xa9\x23\xce\xe6\x70\x6f\x10\xa9\x1e"
+      "\x8d\x92\x80\xcf\xb7\x10\x8e\x2f\x19\x49\xb9\x3c\xa0\x06\x5e\x9f\xa2\xc8"
+      "\xff\x21\xbc\xfd\xdd\xcb\xd7\xbd\x9f\x28\x2d\xd4\x6e\x55\x0c\x3d\xde\x68"
+      "\x60\x00\xbb\x94\x8d\x8f\x79\x00\x81\xc4\x28\x9e\xda\x17\x15\xde\x3f\x49"
+      "\xf6\xd2\x1f\xc4\x64\xe2\xc8\x25\x54\xff\x13\x99\x8b\xe2\xba\xf2\x32\xb7"
+      "\x77\x41\x5a\x66\xd1\x73\x3f\x23\x91\x5c\x27\x2b\xe7\x98\x1b\xc0\xb6\x56"
+      "\x9b\xf6\x74\x0c\x36\xcf\xc7\x7a\x47\xa8\x67\xe1\x3e\x6e\x57\xb1\xf8\x78"
+      "\x34\xb9\x5c\x18\x8d\x5c\xbf\xb3\xe3\x7c\xce\xc4\xd0\xcd\xce\x75\x18\xc1"
+      "\x5e\x8e\x1b\x1c\xd1\xf7\x57\x8d\x09\x5a\x47\x58\x28\x9d\xfa\xdb\x07\x3e"
+      "\x02\x6e\x02\xc8\xf8\xf0\x30\x39\x83\x00\x18\x41\x6c\x4d\x50\x21\x7a\xa8"
+      "\x8a\xdb\x35\x1a\xfc\x2e\x8a\x07\x6e\xb4\x3a\x83\x87\x8d\x2d\x19\x6a\x21"
+      "\x4a\x80\x96\xe8\x66\x33\x62\xd2\x06\x82\xa6\xca\x22\x81\x19\xc5\x7d\x37"
+      "\xac\xb9\x32\x9f\xe6\xd4\x1f\x1b\xec\xe6\x33\x4b\xe5\xda\xc1\x5e\x77\x87"
+      "\x3d\xde\x52\xae\xb5\xa9\xe4\x30\x19\x69\xfb\x40\x81\x6b\x27\xee\x57\xe9"
+      "\x76\xd0\xeb\x3c\x56\xc0\x34\x06\x7e\x58\xa3\x91\xf5\xba\x6e\xf8\x8b\x06"
+      "\xb5\xfc\xe2\x13\x44\x02\x76\x61\x91\x01\x25\xf9\x7f\x22\xd1\xf9\x6c\x04"
+      "\xeb\x48\x2f\x70\x4c\x27\x99\x36\x70\xcd\x87\x0c\xa5\x24\xd1\x93\x44\xc7"
+      "\xb2\xef\x72\xb2\xad\x4b\x4f\x31\x0a\x02\x69\x49\xfe\x9a\xb6\x9f\xcb\x93"
+      "\x5d\xd8\x3f\x47\xa9\x93\x66\x5a\x59\xb5\x4b\xa9\xde\xdc\xca\xf3\x1b\x6e"
+      "\xcf\xe9\x65\x4d\xe2\x02\x19\x13\x53\x57\xfd\x08\x93\x79\xae\xe7\x50\xf5"
+      "\x44\x7f\xb5\x6c\x53\x34\x11\x40\xeb\xa3\xbe\x19\xcc\x85\xbc\x34\x07\x53"
+      "\xa0\xb6\x3b\x3b\xe7\x21\x2d\x6b\x87\xc5\x29\x64\x6d\x55\x2e\x69\xde\x9a"
+      "\x3b\x28\xdb\xd2\x63\x32\x39\x73\x5c\x03\x8e\x0e\x3f\xd7\x84\xdc\x9e\xce"
+      "\xf2\x9b\xf3\x1e\x3f\x0f\x8a\xff\x97\x30\x37\xf2\x16\x14\xa7\xb2\x92\x37"
+      "\x3e\xf7\xda\xdf\x51\x8f\x4c\xed\x8e\xf2\xb8\x6d\xf3\x6e\x50\xc7\x69\xad"
+      "\x43\xdc\x2e\x24\x58\xa7\x41\x4e\x82\x86\xaa\x0b\xc3\x52\xe4\x99\xf7\x14"
+      "\xbf\xd0\xf2\x1b\x70\xfb\x53\x24\x0a\x5a\x2c\xc4\x9f\x02\x32\xba\xba\x28"
+      "\x79\xf8\x7f\xb8\x84\x3e\x01\xab\xb6\x16\x61\xa6\x53\x6d\xe0\x73\xd9\x8e"
+      "\x51\xe9\x73\x62\x26\x62\x5c\x76\x5e\xbb\x11\x88\x91\xdb\xa2\xc3\x15\xf0"
+      "\x21\x15\x30\x26\x0f\xe1\x55\x8c\xef\x91\x6d\x4b\x83\xb0\x66\x27\xc3\xc8"
+      "\x78\x5b\xb4\xbd\x68\x04\x50\xad\x16\xeb\xc0\xbe\x67\x40\x0d\x48\xdd\x66"
+      "\x66\xd7\xf8\x67\x46\x64\xe8\xc3\xc5\x85\xf2\x09\x96\x46\x04\xab\xc2\x98"
+      "\xb3\x8f\xc7\x28\xba\xf0\x69\x3d\xc6\x96\x78\xd6\x4d\xd0\x95\x64\xe5\x6a"
+      "\x17\x4c\x8a\x94\x53\x03\x55\x34\xd0\x47\xf2\xf4\x24\x0c\xb2\x51\xb7\xd8"
+      "\x01\x30\xe5\x81\x93\x88\x1b\xc9\x72\x89\x23\xfd\x75\x8b\x9b\x14\x48\x65"
+      "\xf8\xde\x24\x5d\xc8\x6f\xa9\xf3\x3b\x6f\xdf\x8e\x6b\xbe\x3a\x88\x83\x99"
+      "\xff\xde\x11\x3f\xde\x69\x10\x55\x76\x3a\xa8\x66\x2e\x89\x65\x29\xea\xbc"
+      "\xf8\x58\x9a\xbd\xec\x04\x70\x3d\x4a\x4f\x52\x9c\x4c\x85\xe1\x5f\x9c\xe9"
+      "\xbe\x67\xf4\x46\x9b\x06\xb8\xca\xf2\x44\xf1\xca\xe7\xae\x34\x70\x7a\x78"
+      "\x26\xd2\x5b\xcf\x53\x01\x0a\x38\x27\x67\xad\x44\x48\x53\x63\x67\x7a\x87"
+      "\x96\x31\x28\x8a\x84\x96\x05\x96\x16\x99\xff\x7a\xfe\xde\xc5\x1f\x6b\x72"
+      "\xf6\xb7\xc8\xa2\x4d\xc1\xe0\x40\xc9\x22\x9a\x22\x1c\x8b\x53\xbb\x1e\x04"
+      "\xb2\x11\xb5\x83\x53\xc7\x10\xad\xdb\xfb\x86\xbe\x55\x63\x15\x56\x35\xd9"
+      "\x64\x09\xc8\xd5\xe9\x8c\xa3\x93\xb0\xac\x98\xd8\x63\x9b\x63\xc6\xf5\x9f"
+      "\xf2\x9f\xf7\x8f\xc9\x6a\xaa\x97\x6f\x82\xa5\x59\xb3\xb8\xcb\x19\x98\xcd"
+      "\x5a\x26\x9a\x7e\xde\x5b\x88\x8b\x86\x69\x72\x93\x23\x6c\x77\x9a\xdf\xf4"
+      "\x1d\xfd\x81\x53\xbe\x2c\xb3\x2b\x3f\xaa\x22\x3c\x0c\x30\xe8\xe9\xf5\xb9"
+      "\x55\xa7\xc9\xcd\xf9\xc3\x68\x3b\x5b\x91\x2c\x1e\x80\xef\xa7\x39\x0c\xeb"
+      "\x25\x1a\x71\x95\xa5\x2d\x25\x49\xbe\xc4\x2d\x5b\x4e\xa8\xf0\x06\x20\xf6"
+      "\x54\x2d\x3a\x92\x31\x0a\x7b\x12\xab\xed\xc2\xdf\x8d\x0e\x45\xa5\xfc\xe8"
+      "\x3b\xe1\x9b\x68\xac\xac\x6a\x6d\x93\x7a\x87\x80\x36\x92\x7d\xde\x71\xe7"
+      "\xd4\xd2\xcb\x0a\xe0\x7a\x89\xdc\x03\xc7\xf5\x41\xcd\x05\x3f\x6d\xd1\x0f"
+      "\xbc\x51\x16\x52\x0e\xe6\x66\xcb\xe0\x3b\x31\x65\xbd\x22\x86\xb2\xd2\xc4"
+      "\x62\xb6\xfc\x12\xbf\xf1\x4f\x2e\x80\x66\xb1\x42\x3a\x36\x49\x9d\x1b\x87"
+      "\xa5\x8b\xb8\x12\x76\x1a\xe8\x1f\x87\xc6\x6d\x2f\xbb\x4d\xfa\x83\x8f\x4b"
+      "\x88\xa8\xf2\x1e\xf7\x51\xef\xf2\xec\x33\xff\xf5\x33\x3b\xa3\xd9\xb1\x29"
+      "\x52\xa4\xe6\x53\xbb\x57\xb1\x8d\x98\x64\x1d\x68\xf0\x8d\xbd\x0f\xaa\x92"
+      "\xcb\xa9\x03\x4a\x42\xed\x75\x69\xdb\xb8\x5f\x6e\x33\xc4\xb5\x30\x43\x67"
+      "\xe5\x82\xc6\xf2\xfb\x80\x43\xdc\xfb\xf4\x5a\x1a\x5a\xdb\xb5\x92\xc0\xbb"
+      "\x6e\x36\xed\x74\x25\xa2\x9b\x8d\xbd\x8f\x30\x67\x97\x64\x2a\xa6\xd3\x3c"
+      "\x15\xec\xf2\x65\x81\xc7\x43\x7e\x5d\xba\x45\x41\x91\xec\x8b\xa3\x25\xfc"
+      "\xd8\xe0\x9f\xd3\x14\xe3\xfa\x12\x99\x94\x9f\x19\x39\x73\x26\x80\x93\x0f"
+      "\x4b\x52\x30\xb3\x62\xdb\x56\x8a\x9e\x0a\xff\x70\x81\x4d\x33\xb0\x16\xb6"
+      "\x1a\x61\x77\x14\xab\xde\xe1\x28\xdd\x8c\x70\x82\x8c\xa5\xb7\x02\x65\x58"
+      "\x0b\x70\xa4\x6b\x19\xfa\x51\x99\x4a\x89\x5b\x89\x53\x29\xb7\x85\x76\x8b"
+      "\x09\xe5\xab\x00\x66\x8e\x72\x43\xf3\x6e\x19\x56\x13\x3a\x0f\xfe\xbb\x38"
+      "\xce\xdb\x25\x9b\x69\x44\xe0\x2e\x4a\x1e\x41\xe8\x31\x0d\x8e\x57\x9a\x93"
+      "\x71\x26\x43\x8d\x98\x09\x46\x32\xf2\x19\x1d\x97\x13\x32\x96\xa2\xa4\x19"
+      "\x3a\xee\x8d\xd4\x3f\x20\x0f\x34\x7d\xea\x42\xc8\xcb\xaa\x21\x5e\x94\x11"
+      "\x0c\xc4\x7b\xe1\xfb\x98\xa1\xe2\xd9\x22\xa8\x0b\x60\x6d\x0d\xcc\x8d\xd9"
+      "\xed\x9f\xa1\xff\xe2\x9b\x85\x25\xdb\x54\x1b\xd7\xf0\xf8\x4e\xcd\xf8\x90"
+      "\xdd\x22\x67\x9c\xf4\x38\xef\x07\xdc\x93\xed\x35\x4e\xdc\xcf\xe5\xd4\x59"
+      "\x16\x62\x5d\xbd\xee\xf5\x14\x29\x9b\xaa\xda\x56\x30\x86\x40\x8e\x93\x08"
+      "\x32\x4d\xa0\x0d\xe9\x74\x37\x43\xd4\xa6\x44\x75\x7b\xf1\x4b\x83\x66\x39"
+      "\x29\xc5\x51\x84\xd0\xed\xef\x23\x81\x61\xac\x28\x01\x26\x1e\x5f\x07\x77"
+      "\x67\xb3\x7d\xde\x0e\x8c\x87\x9e\x52\x96\x39\x7c\xbe\xf8\x52\x47\x6f\xdf"
+      "\x6b\x36\xa9\xb3\xdc\x26\x92\x69\x47\x0f\x68\xcf\x6d\x03\x22\x01\x49\x0f"
+      "\x0d\x36\xa2\xfc\xff\xc9\x8b\xc6\x77\xb9\x51\x94\xaa\xf1\x0f\x79\xdd\xfd"
+      "\x1a\xc0\x4d\x89\xe4\x1d\x6e\x5f\x97\xad\x42\x76\x59\xcb\xa8\x26\x23\x96"
+      "\x5d\xed\xe3\x92\xda\x17\xfe\x3d\x67\xc8\x33\x2a\x7d\x78\x86\xd5\x7c\x75"
+      "\xb2\x29\xb7\x49\x8f\xce\x3c\x73\xbe\x5a\x2c\xe8\x28\x6e\xfd\xdd\x08\x08"
+      "\xc1\x23\x74\x29\x6c\x51\xb9\xe9\x33\x87\x67\x57\x0a\x66\x03\xa2\xa3\x33"
+      "\x85\xc0\xdc\x2f\xea\x71\xe9\xe6\xb1\x37\x39\x13\x10\x72\xc5\x4d\xc5\xc7"
+      "\xad\x1f\x2b\xe6\xdb\x50\xb4\xcc\x2e\x55\xda\x79\xd2\x7d\xaa\x67\x12\xce"
+      "\x0b\xfe\x7e\x9f\x3e\x02\x61\x32\x2b\x1f\xc0\x4a\x0a\x7c\xdd\x2c\x77\xee"
+      "\x47\x16\xb6\xf0\x67\x97\x41\xaf\xa1\xc5\x93\xad\x63\xd8\x28\x06\x4a\x5c"
+      "\xb4\x5f\x5b\xbe\x5d\x98\x02\xb1\x5b\x76\xba\xae\x58\x4f\xeb\x4a\xef\x8e"
+      "\xd7\x23\x87\x96\xc8\x0f\x00\x28\x2b\x5d\xc6\xb6\x31\x80\xe2\xe9\x99\xb6"
+      "\xa9\x7c\x27\xb9\x13\x0d\x3c\xa4\xc2\x32\xc7\x63\xf2\xcc\x1e\x6e\x10\x42"
+      "\xd5\x55\x2c\x15\xf9\x51\x79\x03\x28\x92\xfd\x32\x8a\xff\xcd\xe8\x7a\xd9"
+      "\xb6\xb9\x05\x00\x18\x9b\x47\xff\x1a\x45\xae\xfd\x29\x04\x25\xc2\x42\x94"
+      "\x34\xe5\x48\x46\xee\x09\x21\x0f\xea\x47\x99\x8a\x76\x4e\x51\x34\xf6\x1e"
+      "\x82\x8c\xec\x08\x2b\xfd\x16\x59\xa4\x40\x58\x37\x75\xbf\xcb\x97\x66\x35"
+      "\x1b\x78\x8a\xd7\x4f\x7e\xf0\x7b\x81\x98\x05\x6b\xea\x57\x62\x4b\x30\x2a"
+      "\xed\x67\x14\xbb\xa8\x29\xd3\x6b\x03\x8a\xe0\x8c\xc5\x0b\x0a\x1d\x4b\x9a"
+      "\xb8\x77\x87\x4b\xbd\x56\x62\xc8\x42\x62\xf4\x51\x69\x78\x3b\x59\x21\x60"
+      "\xb8\x5e\x93\x60\x2e\x73\x9a\xed\x9f\xed\x99\x49\x3e\x82\xb9\x82\x7b\xaf"
+      "\x81\x84\x5b\x62\x4c\x4c\xb1\x76\x16\xa0\xe9\x16\x8f\x44\x83\xb4\xdd\xde"
+      "\x48\x16\x61\xf8\xa9\x86\x6f\x2f\x79\x6b\x52\xa5\xe0\xe4\x5e\x7e\x7e\x11"
+      "\xf6\x84\x11\xfe\x6c\x97\xf6\x52\x3c\x70\x30\xe6\x57\x8f\x25\x2f\x17\x47"
+      "\x70\x58\x1d\x92\x35\xf7\xd9\x99\xa4\xcf\x07\x3b\x58\x04\xd3\xa7\x65\xc1"
+      "\x10\x91\x8f\xa7\x78\x79\x56\x71\xcb\x98\x54\xff\x8f\xf5\x9d\xe6\x24\x2a"
+      "\x6b\xff\xc3\x54\x0e\xca\x5f\x94\xb9\x21\x87\xbf\x6f\xd3\x7b\xac\x61\xdd"
+      "\x82\x3a\x98\x82\x9e\xcf\xc4\x74\x7a\x4a\x71\x4f\x0b\xb4\x03\x94\xcc\x00"
+      "\x0a\x96\x68\xb1\xaa\x47\xec\xe9\x4a\xc7\xd0\x20\x22\xdb\x54\xf2\x9b\xc1"
+      "\x21\x69\xe1\x93\x4c\xf2\x35\x66\x78\x17\xe5\xef\x9e\xc4\x5f\x86\xc2\x13"
+      "\xb8\x57\xbe\xd0\x8f\x23\x9d\x1e\x8f\x62\x9e\x7e\x50\xcb\xd7\x16\x5b\x3b"
+      "\xa8\x2d\x62\x57\x33\x30\x7e\xa7\xef\x62\xdd\x0b\x7a\x82\xfd\xc7\x43\x9b"
+      "\x84\x55\x59\x9c\xda\x37\xff\x51\xa5\x0f\xda\x89\x10\x6d\x1f\x67\x36\x71"
+      "\xd8\xb7\xc8\x40\xfd\x4d\x37\x66\x22\x25\xb3\x73\x69\x4c\xc3\x6e\xbf\xe7"
+      "\x43\xde\x04\xff\x86\xef\x1b\x2b\x5a\x85\xc9\x8b\x72\x01\x88\x0b\x75\x3a"
+      "\x22\xad\x26\x30\x18\xe4\xf4\xd8\x65\xa9\x67\x7c\xea\xb4\x0a\x8c\x0c\x9d"
+      "\x9f\xe9\x0e\x19\x32\x9e\xd8\xa6\x18\x5a\x9d\x3a\x36\x47\x04\x73\xd6\x5d"
+      "\xcb\xdb\x1c\xb0\xdf\x94\x22\x27\xff\xf5\x04\xf6\xe0\x04\xce\x97\x2d\xed"
+      "\x4c\xba\x85\xb5\xde\x3e\xe7\x95\x06\xf3\x30\x45\x79\xf2\x0a\xcb\xb9\x92"
+      "\x81\xd1\x30\xa3\xe0\x84\xe9\x3f\x5e\xdc\x3c\x47\x02\x8c\xfb\x34\x34\xbe"
+      "\x18\x4f\xa8\xc1\xc8\xc9\xba\x88\xeb\x1b\xbf\x90\x60\x01\x1f\xbb\xdb\x78"
+      "\x36\xd8\xf7\x9a\x54\x9d\xce\xe1\x48\x09\xfb\xcb\xf0\x92\xbe\xee\x73\xb9"
+      "\xae\xc3\x10\xad\x59\x59\xcc\xa9\x4c\xa2\xa0\xf2\x38\xb8\x66\xc2\xa5\x6a"
+      "\x2b\x0d\xb0\xab\x5b\xfb\x5e\x0d\x20\x15\xf0\x94\x24\x85\x7f\x7d\x99\xb2"
+      "\x8a\x9d\x72\x7c\xdf\x9b\x42\xa4\x41\x20\xb1\x67\xa5\xbc\x12\x26\x5b\x27"
+      "\x95\xc2\x3c\xe4\xb5\x85\x87\xc1\xa3\x7f\x08\x29\x19\x47\xfa\x78\x85\xeb"
+      "\x24\x98\xdf\x6a\x5f\x29\xba\x25\xfd\x9c\x15\xff\xa5\xb2\x60\xa7\x97\xf7"
+      "\x18\xbd\x9e\xad\xe7\x56\xcf\x64\x36\xcc\x39\x1f\xe8\x91\x42\x15\x6d\x38"
+      "\x03\x7d\x71\xf3\xfd\x76\x3d\x27\x52\x5d\x29\x65\xba\xe8\x59\xb2\x93\xb1"
+      "\x78\xe1\xf7\x2e\x26\x9e\x89\xfd\x3e\x6d\x5f\x50\xa3\x4c\x17\x5e\x09\xb4"
+      "\x09\x8b\x94\xc7\xee\x7f\x67\x8d\xa3\xbf\x70\xcb\xdf\x82\xf5\x75\x8b\x5a"
+      "\x0b\xfc\x18\x21\x81\x14\x84\x1c\xf5\x3b\xf2\x48\x84\x8b\xa1\x4b\x02\xac"
+      "\x9d\xa9\xc9\xcf\x65\xfd\x3d\xa4\xa0\x2d\x44\x4b\x90\xbd\x6e\x67\x50\x8c"
+      "\xee\x90\xb5\x8e\x1d\x79\x06\x48\xb6\x22\xee\x27\x54\xe8\xa4\x0c\x52\x38"
+      "\x3f\x53\x80\x21\xbe\xca\xed\x1f\x07\xa2\xc1\xd9\x8c\xbd\xcc\x5e\xef\x48"
+      "\x81\xe6\x35\x2f\xf0\x91\xd8\x58\x0d\x3d\x3c\xc9\xfa\x08\xa6\xc1\xfa\xc8"
+      "\x42\x4a\xa7\xb0\x43\x49\x3f\x34\x81\x2c\x5f\xc6\x1a\xf1\x50\x01\x90\x2b"
+      "\x86\x69\x0c\xeb\x34\x41\x93\xb0\xe8\xf2\xd8\x63\xe9\x10\x4a\x55\x4a\x9b"
+      "\xb9\x7e\x04\xcf\xdd\xb8\xe7\xb3\xff\x31\xb5\x85\xd6\x00\x26\xb4\x2c\xf8"
+      "\xf6\xf0\x23\x56\x36\xc7\x7b\x6f\x91\xdf\x8a\x65\x4b\x1c\x66\x69\x10\x21"
+      "\xf0\xba\xbb\x4f\xe4\xc4\xa4\x24\x58\x02\x6e\x04\x5d\x8a\x63\xb2\xc9\x99"
+      "\x48\x4a\x5f\x9e\xe2\x50\xba\x6b\xde\xbe\xb9\xc9\x9c\x20\x96\x0d\x63\x0a"
+      "\xee\x84\xe0\x63\x85\x6f\xce\x09\x32\x23\x56\xd2\x8d\x5a\x88\xca\x24\x8e"
+      "\x07\xa3\x9e\x7b\x94\x56\xe2\x9b\x3b\x9c\xae\x15\x70\xe1\xbc\x79\xb9\xe9"
+      "\xd5\x30\xcf\x08\x43\x96\xad\x76\x6a\x61\x14\x9a\xa8\x08\x7e\x05\xa3\x4a"
+      "\x8f\x87\x5b\xf8\xee\x71\xd2\x69\x01\x65\x54\xe7\x5a\xf5\x21\x38\x1f\xcf"
+      "\xac\x8b\xab\xb0\x0b\xf3\xaa\x92\x81\xa4\x84\x2c\xad\xca\x00\x4d\xcb\x9f"
+      "\x98\x39\x12\xbf\xcf\x7d\x43\xcf\x49\x00\x13\x5f\x14\x88\x29\x94\xbd\xf4"
+      "\x57\x6b\xb7\x48\x15\x7f\x1a\x90\x7a\x8f\x53\x2c\x5c\x11\xd5\x7a\x19\xbd"
+      "\xf1\x47\x11\xa5\xfd\xe7\x9d\xa8\x7e\xf8\xab\x13\x40\x61\xc3\x9a\xd7\xfe"
+      "\xfc\xc8\xee\x99\x40\xd2\x69\x27\xd9\xdd\xcb\xe4\x9b\x08\xa5\x16\xb8\x86"
+      "\x56\x1c\xef\x41\x3f\xac\xa7\x24\x4e\x0e\xcc\xaf\x1a\xac\x80\xa0\xa6\x2e"
+      "\x3f\x77\xc0\x8c\x5d\x3c\x31\xad\x33\x9d\x7c\xa2\x84\x5a\x35\x1a\xb4\x2b"
+      "\xda\x33\xda\x18\x5b\x40\x17\xdf\x44\xe3\xe8\x34\xef\xce\xd5\x7f\xc2\xee"
+      "\x7d\xe6\x80\xe2\x0b\xe3\xe6\x96\xc8\x9a\x2a\x6c\x58\xc1\x3d\x42\xb6\xba"
+      "\x07\xdf\x02\x38\xc4\xb7\x1a\xd4\x56\x62\x13\xcb\xbc\x1d\xc8\x6d\x37\xbd"
+      "\x0b\x96\x42\x94\xed\x00\x90\x1b\x09\x20\x2d\x83\x29\xe5\xd6\x4d\xcb\xf1"
+      "\x08\xc1\x18\x0e\x9a\xd1\xf8\xa9\xf4\x4e\x87\xcc\xd5\xe1\x70\x00\xd6\x68"
+      "\x65\x66\x33\x49\xc4\x50\xe3\x3a\x12\xf5\xc2\x96\xc4\x44\xd8\xad\xc5\x71"
+      "\xfe\x40\xaa\x78\xaf\xd8\x31\x5d\xdd\xa8\xef\xef\x4c\x39\x32\x88\x73\xde"
+      "\x2f\x5e\x70\x8c\x24\x71\xf8\x93\x23\x33\x10\x99\x5c\x6d\xa4\xf9\xa2\x08"
+      "\x8f\xee\x34\xe2\x58\xe5\xcf\xf4\x85\xec\xa7\xef\xdc\x87\xaa\x1e\xbd\xfd"
+      "\xc3\x09\xc6\xeb\x97\x3b\x24\x8a\x65\x9c\x81\xdc\xb1\x8b\x40\x0b\xb7\x4f"
+      "\x32\x47\xf2\x96\xd8\x17\x99\xb9\xcc\x31\xee\x84\x43\x5d\xb7\xf0\xd8\xc3"
+      "\xfa\x81\x4b\x94\x06\x82\x71\xdc\x6a\x93\x1d\x0a\x52\xb6\x10\x58\x82\x45"
+      "\xaf\x5c\x1b\xf2\x04\xe0\xe1\xc5\x5e\x0b\x72\xdb\x89\x69\x8d\x65\xd8\x0b"
+      "\x13\xf6\x2a\xf6\x49\x33\x8c\xcf\x6a\x15\x8b\x9e\x9a\xba\x3f\xd0\x3b\x9e"
+      "\x19\xad\x76\xf6\x9a\xaf\xb4\xb1\x25\xd6\xba\x86\xd6\xbc\xf5\x04\x7c\xf3"
+      "\xe4\xa2\x4a\xe1\xd6\x9c\xf2\xe7\xfe\xe3\x3e\x34\x2c\x69\x1a\x24\xfd\xc5"
+      "\x11\x9b\x47\x8b\x24\xbd\xac\x06\xeb\x8d\x58\xc2\x62\x6d\xb6\x00\x71\x81"
+      "\x8b\xf5\xef\x89\x0b\x61\xfe\xdf\xa9\x6a\xd6\xe7\x8d\x99\x35\xc8\x09\xfc"
+      "\xae\xcb\x6e\xf4\x89\x1b\xf8\xd7\x10\xdb\x70\x53\xbb\xe7\x01\x2d\xb4\xb3"
+      "\x05\xb3\xa5\x08\xf2\xcd\x94\x71\xd2\x1e\x5e\x21\x46\x7e\xbc\xf9\x37\xa6"
+      "\xc7\x52\xd8\xf6\x46\xbe\xaf\x0f\x6c\x4a\xa4\x23\x16\xb2\x51\x80\x93\xbc"
+      "\x71\x69\x96\x56\x43\x19\x7d\x0c\x62\x95\x0f\xa7\x41\x37\x3a\xac\xd7\x14"
+      "\xd8\x2d\x4a\x0d\x1d\x2a\x55\xc1\x91\x8f\xa0\x86\x3d\xff\x1e\x3d\xd1\x2a"
+      "\x68\x70\x11\xc1\x12\x8b\xb5\xe6\x3f\x58\xbe\xaa\x7b\xaf\x92\x7a\x03\x3f"
+      "\x75\xa0\x99\xfe\xa6\x75\x00\x08\x1d\xe1\x03\x1f\x85\x56\x0c\x81\x93\x84"
+      "\xa1\x64\xc6\x9c\xa8\x07\x30\x81\x1f\x17\xbf\x70\x7c\x7d\x0c\x9f\x56\xa6"
+      "\x61\xab\x2d\xfc\xe6\xa0\x7c\x61\x77\x92\x15\x89\x63\xca\x96\xfd\x67\x1b"
+      "\x4c\x2d\xd7\x30\x00\x9f\x1e\xb1\xab\xe1\x12\x2a\xaa\x0b\x15\x9c\x29\x5d"
+      "\xe2\x1b\xda\x5d\xf6\x3e\x56\x5e\xbc\xb6\x64\x27\x0a\xe3\x0a\x52\x03\x55"
+      "\x50\x55\x2e\x94\x3d\xca\x22\xf6\xc0\x89\x2c\x3e\x93\xab\xcd\xe8\x61\xf2"
+      "\xec\x19\x9b\x63\x9a\xf6\xf5\x16\xfd\xb5\x81\xd5\xe2\x3b\xfc\x1b\x03\x5b"
+      "\xf7\x67\xec\xea\x78\x12\x6f\xbf\xc6\x51\x1c\xa4\x13\xae\xdf\x51\xae\xf6"
+      "\xac\x19\xa5\xda\x04\xbc\x38\x26\x0e\x7f\x7f\x4f\x99\x16\x5f\x4e\x26\x92"
+      "\x05\x3a\xaa\xe1\x68\xeb\x96\x0d\x76\x2d\xf1\xc5\x06\x4b\x87\x96\xff\x5c"
+      "\x6d\xcc\x93\x4a\x96\x8d\x3c\xe2\x9b\x6a\xf0\x95\x0d\xdc\x07\xc7\x60\xc7"
+      "\xdc\x1e\x3d\x90\xec\x02\x63\x9e\x80\xed\x51\x23\x04\xab\x03\x18\xea\x16"
+      "\x38\xad\x91\xc8\xcb\xa9\x22\xff\x36\x45\x79\x99\x52\x1a\x3e\x84\xcc\x27"
+      "\xac\x68\x2f\xe1\x4e\x78\x91\x46\x0f\x2c\x0e\x5c\x80\xa9\x48\x56\x0e\xb8"
+      "\x0e\xc9\xd3\x5d\xbe\x98\x8d\xe8\x6d\x25\xe7\x16\xc1\x24\x11\xaf\xf9\x56"
+      "\xcb\xe6\x79\x88\x95\x5b\x95\x6a\xb9\xd8\xb5\xe2\x52\x01\x5f\x30\xce\xbc"
+      "\x59\xc4\xe1\x7f\x0d\xb5\x8c\xf5\x40\x62\x09\x92\xf6\xee\xce\xec\x0a\x30"
+      "\x10\x4f\x39\x85\xde\x3d\x95\x42\x0d\x21\x5a\x19\x9a\xa4\x78\x97\xad\xee"
+      "\xe2\x36\x10\xd2\x1a\x7f\x20\xdc\x27\xc8\xd0\x69\xdf\xd6\x33\x71\xf6\xac"
+      "\xd8\x4e\xe7\x48\xb7\x5b\x39\xa8\xc9\x96\x6a\x74\x05\x96\x6f\xfd\x79\xe3"
+      "\x69\x9c\x0f\x1c\x87\x1d\x19\x81\x28\xda\xe7\x99\x4d\x26\xbf\xde\x40\xd4"
+      "\x6a\xd2\xcf\x56\xad\xb9\x6e\xec\xad\x05\x6f\x80\xfa\x31\x31\xfd\x2d\x00"
+      "\xfc\xe5\x21\x55\x72\x5e\xc5\x02\x7c\xfd\x24\x9e\x5d\x30\x9a\x3e\xa5\x29"
+      "\x85\x3b\xc6\x17\x2e\x31\x78\x9e\x77\x78\xf6\x49\x1d\x98\xfd\x10\x0c\xf9"
+      "\xfe\xda\x43\x2a\x10\x64\x67\x3f\xa7\x8c\x12\xf2\x20\xd6\x67\x50\x2d\x5e"
+      "\x32\xf2\x43\x6b\xaf\xd2\x7e\xc2\xf7\x57\x07\x99\x2f\x01\x30\x54\x67\x2c"
+      "\x85\x0d\xce\xc8\xab\x96\x53\x4f\x70\x1a\x9e\xf2\x6e\xdd\x19\xf4\x35\x0e"
+      "\x7a\xe9\xf5\xe1\x18\x68\xaf\x59\x43\x57\xc8\x3f\x41\x28\x65\xc1\x0f\xc7"
+      "\x9f\xc4\xfe\xbd\x43\xa0\x35\x09\x5f\x93\x74\xc4\xe0\x14\x10\x26\xb1\x3a"
+      "\x24\xa2\x2a\xe1\xe7\x32\x7e\x05\x16\x4a\xe2\xa5\xcc\xae\x68\x99\x1b\x57"
+      "\x6e\xa8\x65\x38\x30\x1e\xac\xab\x0d\xe7\xeb\x4c\x95\x27\x4b\xe9\x58\xa3"
+      "\x49\x4b\xc8\xbb\x5a\xf0\x27\x4e\xed\xc6\xa1\x18\x77\xe1\xc0\x40\xfc\xeb"
+      "\x17\x5f\xf2\xa1\xde\xda\x0b\x1c\x3c\xb4\x7f\xdf\x4b\xc3\x8a\xac\x66\x8b"
+      "\x23\x62\xd5\x22\x8e\xcf\x7c\x95\x2e\xb2\x57\x2a\x07\x46\x09\x78\xd5\xd9"
+      "\xe6\xf7\xb4\xf5\x2f\xea\x67\x3d\xb2\x46\x29\x5d\x1b\x0c\xd9\xcc\x33\x17"
+      "\x04\xaa\x64\x89\xb4\xce\x8c\x03\x9b\x25\x20\x7e\x80\x49\x44\x7a\x22\xa5"
+      "\x7e\xbc\x35\xe1\x65\xe4\xe0\x10\x83\x04\xea\x14\x21\xbc\xae\xd2\x61\x32"
+      "\x9d\x4c\xb2\xa7\xc7\x34\x80\x1d\x69\xdb\x9e\xa5\x5a\x07\xba\x37\x8e\x90"
+      "\x7c\xfb\x87\x42\xf1\x2b\x3f\x38\x15\x83\xf1\x7a\xce\x46\x9f\x4c\x2d\x3a"
+      "\xdb\x2f\xf0\xbe\x64\x6f\x69\xa4\x0f\x35\x27\x08\x7e\xff\x0c\xbc\x3a\x02"
+      "\x46\x22\x74\x30\xa7\xc5\x41\x91\x0d\x7b\xde\xfb\xb3\xff\x00\x1b\xeb\xa9"
+      "\x67\xd6\xeb\x4b\x5f\xeb\x6c\xbf\x44\x33\xa1\x1f\x11\x4b\x0b\x13\xb7\x1d"
+      "\xb1\x6e\x35\x88\x68\x74\x30\xb2\x7e\x0e",
+      4096);
+  *(uint16_t*)0x20001304 = 0x1000;
+  syscall(__NR_write, r[0], 0x20000300ul, 0x1006ul);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  loop();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0c641fb581d08c1ef69b061b6517c41c180e99d1.c b/syzkaller-repros/linux/0c641fb581d08c1ef69b061b6517c41c180e99d1.c
new file mode 100644
index 0000000..859f575
--- /dev/null
+++ b/syzkaller-repros/linux/0c641fb581d08c1ef69b061b6517c41c180e99d1.c
@@ -0,0 +1,311 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+#include <linux/in6.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/veth.h>
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+                 0x0};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 2ul, 0x4000000805ul, 0);
+  if (res != -1)
+    r[0] = res;
+  res = syscall(__NR_socket, 2ul, 5ul, 0x84ul);
+  if (res != -1)
+    r[1] = res;
+  res = syscall(__NR_dup3, r[0], r[1], 0ul);
+  if (res != -1)
+    r[2] = res;
+  *(uint16_t*)0x20d6cff0 = 2;
+  *(uint16_t*)0x20d6cff2 = htobe16(0x4e20);
+  *(uint32_t*)0x20d6cff4 = htobe32(0x7f000001);
+  syscall(__NR_setsockopt, r[1], 0x84ul, 0x64ul, 0x20d6cff0ul, 0x10ul);
+  memcpy((void*)0x20fa3fff, "\t", 1);
+  *(uint16_t*)0x206f7000 = 2;
+  *(uint16_t*)0x206f7002 = htobe16(0);
+  *(uint8_t*)0x206f7004 = 0xac;
+  *(uint8_t*)0x206f7005 = 0x14;
+  *(uint8_t*)0x206f7006 = -1;
+  *(uint8_t*)0x206f7007 = 0xbb;
+  syscall(__NR_sendto, r[2], 0x20fa3ffful, 1ul, 0ul, 0x206f7000ul, 0x10ul);
+  memcpy((void*)0x203cef9f, "7", 1);
+  *(uint16_t*)0x20618000 = 2;
+  *(uint16_t*)0x20618002 = htobe16(0x4e20);
+  *(uint32_t*)0x20618004 = htobe32(0x7f000001);
+  syscall(__NR_sendto, r[1], 0x203cef9ful, 0x10231ul, 0ul, 0x20618000ul,
+          0x10ul);
+  memcpy((void*)0x2025e000, "\x7f\x00\x00\x00", 4);
+  *(uint32_t*)0x2025e004 = 0;
+  *(uint32_t*)0x2025e008 = 0;
+  *(uint32_t*)0x20a8a000 = 0xc;
+  res = syscall(__NR_getsockopt, r[1], 0x84ul, 0x1dul, 0x2025e000ul,
+                0x20a8a000ul);
+  if (res != -1)
+    r[3] = *(uint32_t*)0x2025e008;
+  *(uint32_t*)0x2059aff8 = r[3];
+  *(uint32_t*)0x2059affc = 0;
+  *(uint32_t*)0x2034f000 = 0x2059b000;
+  syscall(__NR_getsockopt, r[2], 0x84ul, 0x7aul, 0x2059aff8ul, 0x2034f000ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0d68c5a10991af67c5857fb25a9d33a5f75c69c5.c b/syzkaller-repros/linux/0d68c5a10991af67c5857fb25a9d33a5f75c69c5.c
new file mode 100644
index 0000000..bda548b
--- /dev/null
+++ b/syzkaller-repros/linux/0d68c5a10991af67c5857fb25a9d33a5f75c69c5.c
@@ -0,0 +1,95 @@
+// autogenerated by syzkaller (http://github.com/google/syzkaller)
+
+#ifndef __NR_bpf
+#define __NR_bpf 321
+#endif
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.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 use_temporary_dir()
+{
+  char tmpdir_template[] = "./syzkaller.XXXXXX";
+  char* tmpdir = mkdtemp(tmpdir_template);
+  if (!tmpdir)
+    fail("failed to mkdtemp");
+  if (chmod(tmpdir, 0777))
+    fail("failed to chmod");
+  if (chdir(tmpdir))
+    fail("failed to chdir");
+}
+
+long r[29];
+void loop()
+{
+  memset(r, -1, sizeof(r));
+  r[0] = syscall(__NR_mmap, 0x20000000ul, 0xfff000ul, 0x3ul, 0x32ul,
+                 0xfffffffffffffffful, 0x0ul);
+  *(uint32_t*)0x20851000 = (uint32_t)0x1;
+  *(uint32_t*)0x20851004 = (uint32_t)0x3;
+  *(uint64_t*)0x20851008 = (uint64_t)0x201abfe8;
+  *(uint64_t*)0x20851010 = (uint64_t)0x20b4d000;
+  *(uint32_t*)0x20851018 = (uint32_t)0x1;
+  *(uint32_t*)0x2085101c = (uint32_t)0x80;
+  *(uint64_t*)0x20851020 = (uint64_t)0x2000a000;
+  *(uint32_t*)0x20851028 = (uint32_t)0x0;
+  *(uint32_t*)0x2085102c = (uint32_t)0x0;
+  *(uint8_t*)0x201abfe8 = (uint8_t)0x8db7;
+  *(uint8_t*)0x201abfe9 = (uint8_t)0x0;
+  *(uint16_t*)0x201abfea = (uint16_t)0x0;
+  *(uint32_t*)0x201abfec = (uint32_t)0xe70;
+  *(uint8_t*)0x201abff0 = (uint8_t)0x20000007;
+  *(uint8_t*)0x201abff1 = (uint8_t)0x80000001;
+  *(uint16_t*)0x201abff2 = (uint16_t)0x0;
+  *(uint32_t*)0x201abff4 = (uint32_t)0xffffffffffffffff;
+  *(uint8_t*)0x201abff8 = (uint8_t)0xd395;
+  *(uint8_t*)0x201abff9 = (uint8_t)0x0;
+  *(uint16_t*)0x201abffa = (uint16_t)0x0;
+  *(uint32_t*)0x201abffc = (uint32_t)0x0;
+  memcpy((void*)0x20b4d000, "\x73\x79\x73\x65\x4f\x00", 6);
+  r[23] = syscall(__NR_bpf, 0x5ul, 0x20851000ul, 0x30ul);
+  r[24] = syscall(__NR_socket, 0x29ul, 0x2ul, 0x0ul);
+  r[25] = syscall(__NR_socket, 0x29ul, 0x5ul, 0x0ul);
+  *(uint32_t*)0x20cb6ff8 = r[25];
+  *(uint32_t*)0x20cb6ffc = r[23];
+  r[28] = syscall(__NR_ioctl, r[24], 0x89e0ul, 0x20cb6ff8ul);
+}
+
+int main()
+{
+  use_temporary_dir();
+  loop();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0ecb8544c47bb7d668a1951ff5ff4c38c5a32f24.c b/syzkaller-repros/linux/0ecb8544c47bb7d668a1951ff5ff4c38c5a32f24.c
new file mode 100644
index 0000000..6f4190b
--- /dev/null
+++ b/syzkaller-repros/linux/0ecb8544c47bb7d668a1951ff5ff4c38c5a32f24.c
@@ -0,0 +1,1203 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <sched.h>
+#include <setjmp.h>
+#include <signal.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/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/uio.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <linux/capability.h>
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/if_tun.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/tcp.h>
+#include <linux/veth.h>
+
+unsigned long long procid;
+
+static __thread int skip_segv;
+static __thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* ctx)
+{
+  uintptr_t addr = (uintptr_t)info->si_addr;
+  const uintptr_t prog_start = 1 << 20;
+  const uintptr_t prog_end = 100 << 20;
+  if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) &&
+      (addr < prog_start || addr > prog_end)) {
+    _longjmp(segv_env, 1);
+  }
+  exit(sig);
+}
+
+static void install_segv_handler(void)
+{
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = SIG_IGN;
+  syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
+  syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_sigaction = segv_handler;
+  sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+  sigaction(SIGSEGV, &sa, NULL);
+  sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...)                                                        \
+  {                                                                            \
+    __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
+    if (_setjmp(segv_env) == 0) {                                              \
+      __VA_ARGS__;                                                             \
+    }                                                                          \
+    __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
+  }
+
+static void use_temporary_dir(void)
+{
+  char tmpdir_template[] = "./syzkaller.XXXXXX";
+  char* tmpdir = mkdtemp(tmpdir_template);
+  if (!tmpdir)
+    exit(1);
+  if (chmod(tmpdir, 0777))
+    exit(1);
+  if (chdir(tmpdir))
+    exit(1);
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static void netlink_nest(struct nlmsg* nlmsg, int typ)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_type = typ;
+  nlmsg->pos += sizeof(*attr);
+  nlmsg->nested[nlmsg->nesting++] = attr;
+}
+
+static void netlink_done(struct nlmsg* nlmsg)
+{
+  struct nlattr* attr = nlmsg->nested[--nlmsg->nesting];
+  attr->nla_len = nlmsg->pos - (char*)attr;
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_add_device_impl(struct nlmsg* nlmsg, const char* type,
+                                    const char* name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  if (name)
+    netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name));
+  netlink_nest(nlmsg, IFLA_LINKINFO);
+  netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type));
+}
+
+static void netlink_add_device(struct nlmsg* nlmsg, int sock, const char* type,
+                               const char* name)
+{
+  netlink_add_device_impl(nlmsg, type, name);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_veth(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* peer)
+{
+  netlink_add_device_impl(nlmsg, "veth", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_nest(nlmsg, VETH_INFO_PEER);
+  nlmsg->pos += sizeof(struct ifinfomsg);
+  netlink_attr(nlmsg, IFLA_IFNAME, peer, strlen(peer));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_hsr(struct nlmsg* nlmsg, int sock, const char* name,
+                            const char* slave1, const char* slave2)
+{
+  netlink_add_device_impl(nlmsg, "hsr", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  int ifindex1 = if_nametoindex(slave1);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE1, &ifindex1, sizeof(ifindex1));
+  int ifindex2 = if_nametoindex(slave2);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE2, &ifindex2, sizeof(ifindex2));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_linked(struct nlmsg* nlmsg, int sock, const char* type,
+                               const char* name, const char* link)
+{
+  netlink_add_device_impl(nlmsg, type, name);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_vlan(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* link, uint16_t id, uint16_t proto)
+{
+  netlink_add_device_impl(nlmsg, "vlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_VLAN_ID, &id, sizeof(id));
+  netlink_attr(nlmsg, IFLA_VLAN_PROTOCOL, &proto, sizeof(proto));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_macvlan(struct nlmsg* nlmsg, int sock, const char* name,
+                                const char* link)
+{
+  netlink_add_device_impl(nlmsg, "macvlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  uint32_t mode = MACVLAN_MODE_BRIDGE;
+  netlink_attr(nlmsg, IFLA_MACVLAN_MODE, &mode, sizeof(mode));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_geneve(struct nlmsg* nlmsg, int sock, const char* name,
+                               uint32_t vni, struct in_addr* addr4,
+                               struct in6_addr* addr6)
+{
+  netlink_add_device_impl(nlmsg, "geneve", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_GENEVE_ID, &vni, sizeof(vni));
+  if (addr4)
+    netlink_attr(nlmsg, IFLA_GENEVE_REMOTE, addr4, sizeof(*addr4));
+  if (addr6)
+    netlink_attr(nlmsg, IFLA_GENEVE_REMOTE6, addr6, sizeof(*addr6));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+#define IFLA_IPVLAN_FLAGS 2
+#define IPVLAN_MODE_L3S 2
+#undef IPVLAN_F_VEPA
+#define IPVLAN_F_VEPA 2
+
+static void netlink_add_ipvlan(struct nlmsg* nlmsg, int sock, const char* name,
+                               const char* link, uint16_t mode, uint16_t flags)
+{
+  netlink_add_device_impl(nlmsg, "ipvlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_IPVLAN_MODE, &mode, sizeof(mode));
+  netlink_attr(nlmsg, IFLA_IPVLAN_FLAGS, &flags, sizeof(flags));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
+                            const void* addr, int addrsize)
+{
+  struct ifaddrmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
+  hdr.ifa_scope = RT_SCOPE_UNIVERSE;
+  hdr.ifa_index = if_nametoindex(dev);
+  netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
+  netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
+  return netlink_send(nlmsg, sock);
+}
+
+static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in_addr in_addr;
+  inet_pton(AF_INET, addr, &in_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
+  (void)err;
+}
+
+static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, addr, &in6_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+#define DEV_IPV4 "172.20.20.%d"
+#define DEV_IPV6 "fe80::%02x"
+#define DEV_MAC 0x00aaaaaaaaaa
+
+static void netdevsim_add(unsigned int addr, unsigned int port_count)
+{
+  char buf[16];
+  sprintf(buf, "%u %u", addr, port_count);
+  if (write_file("/sys/bus/netdevsim/new_device", buf)) {
+    snprintf(buf, sizeof(buf), "netdevsim%d", addr);
+    initialize_devlink_ports("netdevsim", buf, "netdevsim");
+  }
+}
+
+#define WG_GENL_NAME "wireguard"
+enum wg_cmd {
+  WG_CMD_GET_DEVICE,
+  WG_CMD_SET_DEVICE,
+};
+enum wgdevice_attribute {
+  WGDEVICE_A_UNSPEC,
+  WGDEVICE_A_IFINDEX,
+  WGDEVICE_A_IFNAME,
+  WGDEVICE_A_PRIVATE_KEY,
+  WGDEVICE_A_PUBLIC_KEY,
+  WGDEVICE_A_FLAGS,
+  WGDEVICE_A_LISTEN_PORT,
+  WGDEVICE_A_FWMARK,
+  WGDEVICE_A_PEERS,
+};
+enum wgpeer_attribute {
+  WGPEER_A_UNSPEC,
+  WGPEER_A_PUBLIC_KEY,
+  WGPEER_A_PRESHARED_KEY,
+  WGPEER_A_FLAGS,
+  WGPEER_A_ENDPOINT,
+  WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+  WGPEER_A_LAST_HANDSHAKE_TIME,
+  WGPEER_A_RX_BYTES,
+  WGPEER_A_TX_BYTES,
+  WGPEER_A_ALLOWEDIPS,
+  WGPEER_A_PROTOCOL_VERSION,
+};
+enum wgallowedip_attribute {
+  WGALLOWEDIP_A_UNSPEC,
+  WGALLOWEDIP_A_FAMILY,
+  WGALLOWEDIP_A_IPADDR,
+  WGALLOWEDIP_A_CIDR_MASK,
+};
+
+static int netlink_wireguard_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, WG_GENL_NAME,
+               strlen(WG_GENL_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_wireguard_setup(void)
+{
+  const char ifname_a[] = "wg0";
+  const char ifname_b[] = "wg1";
+  const char ifname_c[] = "wg2";
+  const char private_a[] =
+      "\xa0\x5c\xa8\x4f\x6c\x9c\x8e\x38\x53\xe2\xfd\x7a\x70\xae\x0f\xb2\x0f\xa1"
+      "\x52\x60\x0c\xb0\x08\x45\x17\x4f\x08\x07\x6f\x8d\x78\x43";
+  const char private_b[] =
+      "\xb0\x80\x73\xe8\xd4\x4e\x91\xe3\xda\x92\x2c\x22\x43\x82\x44\xbb\x88\x5c"
+      "\x69\xe2\x69\xc8\xe9\xd8\x35\xb1\x14\x29\x3a\x4d\xdc\x6e";
+  const char private_c[] =
+      "\xa0\xcb\x87\x9a\x47\xf5\xbc\x64\x4c\x0e\x69\x3f\xa6\xd0\x31\xc7\x4a\x15"
+      "\x53\xb6\xe9\x01\xb9\xff\x2f\x51\x8c\x78\x04\x2f\xb5\x42";
+  const char public_a[] =
+      "\x97\x5c\x9d\x81\xc9\x83\xc8\x20\x9e\xe7\x81\x25\x4b\x89\x9f\x8e\xd9\x25"
+      "\xae\x9f\x09\x23\xc2\x3c\x62\xf5\x3c\x57\xcd\xbf\x69\x1c";
+  const char public_b[] =
+      "\xd1\x73\x28\x99\xf6\x11\xcd\x89\x94\x03\x4d\x7f\x41\x3d\xc9\x57\x63\x0e"
+      "\x54\x93\xc2\x85\xac\xa4\x00\x65\xcb\x63\x11\xbe\x69\x6b";
+  const char public_c[] =
+      "\xf4\x4d\xa3\x67\xa8\x8e\xe6\x56\x4f\x02\x02\x11\x45\x67\x27\x08\x2f\x5c"
+      "\xeb\xee\x8b\x1b\xf5\xeb\x73\x37\x34\x1b\x45\x9b\x39\x22";
+  const uint16_t listen_a = 20001;
+  const uint16_t listen_b = 20002;
+  const uint16_t listen_c = 20003;
+  const uint16_t af_inet = AF_INET;
+  const uint16_t af_inet6 = AF_INET6;
+  /* Unused, but useful in case we change this:
+  const struct sockaddr_in endpoint_a_v4 = {
+      .sin_family = AF_INET,
+      .sin_port = htons(listen_a),
+      .sin_addr = {htonl(INADDR_LOOPBACK)}};*/
+  const struct sockaddr_in endpoint_b_v4 = {
+      .sin_family = AF_INET,
+      .sin_port = htons(listen_b),
+      .sin_addr = {htonl(INADDR_LOOPBACK)}};
+  const struct sockaddr_in endpoint_c_v4 = {
+      .sin_family = AF_INET,
+      .sin_port = htons(listen_c),
+      .sin_addr = {htonl(INADDR_LOOPBACK)}};
+  struct sockaddr_in6 endpoint_a_v6 = {.sin6_family = AF_INET6,
+                                       .sin6_port = htons(listen_a)};
+  endpoint_a_v6.sin6_addr = in6addr_loopback;
+  /* Unused, but useful in case we change this:
+  const struct sockaddr_in6 endpoint_b_v6 = {
+      .sin6_family = AF_INET6,
+      .sin6_port = htons(listen_b)};
+  endpoint_b_v6.sin6_addr = in6addr_loopback; */
+  struct sockaddr_in6 endpoint_c_v6 = {.sin6_family = AF_INET6,
+                                       .sin6_port = htons(listen_c)};
+  endpoint_c_v6.sin6_addr = in6addr_loopback;
+  const struct in_addr first_half_v4 = {0};
+  const struct in_addr second_half_v4 = {htonl(128 << 24)};
+  const struct in6_addr first_half_v6 = {{{0}}};
+  const struct in6_addr second_half_v6 = {{{0x80}}};
+  const uint8_t half_cidr = 1;
+  const uint16_t persistent_keepalives[] = {1, 3, 7, 9, 14, 19};
+  struct genlmsghdr genlhdr = {.cmd = WG_CMD_SET_DEVICE, .version = 1};
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_wireguard_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_a, strlen(ifname_a) + 1);
+  netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_a, 32);
+  netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_a, 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_b, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_b_v4,
+               sizeof(endpoint_b_v4));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[0], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
+               sizeof(first_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
+               sizeof(first_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_c, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_c_v6,
+               sizeof(endpoint_c_v6));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[1], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
+               sizeof(second_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
+               sizeof(second_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_b, strlen(ifname_b) + 1);
+  netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_b, 32);
+  netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_b, 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_a, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_a_v6,
+               sizeof(endpoint_a_v6));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[2], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
+               sizeof(first_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
+               sizeof(first_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_c, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_c_v4,
+               sizeof(endpoint_c_v4));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[3], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
+               sizeof(second_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
+               sizeof(second_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_c, strlen(ifname_c) + 1);
+  netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_c, 32);
+  netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_c, 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_a, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_a_v6,
+               sizeof(endpoint_a_v6));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[4], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
+               sizeof(first_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
+               sizeof(first_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_b, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_b_v4,
+               sizeof(endpoint_b_v4));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[5], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
+               sizeof(second_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
+               sizeof(second_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+
+error:
+  close(sock);
+}
+static void initialize_netdevices(void)
+{
+  char netdevsim[16];
+  sprintf(netdevsim, "netdevsim%d", (int)procid);
+  struct {
+    const char* type;
+    const char* dev;
+  } devtypes[] = {
+      {"ip6gretap", "ip6gretap0"}, {"bridge", "bridge0"},
+      {"vcan", "vcan0"},           {"bond", "bond0"},
+      {"team", "team0"},           {"dummy", "dummy0"},
+      {"nlmon", "nlmon0"},         {"caif", "caif0"},
+      {"batadv", "batadv0"},       {"vxcan", "vxcan1"},
+      {"netdevsim", netdevsim},    {"veth", 0},
+      {"xfrm", "xfrm0"},           {"wireguard", "wg0"},
+      {"wireguard", "wg1"},        {"wireguard", "wg2"},
+  };
+  const char* devmasters[] = {"bridge", "bond", "team", "batadv"};
+  struct {
+    const char* name;
+    int macsize;
+    bool noipv6;
+  } devices[] = {
+      {"lo", ETH_ALEN},
+      {"sit0", 0},
+      {"bridge0", ETH_ALEN},
+      {"vcan0", 0, true},
+      {"tunl0", 0},
+      {"gre0", 0},
+      {"gretap0", ETH_ALEN},
+      {"ip_vti0", 0},
+      {"ip6_vti0", 0},
+      {"ip6tnl0", 0},
+      {"ip6gre0", 0},
+      {"ip6gretap0", ETH_ALEN},
+      {"erspan0", ETH_ALEN},
+      {"bond0", ETH_ALEN},
+      {"veth0", ETH_ALEN},
+      {"veth1", ETH_ALEN},
+      {"team0", ETH_ALEN},
+      {"veth0_to_bridge", ETH_ALEN},
+      {"veth1_to_bridge", ETH_ALEN},
+      {"veth0_to_bond", ETH_ALEN},
+      {"veth1_to_bond", ETH_ALEN},
+      {"veth0_to_team", ETH_ALEN},
+      {"veth1_to_team", ETH_ALEN},
+      {"veth0_to_hsr", ETH_ALEN},
+      {"veth1_to_hsr", ETH_ALEN},
+      {"hsr0", 0},
+      {"dummy0", ETH_ALEN},
+      {"nlmon0", 0},
+      {"vxcan0", 0, true},
+      {"vxcan1", 0, true},
+      {"caif0", ETH_ALEN},
+      {"batadv0", ETH_ALEN},
+      {netdevsim, ETH_ALEN},
+      {"xfrm0", ETH_ALEN},
+      {"veth0_virt_wifi", ETH_ALEN},
+      {"veth1_virt_wifi", ETH_ALEN},
+      {"virt_wifi0", ETH_ALEN},
+      {"veth0_vlan", ETH_ALEN},
+      {"veth1_vlan", ETH_ALEN},
+      {"vlan0", ETH_ALEN},
+      {"vlan1", ETH_ALEN},
+      {"macvlan0", ETH_ALEN},
+      {"macvlan1", ETH_ALEN},
+      {"ipvlan0", ETH_ALEN},
+      {"ipvlan1", ETH_ALEN},
+      {"veth0_macvtap", ETH_ALEN},
+      {"veth1_macvtap", ETH_ALEN},
+      {"macvtap0", ETH_ALEN},
+      {"macsec0", ETH_ALEN},
+      {"veth0_to_batadv", ETH_ALEN},
+      {"veth1_to_batadv", ETH_ALEN},
+      {"batadv_slave_0", ETH_ALEN},
+      {"batadv_slave_1", ETH_ALEN},
+      {"geneve0", ETH_ALEN},
+      {"geneve1", ETH_ALEN},
+      {"wg0", 0},
+      {"wg1", 0},
+      {"wg2", 0},
+  };
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++)
+    netlink_add_device(&nlmsg, sock, devtypes[i].type, devtypes[i].dev);
+  for (i = 0; i < sizeof(devmasters) / (sizeof(devmasters[0])); i++) {
+    char master[32], slave0[32], veth0[32], slave1[32], veth1[32];
+    sprintf(slave0, "%s_slave_0", devmasters[i]);
+    sprintf(veth0, "veth0_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave0, veth0);
+    sprintf(slave1, "%s_slave_1", devmasters[i]);
+    sprintf(veth1, "veth1_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave1, veth1);
+    sprintf(master, "%s0", devmasters[i]);
+    netlink_device_change(&nlmsg, sock, slave0, false, master, 0, 0, NULL);
+    netlink_device_change(&nlmsg, sock, slave1, false, master, 0, 0, NULL);
+  }
+  netlink_device_change(&nlmsg, sock, "bridge_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "bridge_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_0", "veth0_to_hsr");
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_1", "veth1_to_hsr");
+  netlink_add_hsr(&nlmsg, sock, "hsr0", "hsr_slave_0", "hsr_slave_1");
+  netlink_device_change(&nlmsg, sock, "hsr_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "hsr_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "veth0_virt_wifi", "veth1_virt_wifi");
+  netlink_add_linked(&nlmsg, sock, "virt_wifi", "virt_wifi0",
+                     "veth1_virt_wifi");
+  netlink_add_veth(&nlmsg, sock, "veth0_vlan", "veth1_vlan");
+  netlink_add_vlan(&nlmsg, sock, "vlan0", "veth0_vlan", 0, htons(ETH_P_8021Q));
+  netlink_add_vlan(&nlmsg, sock, "vlan1", "veth0_vlan", 1, htons(ETH_P_8021AD));
+  netlink_add_macvlan(&nlmsg, sock, "macvlan0", "veth1_vlan");
+  netlink_add_macvlan(&nlmsg, sock, "macvlan1", "veth1_vlan");
+  netlink_add_ipvlan(&nlmsg, sock, "ipvlan0", "veth0_vlan", IPVLAN_MODE_L2, 0);
+  netlink_add_ipvlan(&nlmsg, sock, "ipvlan1", "veth0_vlan", IPVLAN_MODE_L3S,
+                     IPVLAN_F_VEPA);
+  netlink_add_veth(&nlmsg, sock, "veth0_macvtap", "veth1_macvtap");
+  netlink_add_linked(&nlmsg, sock, "macvtap", "macvtap0", "veth0_macvtap");
+  netlink_add_linked(&nlmsg, sock, "macsec", "macsec0", "veth1_macvtap");
+  char addr[32];
+  sprintf(addr, DEV_IPV4, 14 + 10);
+  struct in_addr geneve_addr4;
+  if (inet_pton(AF_INET, addr, &geneve_addr4) <= 0)
+    exit(1);
+  struct in6_addr geneve_addr6;
+  if (inet_pton(AF_INET6, "fc00::01", &geneve_addr6) <= 0)
+    exit(1);
+  netlink_add_geneve(&nlmsg, sock, "geneve0", 0, &geneve_addr4, 0);
+  netlink_add_geneve(&nlmsg, sock, "geneve1", 1, 0, &geneve_addr6);
+  netdevsim_add((int)procid, 4);
+  netlink_wireguard_setup();
+  for (i = 0; i < sizeof(devices) / (sizeof(devices[0])); i++) {
+    char addr[32];
+    sprintf(addr, DEV_IPV4, i + 10);
+    netlink_add_addr4(&nlmsg, sock, devices[i].name, addr);
+    if (!devices[i].noipv6) {
+      sprintf(addr, DEV_IPV6, i + 10);
+      netlink_add_addr6(&nlmsg, sock, devices[i].name, addr);
+    }
+    uint64_t macaddr = DEV_MAC + ((i + 10ull) << 40);
+    netlink_device_change(&nlmsg, sock, devices[i].name, true, 0, &macaddr,
+                          devices[i].macsize, NULL);
+  }
+  close(sock);
+}
+static void initialize_netdevices_init(void)
+{
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  struct {
+    const char* type;
+    int macsize;
+    bool noipv6;
+    bool noup;
+  } devtypes[] = {
+      {"nr", 7, true},
+      {"rose", 5, true, true},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++) {
+    char dev[32], addr[32];
+    sprintf(dev, "%s%d", devtypes[i].type, (int)procid);
+    sprintf(addr, "172.30.%d.%d", i, (int)procid + 1);
+    netlink_add_addr4(&nlmsg, sock, dev, addr);
+    if (!devtypes[i].noipv6) {
+      sprintf(addr, "fe88::%02x:%02x", i, (int)procid + 1);
+      netlink_add_addr6(&nlmsg, sock, dev, addr);
+    }
+    int macsize = devtypes[i].macsize;
+    uint64_t macaddr = 0xbbbbbb +
+                       ((unsigned long long)i << (8 * (macsize - 2))) +
+                       (procid << (8 * (macsize - 1)));
+    netlink_device_change(&nlmsg, sock, dev, !devtypes[i].noup, 0, &macaddr,
+                          macsize, NULL);
+  }
+  close(sock);
+}
+
+static void setup_common()
+{
+  if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
+  }
+}
+
+static void loop();
+
+static void sandbox_common()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setsid();
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  if (dup2(netns, kInitNetNsFd) < 0)
+    exit(1);
+  close(netns);
+  struct rlimit rlim;
+  rlim.rlim_cur = rlim.rlim_max = (200 << 20);
+  setrlimit(RLIMIT_AS, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 32 << 20;
+  setrlimit(RLIMIT_MEMLOCK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 136 << 20;
+  setrlimit(RLIMIT_FSIZE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+  setrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 0;
+  setrlimit(RLIMIT_CORE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 256;
+  setrlimit(RLIMIT_NOFILE, &rlim);
+  if (unshare(CLONE_NEWNS)) {
+  }
+  if (unshare(CLONE_NEWIPC)) {
+  }
+  if (unshare(0x02000000)) {
+  }
+  if (unshare(CLONE_NEWUTS)) {
+  }
+  if (unshare(CLONE_SYSVSEM)) {
+  }
+  typedef struct {
+    const char* name;
+    const char* value;
+  } sysctl_t;
+  static const sysctl_t sysctls[] = {
+      {"/proc/sys/kernel/shmmax", "16777216"},
+      {"/proc/sys/kernel/shmall", "536870912"},
+      {"/proc/sys/kernel/shmmni", "1024"},
+      {"/proc/sys/kernel/msgmax", "8192"},
+      {"/proc/sys/kernel/msgmni", "1024"},
+      {"/proc/sys/kernel/msgmnb", "1024"},
+      {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
+    write_file(sysctls[i].name, sysctls[i].value);
+}
+
+int wait_for_loop(int pid)
+{
+  if (pid < 0)
+    exit(1);
+  int status = 0;
+  while (waitpid(-1, &status, __WALL) != pid) {
+  }
+  return WEXITSTATUS(status);
+}
+
+static void drop_caps(void)
+{
+  struct __user_cap_header_struct cap_hdr = {};
+  struct __user_cap_data_struct cap_data[2] = {};
+  cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
+  cap_hdr.pid = getpid();
+  if (syscall(SYS_capget, &cap_hdr, &cap_data))
+    exit(1);
+  const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
+  cap_data[0].effective &= ~drop;
+  cap_data[0].permitted &= ~drop;
+  cap_data[0].inheritable &= ~drop;
+  if (syscall(SYS_capset, &cap_hdr, &cap_data))
+    exit(1);
+}
+
+static int do_sandbox_none(void)
+{
+  int pid = fork();
+  if (pid != 0)
+    return wait_for_loop(pid);
+  setup_common();
+  sandbox_common();
+  drop_caps();
+  initialize_netdevices_init();
+  if (unshare(CLONE_NEWNET)) {
+  }
+  initialize_devlink_pci();
+  initialize_netdevices();
+  loop();
+  exit(1);
+}
+
+static int inject_fault(int nth)
+{
+  int fd;
+  fd = open("/proc/thread-self/fail-nth", O_RDWR);
+  if (fd == -1)
+    exit(1);
+  char buf[16];
+  sprintf(buf, "%d", nth + 1);
+  if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf))
+    exit(1);
+  return fd;
+}
+
+static void setup_fault()
+{
+  static struct {
+    const char* file;
+    const char* val;
+    bool fatal;
+  } files[] = {
+      {"/sys/kernel/debug/failslab/ignore-gfp-wait", "N", true},
+      {"/sys/kernel/debug/fail_futex/ignore-private", "N", false},
+      {"/sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem", "N", false},
+      {"/sys/kernel/debug/fail_page_alloc/ignore-gfp-wait", "N", false},
+      {"/sys/kernel/debug/fail_page_alloc/min-order", "0", false},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(files) / sizeof(files[0]); i++) {
+    if (!write_file(files[i].file, files[i].val)) {
+      if (files[i].fatal)
+        exit(1);
+    }
+  }
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void loop(void)
+{
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0x14ul);
+  if (res != -1)
+    r[0] = res;
+  NONFAILING(*(uint64_t*)0x200031c0 = 0);
+  NONFAILING(*(uint32_t*)0x200031c8 = 0);
+  NONFAILING(*(uint64_t*)0x200031d0 = 0x20003180);
+  NONFAILING(*(uint64_t*)0x20003180 = 0x20000000);
+  NONFAILING(*(uint32_t*)0x20000000 = 0x38);
+  NONFAILING(*(uint16_t*)0x20000004 = 0x1403);
+  NONFAILING(*(uint16_t*)0x20000006 = 1);
+  NONFAILING(*(uint32_t*)0x20000008 = 0);
+  NONFAILING(*(uint32_t*)0x2000000c = 0);
+  NONFAILING(*(uint16_t*)0x20000010 = 9);
+  NONFAILING(*(uint16_t*)0x20000012 = 2);
+  NONFAILING(memcpy((void*)0x20000014, "syz1\000", 5));
+  NONFAILING(*(uint16_t*)0x2000001c = 8);
+  NONFAILING(*(uint16_t*)0x2000001e = 0x41);
+  NONFAILING(memcpy((void*)0x20000020, "siw\000", 4));
+  NONFAILING(*(uint16_t*)0x20000024 = 0x14);
+  NONFAILING(*(uint16_t*)0x20000026 = 0x33);
+  NONFAILING(
+      memcpy((void*)0x20000028,
+             "lo\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16));
+  NONFAILING(*(uint64_t*)0x20003188 = 0x38);
+  NONFAILING(*(uint64_t*)0x200031d8 = 1);
+  NONFAILING(*(uint64_t*)0x200031e0 = 0);
+  NONFAILING(*(uint64_t*)0x200031e8 = 0);
+  NONFAILING(*(uint32_t*)0x200031f0 = 0);
+  inject_fault(4);
+  syscall(__NR_sendmsg, r[0], 0x200031c0ul, 0ul);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  setup_fault();
+  install_segv_handler();
+  use_temporary_dir();
+  do_sandbox_none();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0f798bd6908a49a54cb972b2b92241e5783c6421.c b/syzkaller-repros/linux/0f798bd6908a49a54cb972b2b92241e5783c6421.c
new file mode 100644
index 0000000..c5796c6
--- /dev/null
+++ b/syzkaller-repros/linux/0f798bd6908a49a54cb972b2b92241e5783c6421.c
@@ -0,0 +1,454 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.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 <sys/mount.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/usb/ch9.h>
+
+unsigned long long procid;
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+#define USB_MAX_EP_NUM 32
+
+struct usb_device_index {
+  struct usb_device_descriptor* dev;
+  struct usb_config_descriptor* config;
+  unsigned config_length;
+  struct usb_interface_descriptor* iface;
+  struct usb_endpoint_descriptor* eps[USB_MAX_EP_NUM];
+  unsigned eps_num;
+};
+
+static bool parse_usb_descriptor(char* buffer, size_t length,
+                                 struct usb_device_index* index)
+{
+  if (length <
+      sizeof(*index->dev) + sizeof(*index->config) + sizeof(*index->iface))
+    return false;
+  index->dev = (struct usb_device_descriptor*)buffer;
+  index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
+  index->config_length = length - sizeof(*index->dev);
+  index->iface =
+      (struct usb_interface_descriptor*)(buffer + sizeof(*index->dev) +
+                                         sizeof(*index->config));
+  index->eps_num = 0;
+  size_t offset = 0;
+  while (true) {
+    if (offset == length)
+      break;
+    if (offset + 1 < length)
+      break;
+    uint8_t length = buffer[offset];
+    uint8_t type = buffer[offset + 1];
+    if (type == USB_DT_ENDPOINT) {
+      index->eps[index->eps_num] =
+          (struct usb_endpoint_descriptor*)(buffer + offset);
+      index->eps_num++;
+    }
+    if (index->eps_num == USB_MAX_EP_NUM)
+      break;
+    offset += length;
+  }
+  return true;
+}
+
+enum usb_fuzzer_event_type {
+  USB_FUZZER_EVENT_INVALID,
+  USB_FUZZER_EVENT_CONNECT,
+  USB_FUZZER_EVENT_DISCONNECT,
+  USB_FUZZER_EVENT_SUSPEND,
+  USB_FUZZER_EVENT_RESUME,
+  USB_FUZZER_EVENT_CONTROL,
+};
+
+struct usb_fuzzer_event {
+  uint32_t type;
+  uint32_t length;
+  char data[0];
+};
+
+struct usb_fuzzer_init {
+  uint64_t speed;
+  const char* driver_name;
+  const char* device_name;
+};
+
+struct usb_fuzzer_ep_io {
+  uint16_t ep;
+  uint16_t flags;
+  uint32_t length;
+  char data[0];
+};
+
+#define USB_FUZZER_IOCTL_INIT _IOW('U', 0, struct usb_fuzzer_init)
+#define USB_FUZZER_IOCTL_RUN _IO('U', 1)
+#define USB_FUZZER_IOCTL_EP0_READ _IOWR('U', 2, struct usb_fuzzer_event)
+#define USB_FUZZER_IOCTL_EP0_WRITE _IOW('U', 3, struct usb_fuzzer_ep_io)
+#define USB_FUZZER_IOCTL_EP_ENABLE _IOW('U', 4, struct usb_endpoint_descriptor)
+#define USB_FUZZER_IOCTL_EP_WRITE _IOW('U', 6, struct usb_fuzzer_ep_io)
+#define USB_FUZZER_IOCTL_CONFIGURE _IO('U', 8)
+#define USB_FUZZER_IOCTL_VBUS_DRAW _IOW('U', 9, uint32_t)
+
+int usb_fuzzer_open()
+{
+  return open("/sys/kernel/debug/usb-fuzzer", O_RDWR);
+}
+
+int usb_fuzzer_init(int fd, uint32_t speed, const char* driver,
+                    const char* device)
+{
+  struct usb_fuzzer_init arg;
+  arg.speed = speed;
+  arg.driver_name = driver;
+  arg.device_name = device;
+  return ioctl(fd, USB_FUZZER_IOCTL_INIT, &arg);
+}
+
+int usb_fuzzer_run(int fd)
+{
+  return ioctl(fd, USB_FUZZER_IOCTL_RUN, 0);
+}
+
+int usb_fuzzer_ep0_read(int fd, struct usb_fuzzer_event* event)
+{
+  return ioctl(fd, USB_FUZZER_IOCTL_EP0_READ, event);
+}
+
+int usb_fuzzer_ep0_write(int fd, struct usb_fuzzer_ep_io* io)
+{
+  return ioctl(fd, USB_FUZZER_IOCTL_EP0_WRITE, io);
+}
+
+int usb_fuzzer_ep_write(int fd, struct usb_fuzzer_ep_io* io)
+{
+  return ioctl(fd, USB_FUZZER_IOCTL_EP_WRITE, io);
+}
+
+int usb_fuzzer_ep_enable(int fd, struct usb_endpoint_descriptor* desc)
+{
+  return ioctl(fd, USB_FUZZER_IOCTL_EP_ENABLE, desc);
+}
+
+int usb_fuzzer_configure(int fd)
+{
+  return ioctl(fd, USB_FUZZER_IOCTL_CONFIGURE, 0);
+}
+
+int usb_fuzzer_vbus_draw(int fd, uint32_t power)
+{
+  return ioctl(fd, USB_FUZZER_IOCTL_VBUS_DRAW, power);
+}
+
+#define USB_MAX_PACKET_SIZE 1024
+
+struct usb_fuzzer_control_event {
+  struct usb_fuzzer_event inner;
+  struct usb_ctrlrequest ctrl;
+};
+
+struct usb_fuzzer_ep_io_data {
+  struct usb_fuzzer_ep_io inner;
+  char data[USB_MAX_PACKET_SIZE];
+};
+
+struct vusb_connect_string_descriptor {
+  uint32_t len;
+  char* str;
+} __attribute__((packed));
+
+struct vusb_connect_descriptors {
+  uint32_t qual_len;
+  char* qual;
+  uint32_t bos_len;
+  char* bos;
+  uint32_t strs_len;
+  struct vusb_connect_string_descriptor strs[0];
+} __attribute__((packed));
+
+static volatile long syz_usb_connect(volatile long a0, volatile long a1,
+                                     volatile long a2, volatile long a3)
+{
+  int64_t speed = a0;
+  int64_t dev_len = a1;
+  char* dev = (char*)a2;
+  struct vusb_connect_descriptors* conn_descs =
+      (struct vusb_connect_descriptors*)a3;
+  if (!dev)
+    return -1;
+  struct usb_device_index index;
+  memset(&index, 0, sizeof(index));
+  int rv = parse_usb_descriptor(dev, dev_len, &index);
+  if (!rv)
+    return -1;
+  int fd = usb_fuzzer_open();
+  if (fd < 0)
+    return -1;
+  char device[32];
+  sprintf(&device[0], "dummy_udc.%llu", procid);
+  rv = usb_fuzzer_init(fd, speed, "dummy_udc", &device[0]);
+  if (rv < 0)
+    return -1;
+  rv = usb_fuzzer_run(fd);
+  if (rv < 0)
+    return -1;
+  bool done = false;
+  while (!done) {
+    char* response_data = NULL;
+    uint32_t response_length = 0;
+    unsigned ep;
+    uint8_t str_idx;
+    struct usb_fuzzer_control_event event;
+    event.inner.type = 0;
+    event.inner.length = sizeof(event.ctrl);
+    rv = usb_fuzzer_ep0_read(fd, (struct usb_fuzzer_event*)&event);
+    if (rv < 0)
+      return -1;
+    if (event.inner.type != USB_FUZZER_EVENT_CONTROL)
+      continue;
+    switch (event.ctrl.bRequestType & USB_TYPE_MASK) {
+    case USB_TYPE_STANDARD:
+      switch (event.ctrl.bRequest) {
+      case USB_REQ_GET_DESCRIPTOR:
+        switch (event.ctrl.wValue >> 8) {
+        case USB_DT_DEVICE:
+          response_data = (char*)index.dev;
+          response_length = sizeof(*index.dev);
+          goto reply;
+        case USB_DT_CONFIG:
+          response_data = (char*)index.config;
+          response_length = index.config_length;
+          goto reply;
+        case USB_DT_STRING:
+          str_idx = (uint8_t)event.ctrl.wValue;
+          if (str_idx >= conn_descs->strs_len)
+            goto reply;
+          response_data = conn_descs->strs[str_idx].str;
+          response_length = conn_descs->strs[str_idx].len;
+          goto reply;
+        case USB_DT_BOS:
+          response_data = conn_descs->bos;
+          response_length = conn_descs->bos_len;
+          goto reply;
+        case USB_DT_DEVICE_QUALIFIER:
+          response_data = conn_descs->qual;
+          response_length = conn_descs->qual_len;
+          goto reply;
+        default:
+          exit(1);
+          continue;
+        }
+        break;
+      case USB_REQ_SET_CONFIGURATION:
+        rv = usb_fuzzer_vbus_draw(fd, index.config->bMaxPower);
+        if (rv < 0)
+          return -1;
+        rv = usb_fuzzer_configure(fd);
+        if (rv < 0)
+          return -1;
+        for (ep = 0; ep < index.eps_num; ep++) {
+          rv = usb_fuzzer_ep_enable(fd, index.eps[ep]);
+          if (rv < 0)
+            exit(1);
+        }
+        done = true;
+        goto reply;
+      default:
+        exit(1);
+        continue;
+      }
+      break;
+    default:
+      exit(1);
+      continue;
+    }
+    struct usb_fuzzer_ep_io_data response;
+  reply:
+    response.inner.ep = 0;
+    response.inner.flags = 0;
+    if (response_length > sizeof(response.data))
+      response_length = 0;
+    response.inner.length = response_length;
+    if (response_data)
+      memcpy(&response.data[0], response_data, response_length);
+    if (event.ctrl.wLength < response.inner.length)
+      response.inner.length = event.ctrl.wLength;
+    usb_fuzzer_ep0_write(fd, (struct usb_fuzzer_ep_io*)&response);
+  }
+  sleep_ms(200);
+  return fd;
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+#define SYZ_HAVE_SETUP_TEST 1
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  int iter;
+  for (iter = 0;; iter++) {
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      setup_test();
+      execute_one();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+  }
+}
+
+void execute_one(void)
+{
+  *(uint8_t*)0x20000000 = 0x12;
+  *(uint8_t*)0x20000001 = 1;
+  *(uint16_t*)0x20000002 = 0;
+  *(uint8_t*)0x20000004 = 0x58;
+  *(uint8_t*)0x20000005 = 0x7e;
+  *(uint8_t*)0x20000006 = 0xc7;
+  *(uint8_t*)0x20000007 = 8;
+  *(uint16_t*)0x20000008 = 0x841;
+  *(uint16_t*)0x2000000a = 1;
+  *(uint16_t*)0x2000000c = 0xed74;
+  *(uint8_t*)0x2000000e = 0;
+  *(uint8_t*)0x2000000f = 0;
+  *(uint8_t*)0x20000010 = 0;
+  *(uint8_t*)0x20000011 = 1;
+  *(uint8_t*)0x20000012 = 9;
+  *(uint8_t*)0x20000013 = 2;
+  *(uint16_t*)0x20000014 = 0x12;
+  *(uint8_t*)0x20000016 = 1;
+  *(uint8_t*)0x20000017 = 0;
+  *(uint8_t*)0x20000018 = 0;
+  *(uint8_t*)0x20000019 = 0;
+  *(uint8_t*)0x2000001a = 0;
+  *(uint8_t*)0x2000001b = 9;
+  *(uint8_t*)0x2000001c = 4;
+  *(uint8_t*)0x2000001d = 0x6e;
+  *(uint8_t*)0x2000001e = 0;
+  *(uint8_t*)0x2000001f = 0;
+  *(uint8_t*)0x20000020 = 0xe5;
+  *(uint8_t*)0x20000021 = 0xb7;
+  *(uint8_t*)0x20000022 = -1;
+  *(uint8_t*)0x20000023 = 0;
+  syz_usb_connect(5, 0x24, 0x20000000, 0);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0);
+  for (procid = 0; procid < 8; procid++) {
+    if (fork() == 0) {
+      loop();
+    }
+  }
+  sleep(1000000);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/0fac2c3f760499a1802232af55857850a18713c0.c b/syzkaller-repros/linux/0fac2c3f760499a1802232af55857850a18713c0.c
new file mode 100644
index 0000000..c6bb798
--- /dev/null
+++ b/syzkaller-repros/linux/0fac2c3f760499a1802232af55857850a18713c0.c
@@ -0,0 +1,400 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/futex.h>
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+  pthread_t th;
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setstacksize(&attr, 128 << 10);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (pthread_create(&th, &attr, fn, arg) == 0) {
+      pthread_attr_destroy(&attr);
+      return;
+    }
+    if (errno == EAGAIN) {
+      usleep(50);
+      continue;
+    }
+    break;
+  }
+  exit(1);
+}
+
+typedef struct {
+  int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+  if (ev->state)
+    exit(1);
+  __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
+  syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
+}
+
+static void event_wait(event_t* ev)
+{
+  while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
+}
+
+static int event_isset(event_t* ev)
+{
+  return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+  uint64_t start = current_time_ms();
+  uint64_t now = start;
+  for (;;) {
+    uint64_t remain = timeout - (now - start);
+    struct timespec ts;
+    ts.tv_sec = remain / 1000;
+    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
+    if (__atomic_load_n(&ev->state, __ATOMIC_RELAXED))
+      return 1;
+    now = current_time_ms();
+    if (now - start > timeout)
+      return 0;
+  }
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+}
+
+struct thread_t {
+  int created, call;
+  event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+  struct thread_t* th = (struct thread_t*)arg;
+  for (;;) {
+    event_wait(&th->ready);
+    event_reset(&th->ready);
+    execute_call(th->call);
+    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+    event_set(&th->done);
+  }
+  return 0;
+}
+
+static void execute_one(void)
+{
+  int i, call, thread;
+  int collide = 0;
+again:
+  for (call = 0; call < 12; call++) {
+    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+         thread++) {
+      struct thread_t* th = &threads[thread];
+      if (!th->created) {
+        th->created = 1;
+        event_init(&th->ready);
+        event_init(&th->done);
+        event_set(&th->done);
+        thread_start(thr, th);
+      }
+      if (!event_isset(&th->done))
+        continue;
+      event_reset(&th->done);
+      th->call = call;
+      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+      event_set(&th->ready);
+      if (collide && (call % 2) == 0)
+        break;
+      event_timedwait(&th->done, 45);
+      break;
+    }
+  }
+  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+    sleep_ms(1);
+  if (!collide) {
+    collide = 1;
+    goto again;
+  }
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  int iter;
+  for (iter = 0;; iter++) {
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      setup_test();
+      execute_one();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+  }
+}
+
+uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0,
+                 0xffffffffffffffff};
+
+void execute_call(int call)
+{
+  intptr_t res;
+  switch (call) {
+  case 0:
+    res = syscall(__NR_socket, 0xaul, 5ul, 0x84ul);
+    if (res != -1)
+      r[0] = res;
+    break;
+  case 1:
+    syscall(__NR_shutdown, r[0], 0ul);
+    break;
+  case 2:
+    *(uint32_t*)0x20000000 = 0;
+    *(uint32_t*)0x20000004 = 0x1c;
+    *(uint64_t*)0x20000008 = 0x20000080;
+    *(uint16_t*)0x20000080 = 0xa;
+    *(uint16_t*)0x20000082 = htobe16(0);
+    *(uint32_t*)0x20000084 = htobe32(0);
+    memcpy((void*)0x20000088,
+           "\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+           16);
+    *(uint32_t*)0x20000098 = 0;
+    *(uint32_t*)0x20000180 = 0x10;
+    syscall(__NR_getsockopt, r[0], 0x84ul, 0x6ful, 0x20000000ul, 0x20000180ul);
+    break;
+  case 3:
+    res = syscall(__NR_socket, 2ul, 0x80001ul, 0x84);
+    if (res != -1)
+      r[1] = res;
+    break;
+  case 4:
+    *(uint32_t*)0x20000040 = 8;
+    res = syscall(__NR_getsockopt, r[1], 0x84ul, 0x14ul, 0x20000000ul,
+                  0x20000040ul);
+    if (res != -1)
+      r[2] = *(uint32_t*)0x20000000;
+    break;
+  case 5:
+    *(uint32_t*)0x200000c0 = r[2];
+    *(uint32_t*)0x200000c4 = 0;
+    *(uint32_t*)0x200000c8 = 0;
+    *(uint32_t*)0x200000cc = 0;
+    syscall(__NR_setsockopt, -1, 0x84ul, 0ul, 0x200000c0ul, 0x10ul);
+    break;
+  case 6:
+    *(uint16_t*)0x20000000 = 0xa;
+    *(uint16_t*)0x20000002 = htobe16(0);
+    *(uint32_t*)0x20000004 = htobe32(0);
+    *(uint8_t*)0x20000008 = 0xfe;
+    *(uint8_t*)0x20000009 = 0x88;
+    *(uint8_t*)0x2000000a = 0;
+    *(uint8_t*)0x2000000b = 0;
+    *(uint8_t*)0x2000000c = 0;
+    *(uint8_t*)0x2000000d = 0;
+    *(uint8_t*)0x2000000e = 0;
+    *(uint8_t*)0x2000000f = 0;
+    *(uint8_t*)0x20000010 = 0;
+    *(uint8_t*)0x20000011 = 0;
+    *(uint8_t*)0x20000012 = 0;
+    *(uint8_t*)0x20000013 = 0;
+    *(uint8_t*)0x20000014 = 0;
+    *(uint8_t*)0x20000015 = 0;
+    *(uint8_t*)0x20000016 = 0;
+    *(uint8_t*)0x20000017 = 1;
+    *(uint32_t*)0x20000018 = 0;
+    *(uint16_t*)0x2000001c = 0xa;
+    *(uint16_t*)0x2000001e = htobe16(0);
+    *(uint32_t*)0x20000020 = htobe32(0);
+    *(uint8_t*)0x20000024 = -1;
+    *(uint8_t*)0x20000025 = 2;
+    *(uint8_t*)0x20000026 = 0;
+    *(uint8_t*)0x20000027 = 0;
+    *(uint8_t*)0x20000028 = 0;
+    *(uint8_t*)0x20000029 = 0;
+    *(uint8_t*)0x2000002a = 0;
+    *(uint8_t*)0x2000002b = 0;
+    *(uint8_t*)0x2000002c = 0;
+    *(uint8_t*)0x2000002d = 0;
+    *(uint8_t*)0x2000002e = 0;
+    *(uint8_t*)0x2000002f = 0;
+    *(uint8_t*)0x20000030 = 0;
+    *(uint8_t*)0x20000031 = 0;
+    *(uint8_t*)0x20000032 = 0;
+    *(uint8_t*)0x20000033 = 1;
+    *(uint32_t*)0x20000034 = 0;
+    *(uint16_t*)0x20000038 = 2;
+    *(uint32_t*)0x2000003c = 0;
+    *(uint32_t*)0x20000040 = 0;
+    *(uint32_t*)0x20000044 = 0;
+    *(uint32_t*)0x20000048 = 0;
+    *(uint32_t*)0x2000004c = 0;
+    *(uint32_t*)0x20000050 = 0;
+    *(uint32_t*)0x20000054 = 0;
+    *(uint32_t*)0x20000058 = 0;
+    syscall(__NR_setsockopt, -1, 0x29ul, 0xccul, 0x20000000ul, 0x5cul);
+    break;
+  case 7:
+    res = syscall(__NR_socket, 0x10ul, 3ul, 6);
+    if (res != -1)
+      r[3] = res;
+    break;
+  case 8:
+    memcpy((void*)0x20000000,
+           "\x1b\xa0\x00\x00\x19\x00\x1d\x0d\x89\xfd\xc5\xcb\xdd\x04\x57\x98"
+           "\x70\x7b\xed\x4d\xca\x14\xa7\x96\x0f\x0f\x8e\xc8\xda\x78\x03\x1c"
+           "\x76\x60\xb0\x8f\x51\x5e",
+           38);
+    syscall(__NR_sendto, r[3], 0x20000000ul, 0xff3bul, 0ul, 0ul, 0x2e2ul);
+    break;
+  case 9:
+    memcpy((void*)0x20000080,
+           "\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x01\x00\x05\x02\x00\x00\x00"
+           "\x01\x00\x07\x10\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00"
+           "\x00\x01\x00\x00\x04\xba\x05\xc9\x10\xfe\x88\x00\x00\x00\x00\x00"
+           "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x15",
+           59);
+    syscall(__NR_setsockopt, -1, 0x29ul, 0ul, 0x20000080ul, 1ul);
+    break;
+  case 10:
+    syscall(__NR_getsockopt, -1, 0x84ul, 0x6ful, 0ul, 0ul);
+    break;
+  case 11:
+    syscall(__NR_recvfrom, -1, 0ul, 0ul, 0x700ul, 0ul, 0ul);
+    break;
+  }
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  loop();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/10681a527a04da4b77753f36780b87143714d47d.c b/syzkaller-repros/linux/10681a527a04da4b77753f36780b87143714d47d.c
new file mode 100644
index 0000000..b881c5d
--- /dev/null
+++ b/syzkaller-repros/linux/10681a527a04da4b77753f36780b87143714d47d.c
@@ -0,0 +1,226 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+#define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off))
+#define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len)               \
+  *(type*)(addr) =                                                             \
+      htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) |           \
+            (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len))))
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  int iter;
+  for (iter = 0;; iter++) {
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      setup_test();
+      execute_one();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+  }
+}
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_one(void)
+{
+  intptr_t res = 0;
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[0] = res;
+  *(uint64_t*)0x20000240 = 0;
+  *(uint32_t*)0x20000248 = 0;
+  *(uint64_t*)0x20000250 = 0x20000200;
+  *(uint64_t*)0x20000200 = 0x200001c0;
+  *(uint32_t*)0x200001c0 = 0x1c;
+  *(uint8_t*)0x200001c4 = 7;
+  *(uint8_t*)0x200001c5 = 6;
+  *(uint16_t*)0x200001c6 = 0x801;
+  *(uint32_t*)0x200001c8 = 0;
+  *(uint32_t*)0x200001cc = 0;
+  *(uint8_t*)0x200001d0 = 0;
+  *(uint8_t*)0x200001d1 = 0;
+  *(uint16_t*)0x200001d2 = htobe16(0);
+  *(uint16_t*)0x200001d4 = 5;
+  *(uint16_t*)0x200001d6 = 1;
+  *(uint8_t*)0x200001d8 = 7;
+  *(uint64_t*)0x20000208 = 0x1c;
+  *(uint64_t*)0x20000258 = 1;
+  *(uint64_t*)0x20000260 = 0;
+  *(uint64_t*)0x20000268 = 0;
+  *(uint32_t*)0x20000270 = 0;
+  syscall(__NR_sendmsg, r[0], 0x20000240ul, 0ul);
+  syscall(__NR_recvfrom, -1, 0ul, 0ul, 0xf00ul, 0ul, 0ul);
+  res = syscall(__NR_socket, 0x10ul, 3ul, 0xcul);
+  if (res != -1)
+    r[1] = res;
+  *(uint64_t*)0x20000140 = 0;
+  *(uint32_t*)0x20000148 = 0x4000000;
+  *(uint64_t*)0x20000150 = 0x20000100;
+  *(uint64_t*)0x20000100 = 0x20000040;
+  *(uint32_t*)0x20000040 = 0x5c;
+  *(uint8_t*)0x20000044 = 2;
+  *(uint8_t*)0x20000045 = 6;
+  *(uint16_t*)0x20000046 = 0x101;
+  *(uint32_t*)0x20000048 = 0;
+  *(uint32_t*)0x2000004c = 0;
+  *(uint8_t*)0x20000050 = 0;
+  *(uint8_t*)0x20000051 = 0;
+  *(uint16_t*)0x20000052 = htobe16(0);
+  *(uint16_t*)0x20000054 = 5;
+  *(uint16_t*)0x20000056 = 1;
+  *(uint8_t*)0x20000058 = 7;
+  *(uint16_t*)0x2000005c = 5;
+  *(uint16_t*)0x2000005e = 4;
+  *(uint8_t*)0x20000060 = 0;
+  *(uint16_t*)0x20000064 = 0x10;
+  *(uint16_t*)0x20000066 = 3;
+  memcpy((void*)0x20000068, "bitmap:port\000", 12);
+  *(uint16_t*)0x20000074 = 0x14;
+  STORE_BY_BITMASK(uint16_t, , 0x20000076, 7, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000077, 0, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000077, 1, 7, 1);
+  *(uint16_t*)0x20000078 = 6;
+  STORE_BY_BITMASK(uint16_t, , 0x2000007a, 5, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x2000007b, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x2000007b, 0, 7, 1);
+  *(uint16_t*)0x2000007c = htobe16(0);
+  *(uint16_t*)0x20000080 = 6;
+  STORE_BY_BITMASK(uint16_t, , 0x20000082, 4, 0, 14);
+  STORE_BY_BITMASK(uint16_t, , 0x20000083, 1, 6, 1);
+  STORE_BY_BITMASK(uint16_t, , 0x20000083, 0, 7, 1);
+  *(uint16_t*)0x20000084 = htobe16(0);
+  *(uint16_t*)0x20000088 = 9;
+  *(uint16_t*)0x2000008a = 2;
+  memcpy((void*)0x2000008c, "syz0\000", 5);
+  *(uint16_t*)0x20000094 = 5;
+  *(uint16_t*)0x20000096 = 5;
+  *(uint8_t*)0x20000098 = 0;
+  *(uint64_t*)0x20000108 = 0x5c;
+  *(uint64_t*)0x20000158 = 1;
+  *(uint64_t*)0x20000160 = 0;
+  *(uint64_t*)0x20000168 = 0;
+  *(uint32_t*)0x20000170 = 0;
+  syscall(__NR_sendmsg, r[1], 0x20000140ul, 0ul);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  loop();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/107f9ebfce2c1a2ab0331b58ca2f8608b25436c2.c b/syzkaller-repros/linux/107f9ebfce2c1a2ab0331b58ca2f8608b25436c2.c
new file mode 100644
index 0000000..e5d4018
--- /dev/null
+++ b/syzkaller-repros/linux/107f9ebfce2c1a2ab0331b58ca2f8608b25436c2.c
@@ -0,0 +1,544 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+#include <linux/in6.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/veth.h>
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  memcpy((void*)0x20000300, "/dev/kvm\000", 9);
+  res = syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000300ul, 0ul, 0ul);
+  if (res != -1)
+    r[0] = res;
+  res = syscall(__NR_ioctl, r[0], 0xae01ul, 0ul);
+  if (res != -1)
+    r[1] = res;
+  syscall(__NR_ioctl, r[1], 0xae60ul, 0);
+  res = syscall(__NR_ioctl, r[1], 0xae41ul, 0x1000000000000102ul);
+  if (res != -1)
+    r[2] = res;
+  memcpy(
+      (void*)0x200004c0,
+      "\x6c\x64\x12\x5f\xa9\x6f\xa4\x2b\x76\x1c\x6e\xc2\x5b\x2b\xec\x0b\xa4\xc8"
+      "\x10\x36\xc9\x3a\x40\xc8\xa4\xd4\x41\x2a\x76\x3b\x00\x04\x00\x00\x00\x00"
+      "\x00\x00\x3c\x5c\xa2\x06\xc0\x47\xec\xee\x37\x7a\xba\xec\xe6\xb8\x83\x78"
+      "\xe3\xd6\x3a\x98\xfc\x19\x1f\x36\x1d\x26\x4f\xfa\x8b\x46\x48\x5f\x02\xba"
+      "\xee\x1a\xb6\xb8\x15\x42\x52\x06\x61\x78\x86\x8d\x1e\xf4\xa8\x36\x5c\x5d"
+      "\xc2\x6c\xa0\x97\xdd\xda\x7c\x21\xa9\x84\xc2\xb9\xca\x4b\xbb\x7a\x87\x16"
+      "\x5c\x0c\x1d\xbc\x75\xd7\xea\x4d\xf1\x00\x10\x17\x4a\x3a\xc8\x69\x45\x25"
+      "\x95\x2f\x44\x50\x0a\x1f\x0d\xb5\x09\xc3\x2c\xc7\xac\xe8\x42\xc2\x8f\x37"
+      "\xf0\x6e\x4e\xa9\xf1\xe5\xf0\xc6\xc3\x79\xf9\xcc\x58\xbf\x69\xfc\xde\x31"
+      "\x8e\xad\x48\x25\xaa\x1b\x6a\x83\x2d\x4e\x48\xcc\x41\xbb\x5a\x6b\xaa\x41"
+      "\xd6\x14\xf6\xc8\x94\x1b\xee\x80\x59\x54\xa6\x2d\x19\x6a\x07\x00\x00\x00"
+      "\xb2\x12\x24\xb5\x7f\x53\x0d\x00\x00\xc1\xff\x53\xbf\x79\xa1\xf5\xc5\xdc"
+      "\x34\xb2\x26\x2d\x66\xae\x79\x3b\x63\x04\xa3\x0b\x97\x07\x7f\x1c\x13\x10"
+      "\x45\xcb\xc1\x1c\x45\x62\xd2\x2d\xb8\x8d\x0e\xdc\x5d\xae\xe1\x71\xcc\x04"
+      "\xd9\x6d\x9e\xc2\xdb\x07\x47\x8f\x34\x7e\xdb\xd6\x40\x49\x23\xad\x4a\x56"
+      "\x72\xb1\xb2\x85\xc7\x98\x8c\x4e\xc0\x92\x2c\x65\x5f\xf6\x00\x00\x00\x00"
+      "\xc0\x0d\xc2\x90\xd9\x36\xd9\x32\x36\x05\x1f\xad\xfb\x4b\x95\xd0\x2c\x0b"
+      "\xda\x7c\xe3\x8d\xab\xb7\xcd\x10\x3f\xe4\xd0\xc9\xc9\x63\xcd\x71\x7a\x77"
+      "\xf8\xdf\x8d\x46\x09\x9b\x1f\x58\xe0\x68\xaf\x6a\xfb\xbc\x19\xdb\x16\x1c"
+      "\x6d\xf3\xe7\xc9\xc7\x1b\xc0\x8a\x28\x2f\xc2\xc1\x42\x85\x6b\x5e\x4c\xaf"
+      "\xf4\xc0\xa4\xf7\x24\x45\xef\x10\xdc\xd2\xc5\x69\x31\x9d\x6e\x9b\xb2\x05"
+      "\x8d\x02\x3f\x66\x9a\x64\xfc\x7d\x96\x84\xb4\x5b\x00\x00\x00\x00\x36\x46"
+      "\x73\xdc\xfa\x92\x35\xea\x5a\x2f\xf2\x3c\x4b\xb5\xc5\xac\xb2\x90\xe8\x97"
+      "\x6d\xca\xc7\x79\xff\x00\x27\xb4\x87\x34\x2b\x9e\x21\x26\x18\x5a\xfe\x28"
+      "\xa7\x74\xb9\x9d\x38\x90\xbd\x37\x42\x86\x17\xde\x4c\xdd\x6f\x53\xc4\x19"
+      "\xce\x31\x05\x41\x82\xfd\x09\x8a\xf7\xb7\xf1\xb1\x15\x2c\x69\x16\x11\xf8"
+      "\x97\x55\x8d\x4b\x75\x5c\xb7\x83\x97\x8d\x98\x59\xb0\x53\x7b\x05\xb6\x23"
+      "\xdc\xb5\xc4\xca\x93\x17\x47\x1a\x40\xfa\x49\x98\xcc\xa8\x0e\x96\x1e\xff"
+      "\xfb\x4e\x1a\xa2\x5d\x8a\x17\xde\xef\x0c\x86\x94\xc4\x39\x5f\xc9\x9b\xe3"
+      "\xc3\xfe\x7a\xeb\x8a\xf4\x92\x9c\xe7\xd3\x46\xca\x62\xb2\x5d\x48\xfd\xa5"
+      "\xd1\x01\x46\x70\x2f\x78\xb2\x33\xb5\x20\x87\x52\x72\x6e\xd9\xf0\xc3\x40"
+      "\xd4\x94\xb9\x2d\x19\xcc\x93\x0b\xb8\xa5\xf8\xb4\xda\x8f\x46\x03\xac\x0c"
+      "\x3b\x69\x83\x84\xe1\x7a\x57\x0d\xc8\x52\x48\x23\xed\x15\xaf\x4e\xcf\xab"
+      "\xb4\xb2\x54\x1d\x3c\x11\x4b\x7b\xba\x1c\x21\xa8\x45\xc9\xcf\x0d\x1c\xc2"
+      "\x4a\xba\x47\xe3\x0f\x55\x8b\x22\x46\xad\x95\xcc\xf7\xd2\xf8\x0c\xc0\xab"
+      "\x26\xf0\x83\x36\xea\x1a\x33\xb7\x9c\xf3\x5b\x89\x88\x37\x01\x6e\xb2\x11"
+      "\xa1\x73\x4c\x7a\xf0\x76\xe1\x54\x51\xe3\x35\x19\xfc\x97\x8f\x66\xdf\x7d"
+      "\xf4\x55\x7c\x91\x02\x4a\x8d\xc1\x30\xa2\x8e\xf5\xf6\x3a\xd0\x7b\x39\xc8"
+      "\xd2\x3b\x85\xcf\x43\x4e\x06\x5e\x8a\x29\xa8\x00\x47\xfe\x17\xde\xe6\xf6"
+      "\x34\x7b\x49\x51\xf9\x7b\x57\x03\xdc\x78\xb1\xca\x9d\x74\xea\x6a\x9a\xe1"
+      "\x2a\xb3\x67\xc0\xde\x26\x59\xcc\x38\xd2\xf3\x3d\xdd\x86\xe0\x59\x7d\x33"
+      "\x36\x1e\xad\xa1\x19\xb5\x13\x21\x45\xfa\x45\x25\xc4\x88\xc7\xff\xfd\x6c"
+      "\xed\xa6\xe9\xa0\x2e\xbd\x97\xce\xd6\xb0\x16\x1f\x2c\xc8\x46\x15\xce\xb8"
+      "\xb1\x88\x83\x29\x9c\x63\x6e\x9e\x46\x72\x4a\x9a\x06\x00\xa8\xbb\x02\xf3"
+      "\xe4\x89\x63\x1d\x52\x20\x19\xa3\x5f\xe1\x2a\x33\xca\xf9\xdd\x87\x68\xdd"
+      "\xbc\x02\xa4\x84\xc3\x45\xc3\xef\xf2\x54\x29\x7b\x1d\xbb\x04\x98\x9c\x3f"
+      "\x9f\x3c\x7b\x3c\x98\x5c\x39\xb1\xd3\x13\x01\x80\x68\xd3\x80\x9b\xac\x8c"
+      "\x65\x7e\x39\xf4\xf6\x92\x61\x3e\x28\x38\x7e\x95\x57\x22\x90\x8d\x4b\x8b"
+      "\x56\x16\x3b\xe8\x31\x2f\xf4\x7c\x5b\x6f\x28\x04\x72\x93\x5a\xf7\x4e\x97"
+      "\xa5\xa8\x11\x0a\x4d\x74\x49\x6f\x4c\x8e\x88\x2d\xdb\x56\xd9\xb9\x62\xd2"
+      "\xfc\x43\xfa\x01\xa0\x47\x52\x68\x65\xc8\x4f\x7c\xff\x36\x05\x6c\xc4\xac"
+      "\x25\x80\x21\xe1\x58\x1d\x43\xba\xda\xae\xc6\xcc\x5a\x2e\xf9\x89\xde\x98"
+      "\x01\xfe\xd6\xd4\xbe\x2b\xfc\xfe\x07\xa6\x9c\x46\xbf\xfb\xe9\xdd\x03\x97"
+      "\x08\x00\x00\x00\x00\x00\x00\x00\xd3\x72\xbd\xd6\xd8\x9d\xc1\xec\xf6\x3c"
+      "\x23\xd5\x06\x11\x4d\x0f\xba\x2b\xd1\xc6\x9e\x8f\x7e\x3f\xcc\xdc\xda\x85"
+      "\xce\x97\x5e\xc1\x38\x1b\x1c\xec\x6d\xda\xa7\x6e\x18\x67\x19\xd8\x19\x16"
+      "\x43\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+      1024);
+  syscall(__NR_ioctl, r[2], 0x4400ae8ful, 0x200004c0ul);
+  *(uint32_t*)0x200003c0 = 0;
+  *(uint32_t*)0x200003c4 = 0;
+  *(uint64_t*)0x200003c8 = 0x500;
+  *(uint32_t*)0x200003d0 = 0;
+  *(uint32_t*)0x200003d4 = 0;
+  *(uint32_t*)0x200003d8 = 0;
+  *(uint32_t*)0x200003dc = 0;
+  *(uint8_t*)0x200003e0 = 0;
+  *(uint8_t*)0x200003e1 = 0;
+  *(uint8_t*)0x200003e2 = 0;
+  *(uint8_t*)0x200003e3 = 0;
+  *(uint8_t*)0x200003e4 = 0;
+  *(uint8_t*)0x200003e5 = 0;
+  *(uint8_t*)0x200003e6 = 0;
+  *(uint8_t*)0x200003e7 = 0;
+  *(uint8_t*)0x200003e8 = 0;
+  *(uint8_t*)0x200003e9 = 0;
+  *(uint8_t*)0x200003ea = 0;
+  *(uint8_t*)0x200003eb = 0;
+  *(uint8_t*)0x200003ec = 0;
+  *(uint8_t*)0x200003ed = 0;
+  *(uint8_t*)0x200003ee = 0;
+  *(uint8_t*)0x200003ef = 0;
+  *(uint8_t*)0x200003f0 = 0;
+  *(uint8_t*)0x200003f1 = 0;
+  *(uint8_t*)0x200003f2 = 0;
+  *(uint8_t*)0x200003f3 = 0;
+  *(uint8_t*)0x200003f4 = 0;
+  *(uint8_t*)0x200003f5 = 0;
+  *(uint8_t*)0x200003f6 = 0;
+  *(uint8_t*)0x200003f7 = 0;
+  *(uint8_t*)0x200003f8 = 0;
+  *(uint8_t*)0x200003f9 = 0;
+  *(uint8_t*)0x200003fa = 0;
+  *(uint8_t*)0x200003fb = 0;
+  *(uint8_t*)0x200003fc = 0;
+  *(uint8_t*)0x200003fd = 0;
+  *(uint8_t*)0x200003fe = 0;
+  *(uint8_t*)0x200003ff = 0;
+  *(uint8_t*)0x20000400 = 0;
+  *(uint8_t*)0x20000401 = 0;
+  *(uint8_t*)0x20000402 = 0;
+  *(uint8_t*)0x20000403 = 0;
+  *(uint8_t*)0x20000404 = 0;
+  *(uint8_t*)0x20000405 = 0;
+  *(uint8_t*)0x20000406 = 0;
+  *(uint8_t*)0x20000407 = 0;
+  *(uint8_t*)0x20000408 = 0;
+  *(uint8_t*)0x20000409 = 0;
+  *(uint8_t*)0x2000040a = 0;
+  *(uint8_t*)0x2000040b = 0;
+  *(uint8_t*)0x2000040c = 0;
+  *(uint8_t*)0x2000040d = 0;
+  *(uint8_t*)0x2000040e = 0;
+  *(uint8_t*)0x2000040f = 0;
+  *(uint8_t*)0x20000410 = 0;
+  *(uint8_t*)0x20000411 = 0;
+  *(uint8_t*)0x20000412 = 0;
+  *(uint8_t*)0x20000413 = 0;
+  *(uint8_t*)0x20000414 = 0;
+  *(uint8_t*)0x20000415 = 0;
+  *(uint8_t*)0x20000416 = 0;
+  *(uint8_t*)0x20000417 = 0;
+  *(uint8_t*)0x20000418 = 0;
+  *(uint8_t*)0x20000419 = 0;
+  *(uint8_t*)0x2000041a = 0;
+  *(uint8_t*)0x2000041b = 0;
+  *(uint8_t*)0x2000041c = 0;
+  *(uint8_t*)0x2000041d = 0;
+  *(uint8_t*)0x2000041e = 0;
+  *(uint8_t*)0x2000041f = 0;
+  *(uint8_t*)0x20000420 = 0;
+  *(uint8_t*)0x20000421 = 0;
+  *(uint8_t*)0x20000422 = 0;
+  *(uint8_t*)0x20000423 = 0;
+  *(uint8_t*)0x20000424 = 0;
+  *(uint8_t*)0x20000425 = 0;
+  *(uint8_t*)0x20000426 = 0;
+  *(uint8_t*)0x20000427 = 0;
+  *(uint8_t*)0x20000428 = 0;
+  *(uint8_t*)0x20000429 = 0;
+  *(uint8_t*)0x2000042a = 0;
+  *(uint8_t*)0x2000042b = 0;
+  *(uint8_t*)0x2000042c = 0;
+  *(uint8_t*)0x2000042d = 0;
+  *(uint8_t*)0x2000042e = 0;
+  *(uint8_t*)0x2000042f = 0;
+  *(uint8_t*)0x20000430 = 0;
+  *(uint8_t*)0x20000431 = 0;
+  *(uint8_t*)0x20000432 = 0;
+  *(uint8_t*)0x20000433 = 0;
+  *(uint8_t*)0x20000434 = 0;
+  *(uint8_t*)0x20000435 = 0;
+  *(uint8_t*)0x20000436 = 0;
+  *(uint8_t*)0x20000437 = 0;
+  *(uint8_t*)0x20000438 = 0;
+  *(uint8_t*)0x20000439 = 0;
+  *(uint8_t*)0x2000043a = 0;
+  *(uint8_t*)0x2000043b = 0;
+  *(uint8_t*)0x2000043c = 0;
+  *(uint8_t*)0x2000043d = 0;
+  *(uint8_t*)0x2000043e = 0;
+  *(uint8_t*)0x2000043f = 0;
+  *(uint8_t*)0x20000440 = 0;
+  *(uint8_t*)0x20000441 = 0;
+  *(uint8_t*)0x20000442 = 0;
+  *(uint8_t*)0x20000443 = 0;
+  *(uint8_t*)0x20000444 = 0;
+  *(uint8_t*)0x20000445 = 0;
+  *(uint8_t*)0x20000446 = 0;
+  *(uint8_t*)0x20000447 = 0;
+  *(uint8_t*)0x20000448 = 0;
+  *(uint8_t*)0x20000449 = 0;
+  *(uint8_t*)0x2000044a = 0;
+  *(uint8_t*)0x2000044b = 0;
+  *(uint8_t*)0x2000044c = 0;
+  *(uint8_t*)0x2000044d = 0;
+  *(uint8_t*)0x2000044e = 0;
+  *(uint8_t*)0x2000044f = 0;
+  *(uint8_t*)0x20000450 = 0;
+  *(uint8_t*)0x20000451 = 0;
+  *(uint8_t*)0x20000452 = 0;
+  *(uint8_t*)0x20000453 = 0;
+  *(uint8_t*)0x20000454 = 0;
+  *(uint8_t*)0x20000455 = 0;
+  *(uint8_t*)0x20000456 = 0;
+  *(uint8_t*)0x20000457 = 0;
+  *(uint8_t*)0x20000458 = 0;
+  *(uint8_t*)0x20000459 = 0;
+  *(uint8_t*)0x2000045a = 0;
+  *(uint8_t*)0x2000045b = 0;
+  *(uint8_t*)0x2000045c = 0;
+  *(uint8_t*)0x2000045d = 0;
+  *(uint8_t*)0x2000045e = 0;
+  *(uint8_t*)0x2000045f = 0;
+  *(uint8_t*)0x20000460 = 0;
+  *(uint8_t*)0x20000461 = 0;
+  *(uint8_t*)0x20000462 = 0;
+  *(uint8_t*)0x20000463 = 0;
+  *(uint8_t*)0x20000464 = 0;
+  *(uint8_t*)0x20000465 = 0;
+  *(uint8_t*)0x20000466 = 0;
+  *(uint8_t*)0x20000467 = 0;
+  *(uint8_t*)0x20000468 = 0;
+  *(uint8_t*)0x20000469 = 0;
+  *(uint8_t*)0x2000046a = 0;
+  *(uint8_t*)0x2000046b = 0;
+  *(uint8_t*)0x2000046c = 0;
+  *(uint8_t*)0x2000046d = 0;
+  *(uint8_t*)0x2000046e = 0;
+  *(uint8_t*)0x2000046f = 0;
+  *(uint8_t*)0x20000470 = 0;
+  *(uint8_t*)0x20000471 = 0;
+  *(uint8_t*)0x20000472 = 0;
+  *(uint8_t*)0x20000473 = 0;
+  *(uint8_t*)0x20000474 = 0;
+  *(uint8_t*)0x20000475 = 0;
+  *(uint8_t*)0x20000476 = 0;
+  *(uint8_t*)0x20000477 = 0;
+  *(uint8_t*)0x20000478 = 0;
+  *(uint8_t*)0x20000479 = 0;
+  *(uint8_t*)0x2000047a = 0;
+  *(uint8_t*)0x2000047b = 0;
+  *(uint8_t*)0x2000047c = 0;
+  *(uint8_t*)0x2000047d = 0;
+  *(uint8_t*)0x2000047e = 0;
+  *(uint8_t*)0x2000047f = 0;
+  *(uint8_t*)0x20000480 = 0;
+  *(uint8_t*)0x20000481 = 0;
+  *(uint8_t*)0x20000482 = 0;
+  *(uint8_t*)0x20000483 = 0;
+  *(uint8_t*)0x20000484 = 0;
+  *(uint8_t*)0x20000485 = 0;
+  *(uint8_t*)0x20000486 = 0;
+  *(uint8_t*)0x20000487 = 0;
+  *(uint8_t*)0x20000488 = 0;
+  *(uint8_t*)0x20000489 = 0;
+  *(uint8_t*)0x2000048a = 0;
+  *(uint8_t*)0x2000048b = 0;
+  *(uint8_t*)0x2000048c = 0;
+  *(uint8_t*)0x2000048d = 0;
+  *(uint8_t*)0x2000048e = 0;
+  *(uint8_t*)0x2000048f = 0;
+  *(uint8_t*)0x20000490 = 0;
+  *(uint8_t*)0x20000491 = 0;
+  *(uint8_t*)0x20000492 = 0;
+  *(uint8_t*)0x20000493 = 0;
+  *(uint8_t*)0x20000494 = 0;
+  *(uint8_t*)0x20000495 = 0;
+  *(uint8_t*)0x20000496 = 0;
+  *(uint8_t*)0x20000497 = 0;
+  *(uint8_t*)0x20000498 = 0;
+  *(uint8_t*)0x20000499 = 0;
+  *(uint8_t*)0x2000049a = 0;
+  *(uint8_t*)0x2000049b = 0;
+  *(uint8_t*)0x2000049c = 0;
+  *(uint8_t*)0x2000049d = 0;
+  *(uint8_t*)0x2000049e = 0;
+  *(uint8_t*)0x2000049f = 0;
+  syscall(__NR_ioctl, r[1], 0x4020aea5ul, 0x200003c0ul);
+  syscall(__NR_ioctl, r[2], 0x8004ae98ul, 0ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/10857c3f8515a6269522e043228547504abd6455.c b/syzkaller-repros/linux/10857c3f8515a6269522e043228547504abd6455.c
new file mode 100644
index 0000000..ecba1e9
--- /dev/null
+++ b/syzkaller-repros/linux/10857c3f8515a6269522e043228547504abd6455.c
@@ -0,0 +1,341 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <endian.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+#include <linux/in6.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/veth.h>
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+static long syz_open_dev(volatile long a0, volatile long a1, volatile long a2)
+{
+  if (a0 == 0xc || a0 == 0xb) {
+    char buf[128];
+    sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block", (uint8_t)a1,
+            (uint8_t)a2);
+    return open(buf, O_RDWR, 0);
+  } else {
+    char buf[1024];
+    char* hash;
+    strncpy(buf, (char*)a0, sizeof(buf) - 1);
+    buf[sizeof(buf) - 1] = 0;
+    while ((hash = strchr(buf, '#'))) {
+      *hash = '0' + (char)(a1 % 10);
+      a1 /= 10;
+    }
+    return open(buf, a2, 0);
+  }
+}
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  intptr_t res = 0;
+  memcpy((void*)0x20000000, "/dev/fb0\000", 9);
+  res = syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000000ul, 0ul, 0ul);
+  if (res != -1)
+    r[0] = res;
+  *(uint32_t*)0x20000040 = 0;
+  *(uint32_t*)0x20000044 = 0x300;
+  *(uint32_t*)0x20000048 = 0;
+  *(uint32_t*)0x2000004c = 0;
+  *(uint32_t*)0x20000050 = -1;
+  *(uint32_t*)0x20000054 = 0;
+  *(uint32_t*)0x20000058 = 0x20;
+  *(uint32_t*)0x2000005c = 0;
+  *(uint32_t*)0x20000060 = 0;
+  *(uint32_t*)0x20000064 = 0;
+  *(uint32_t*)0x20000068 = 0;
+  *(uint32_t*)0x2000006c = 0;
+  *(uint32_t*)0x20000070 = 0;
+  *(uint32_t*)0x20000074 = 0;
+  *(uint32_t*)0x20000078 = 0;
+  *(uint32_t*)0x2000007c = 0;
+  *(uint32_t*)0x20000080 = 0;
+  *(uint32_t*)0x20000084 = 0;
+  *(uint32_t*)0x20000088 = 0;
+  *(uint32_t*)0x2000008c = 0;
+  *(uint32_t*)0x20000090 = 0;
+  *(uint32_t*)0x20000094 = 0;
+  *(uint32_t*)0x20000098 = 0;
+  *(uint32_t*)0x2000009c = 0;
+  *(uint32_t*)0x200000a0 = 0;
+  *(uint32_t*)0x200000a4 = 0;
+  *(uint32_t*)0x200000a8 = 0;
+  *(uint32_t*)0x200000ac = 0;
+  *(uint32_t*)0x200000b0 = 0;
+  *(uint32_t*)0x200000b4 = 0;
+  *(uint32_t*)0x200000b8 = 0;
+  *(uint32_t*)0x200000bc = 0;
+  *(uint32_t*)0x200000c0 = 0;
+  *(uint32_t*)0x200000c4 = 0;
+  *(uint32_t*)0x200000c8 = 0;
+  *(uint32_t*)0x200000cc = 0;
+  *(uint32_t*)0x200000d0 = 0;
+  *(uint32_t*)0x200000d4 = 0;
+  *(uint32_t*)0x200000d8 = 0;
+  *(uint32_t*)0x200000dc = 0;
+  syscall(__NR_ioctl, r[0], 0x4601ul, 0x20000040ul);
+  res = syz_open_dev(0xc, 4, 1);
+  if (res != -1)
+    r[1] = res;
+  syscall(__NR_ioctl, r[1], 0x5606ul, 9ul);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/10885c48e038cebd26bcf4ae0c0daa0c6b0607a9.c b/syzkaller-repros/linux/10885c48e038cebd26bcf4ae0c0daa0c6b0607a9.c
new file mode 100644
index 0000000..6a96b5c
--- /dev/null
+++ b/syzkaller-repros/linux/10885c48e038cebd26bcf4ae0c0daa0c6b0607a9.c
@@ -0,0 +1,711 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <sched.h>
+#include <signal.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/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 <time.h>
+#include <unistd.h>
+
+#include <linux/capability.h>
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/if_tun.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/tcp.h>
+#include <linux/veth.h>
+
+unsigned long long procid;
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
+                            const void* addr, int addrsize)
+{
+  struct ifaddrmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
+  hdr.ifa_scope = RT_SCOPE_UNIVERSE;
+  hdr.ifa_index = if_nametoindex(dev);
+  netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
+  netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
+  return netlink_send(nlmsg, sock);
+}
+
+static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in_addr in_addr;
+  inet_pton(AF_INET, addr, &in_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
+  (void)err;
+}
+
+static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, addr, &in6_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
+  (void)err;
+}
+
+static void netlink_add_neigh(struct nlmsg* nlmsg, int sock, const char* name,
+                              const void* addr, int addrsize, const void* mac,
+                              int macsize)
+{
+  struct ndmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ndm_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ndm_ifindex = if_nametoindex(name);
+  hdr.ndm_state = NUD_PERMANENT;
+  netlink_init(nlmsg, RTM_NEWNEIGH, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, NDA_DST, addr, addrsize);
+  netlink_attr(nlmsg, NDA_LLADDR, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int tunfd = -1;
+static int tun_frags_enabled;
+
+#define TUN_IFACE "syz_tun"
+
+#define LOCAL_MAC 0xaaaaaaaaaaaa
+#define REMOTE_MAC 0xaaaaaaaaaabb
+
+#define LOCAL_IPV4 "172.20.20.170"
+#define REMOTE_IPV4 "172.20.20.187"
+
+#define LOCAL_IPV6 "fe80::aa"
+#define REMOTE_IPV6 "fe80::bb"
+
+#define IFF_NAPI 0x0010
+#define IFF_NAPI_FRAGS 0x0020
+
+static void initialize_tun(void)
+{
+  tunfd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
+  if (tunfd == -1) {
+    printf("tun: can't open /dev/net/tun: please enable CONFIG_TUN=y\n");
+    printf("otherwise fuzzing or reproducing might not work as intended\n");
+    return;
+  }
+  const int kTunFd = 240;
+  if (dup2(tunfd, kTunFd) < 0)
+    exit(1);
+  close(tunfd);
+  tunfd = kTunFd;
+  struct ifreq ifr;
+  memset(&ifr, 0, sizeof(ifr));
+  strncpy(ifr.ifr_name, TUN_IFACE, IFNAMSIZ);
+  ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_NAPI | IFF_NAPI_FRAGS;
+  if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) {
+    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+    if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0)
+      exit(1);
+  }
+  if (ioctl(tunfd, TUNGETIFF, (void*)&ifr) < 0)
+    exit(1);
+  tun_frags_enabled = (ifr.ifr_flags & IFF_NAPI_FRAGS) != 0;
+  char sysctl[64];
+  sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/accept_dad", TUN_IFACE);
+  write_file(sysctl, "0");
+  sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/router_solicitations", TUN_IFACE);
+  write_file(sysctl, "0");
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  netlink_add_addr4(&nlmsg, sock, TUN_IFACE, LOCAL_IPV4);
+  netlink_add_addr6(&nlmsg, sock, TUN_IFACE, LOCAL_IPV6);
+  uint64_t macaddr = REMOTE_MAC;
+  struct in_addr in_addr;
+  inet_pton(AF_INET, REMOTE_IPV4, &in_addr);
+  netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in_addr, sizeof(in_addr),
+                    &macaddr, ETH_ALEN);
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, REMOTE_IPV6, &in6_addr);
+  netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in6_addr, sizeof(in6_addr),
+                    &macaddr, ETH_ALEN);
+  macaddr = LOCAL_MAC;
+  netlink_device_change(&nlmsg, sock, TUN_IFACE, true, 0, &macaddr, ETH_ALEN,
+                        NULL);
+  close(sock);
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+static int read_tun(char* data, int size)
+{
+  if (tunfd < 0)
+    return -1;
+  int rv = read(tunfd, data, size);
+  if (rv < 0) {
+    if (errno == EAGAIN)
+      return -1;
+    if (errno == EBADFD)
+      return -1;
+    exit(1);
+  }
+  return rv;
+}
+
+static void flush_tun()
+{
+  char data[1000];
+  while (read_tun(&data[0], sizeof(data)) != -1) {
+  }
+}
+
+#define MAX_FDS 30
+
+static void setup_common()
+{
+  if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
+  }
+}
+
+static void loop();
+
+static void sandbox_common()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setsid();
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  if (dup2(netns, kInitNetNsFd) < 0)
+    exit(1);
+  close(netns);
+  struct rlimit rlim;
+  rlim.rlim_cur = rlim.rlim_max = (200 << 20);
+  setrlimit(RLIMIT_AS, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 32 << 20;
+  setrlimit(RLIMIT_MEMLOCK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 136 << 20;
+  setrlimit(RLIMIT_FSIZE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+  setrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 0;
+  setrlimit(RLIMIT_CORE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 256;
+  setrlimit(RLIMIT_NOFILE, &rlim);
+  if (unshare(CLONE_NEWNS)) {
+  }
+  if (unshare(CLONE_NEWIPC)) {
+  }
+  if (unshare(0x02000000)) {
+  }
+  if (unshare(CLONE_NEWUTS)) {
+  }
+  if (unshare(CLONE_SYSVSEM)) {
+  }
+  typedef struct {
+    const char* name;
+    const char* value;
+  } sysctl_t;
+  static const sysctl_t sysctls[] = {
+      {"/proc/sys/kernel/shmmax", "16777216"},
+      {"/proc/sys/kernel/shmall", "536870912"},
+      {"/proc/sys/kernel/shmmni", "1024"},
+      {"/proc/sys/kernel/msgmax", "8192"},
+      {"/proc/sys/kernel/msgmni", "1024"},
+      {"/proc/sys/kernel/msgmnb", "1024"},
+      {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
+    write_file(sysctls[i].name, sysctls[i].value);
+}
+
+int wait_for_loop(int pid)
+{
+  if (pid < 0)
+    exit(1);
+  int status = 0;
+  while (waitpid(-1, &status, __WALL) != pid) {
+  }
+  return WEXITSTATUS(status);
+}
+
+static void drop_caps(void)
+{
+  struct __user_cap_header_struct cap_hdr = {};
+  struct __user_cap_data_struct cap_data[2] = {};
+  cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
+  cap_hdr.pid = getpid();
+  if (syscall(SYS_capget, &cap_hdr, &cap_data))
+    exit(1);
+  const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
+  cap_data[0].effective &= ~drop;
+  cap_data[0].permitted &= ~drop;
+  cap_data[0].inheritable &= ~drop;
+  if (syscall(SYS_capset, &cap_hdr, &cap_data))
+    exit(1);
+}
+
+static int do_sandbox_none(void)
+{
+  if (unshare(CLONE_NEWPID)) {
+  }
+  int pid = fork();
+  if (pid != 0)
+    return wait_for_loop(pid);
+  setup_common();
+  sandbox_common();
+  drop_caps();
+  if (unshare(CLONE_NEWNET)) {
+  }
+  initialize_devlink_pci();
+  initialize_tun();
+  loop();
+  exit(1);
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+  flush_tun();
+}
+
+static void close_fds()
+{
+  int fd;
+  for (fd = 3; fd < MAX_FDS; fd++)
+    close(fd);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  int iter;
+  for (iter = 0;; iter++) {
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      setup_test();
+      execute_one();
+      close_fds();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+  }
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void execute_one(void)
+{
+  intptr_t res = 0;
+  memcpy((void*)0x20000000, "/dev/fb0\000", 9);
+  res = syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000000ul, 0ul, 0ul);
+  if (res != -1)
+    r[0] = res;
+  syscall(__NR_ioctl, -1, 0x81009431ul, 0ul);
+  *(uint32_t*)0x20000040 = 0;
+  *(uint32_t*)0x20000044 = 0;
+  *(uint32_t*)0x20000048 = 0;
+  *(uint32_t*)0x2000004c = 0;
+  *(uint32_t*)0x20000050 = 0;
+  *(uint32_t*)0x20000054 = 0;
+  *(uint32_t*)0x20000058 = 0x20;
+  *(uint32_t*)0x2000005c = 0;
+  *(uint32_t*)0x20000060 = 0;
+  *(uint32_t*)0x20000064 = 0;
+  *(uint32_t*)0x20000068 = 0;
+  *(uint32_t*)0x2000006c = 0;
+  *(uint32_t*)0x20000070 = 0;
+  *(uint32_t*)0x20000074 = 0;
+  *(uint32_t*)0x20000078 = 0;
+  *(uint32_t*)0x2000007c = 0;
+  *(uint32_t*)0x20000080 = 0;
+  *(uint32_t*)0x20000084 = 0;
+  *(uint32_t*)0x20000088 = 0;
+  *(uint32_t*)0x2000008c = 0;
+  *(uint32_t*)0x20000090 = 0;
+  *(uint32_t*)0x20000094 = 0;
+  *(uint32_t*)0x20000098 = 0;
+  *(uint32_t*)0x2000009c = 0;
+  *(uint32_t*)0x200000a0 = 0;
+  *(uint32_t*)0x200000a4 = 0;
+  *(uint32_t*)0x200000a8 = 0;
+  *(uint32_t*)0x200000ac = 0;
+  *(uint32_t*)0x200000b0 = 0;
+  *(uint32_t*)0x200000b4 = 0;
+  *(uint32_t*)0x200000b8 = 0;
+  *(uint32_t*)0x200000bc = 0;
+  *(uint32_t*)0x200000c0 = 0;
+  *(uint32_t*)0x200000c4 = 0x200;
+  *(uint32_t*)0x200000c8 = 0;
+  *(uint32_t*)0x200000cc = 7;
+  *(uint32_t*)0x200000d0 = 0;
+  *(uint32_t*)0x200000d4 = 0;
+  *(uint32_t*)0x200000d8 = 0;
+  *(uint32_t*)0x200000dc = 0;
+  syscall(__NR_ioctl, r[0], 0x4601ul, 0x20000040ul);
+  syscall(__NR_ioctl, -1, 0x4b67ul, 0ul);
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  for (procid = 0; procid < 8; procid++) {
+    if (fork() == 0) {
+      do_sandbox_none();
+    }
+  }
+  sleep(1000000);
+  return 0;
+}
diff --git a/syzkaller-repros/linux/1252759d5b2a86c155d9c9d806902955d4edddca.c b/syzkaller-repros/linux/1252759d5b2a86c155d9c9d806902955d4edddca.c
new file mode 100644
index 0000000..c37c25c
--- /dev/null
+++ b/syzkaller-repros/linux/1252759d5b2a86c155d9c9d806902955d4edddca.c
@@ -0,0 +1,2024 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <sched.h>
+#include <setjmp.h>
+#include <signal.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/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/uio.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/capability.h>
+#include <linux/futex.h>
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/if_tun.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/tcp.h>
+#include <linux/veth.h>
+
+unsigned long long procid;
+
+static __thread int skip_segv;
+static __thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* ctx)
+{
+  uintptr_t addr = (uintptr_t)info->si_addr;
+  const uintptr_t prog_start = 1 << 20;
+  const uintptr_t prog_end = 100 << 20;
+  if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) &&
+      (addr < prog_start || addr > prog_end)) {
+    _longjmp(segv_env, 1);
+  }
+  exit(sig);
+}
+
+static void install_segv_handler(void)
+{
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = SIG_IGN;
+  syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
+  syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_sigaction = segv_handler;
+  sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+  sigaction(SIGSEGV, &sa, NULL);
+  sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...)                                                        \
+  {                                                                            \
+    __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
+    if (_setjmp(segv_env) == 0) {                                              \
+      __VA_ARGS__;                                                             \
+    }                                                                          \
+    __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
+  }
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void use_temporary_dir(void)
+{
+  char tmpdir_template[] = "./syzkaller.XXXXXX";
+  char* tmpdir = mkdtemp(tmpdir_template);
+  if (!tmpdir)
+    exit(1);
+  if (chmod(tmpdir, 0777))
+    exit(1);
+  if (chdir(tmpdir))
+    exit(1);
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+  pthread_t th;
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setstacksize(&attr, 128 << 10);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (pthread_create(&th, &attr, fn, arg) == 0) {
+      pthread_attr_destroy(&attr);
+      return;
+    }
+    if (errno == EAGAIN) {
+      usleep(50);
+      continue;
+    }
+    break;
+  }
+  exit(1);
+}
+
+typedef struct {
+  int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+  ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+  if (ev->state)
+    exit(1);
+  __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
+  syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1000000);
+}
+
+static void event_wait(event_t* ev)
+{
+  while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
+}
+
+static int event_isset(event_t* ev)
+{
+  return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+  uint64_t start = current_time_ms();
+  uint64_t now = start;
+  for (;;) {
+    uint64_t remain = timeout - (now - start);
+    struct timespec ts;
+    ts.tv_sec = remain / 1000;
+    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+    syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
+    if (__atomic_load_n(&ev->state, __ATOMIC_RELAXED))
+      return 1;
+    now = current_time_ms();
+    if (now - start > timeout)
+      return 0;
+  }
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static void netlink_nest(struct nlmsg* nlmsg, int typ)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_type = typ;
+  nlmsg->pos += sizeof(*attr);
+  nlmsg->nested[nlmsg->nesting++] = attr;
+}
+
+static void netlink_done(struct nlmsg* nlmsg)
+{
+  struct nlattr* attr = nlmsg->nested[--nlmsg->nesting];
+  attr->nla_len = nlmsg->pos - (char*)attr;
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)
+{
+  return netlink_send_ext(nlmsg, sock, 0, NULL);
+}
+
+static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset,
+                            unsigned int total_len)
+{
+  struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset);
+  if (offset == total_len || offset + hdr->nlmsg_len > total_len)
+    return -1;
+  return hdr->nlmsg_len;
+}
+
+static void netlink_add_device_impl(struct nlmsg* nlmsg, const char* type,
+                                    const char* name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr,
+               sizeof(hdr));
+  if (name)
+    netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name));
+  netlink_nest(nlmsg, IFLA_LINKINFO);
+  netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type));
+}
+
+static void netlink_add_device(struct nlmsg* nlmsg, int sock, const char* type,
+                               const char* name)
+{
+  netlink_add_device_impl(nlmsg, type, name);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_veth(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* peer)
+{
+  netlink_add_device_impl(nlmsg, "veth", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_nest(nlmsg, VETH_INFO_PEER);
+  nlmsg->pos += sizeof(struct ifinfomsg);
+  netlink_attr(nlmsg, IFLA_IFNAME, peer, strlen(peer));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_hsr(struct nlmsg* nlmsg, int sock, const char* name,
+                            const char* slave1, const char* slave2)
+{
+  netlink_add_device_impl(nlmsg, "hsr", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  int ifindex1 = if_nametoindex(slave1);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE1, &ifindex1, sizeof(ifindex1));
+  int ifindex2 = if_nametoindex(slave2);
+  netlink_attr(nlmsg, IFLA_HSR_SLAVE2, &ifindex2, sizeof(ifindex2));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_linked(struct nlmsg* nlmsg, int sock, const char* type,
+                               const char* name, const char* link)
+{
+  netlink_add_device_impl(nlmsg, type, name);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_vlan(struct nlmsg* nlmsg, int sock, const char* name,
+                             const char* link, uint16_t id, uint16_t proto)
+{
+  netlink_add_device_impl(nlmsg, "vlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_VLAN_ID, &id, sizeof(id));
+  netlink_attr(nlmsg, IFLA_VLAN_PROTOCOL, &proto, sizeof(proto));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_macvlan(struct nlmsg* nlmsg, int sock, const char* name,
+                                const char* link)
+{
+  netlink_add_device_impl(nlmsg, "macvlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  uint32_t mode = MACVLAN_MODE_BRIDGE;
+  netlink_attr(nlmsg, IFLA_MACVLAN_MODE, &mode, sizeof(mode));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_add_geneve(struct nlmsg* nlmsg, int sock, const char* name,
+                               uint32_t vni, struct in_addr* addr4,
+                               struct in6_addr* addr6)
+{
+  netlink_add_device_impl(nlmsg, "geneve", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_GENEVE_ID, &vni, sizeof(vni));
+  if (addr4)
+    netlink_attr(nlmsg, IFLA_GENEVE_REMOTE, addr4, sizeof(*addr4));
+  if (addr6)
+    netlink_attr(nlmsg, IFLA_GENEVE_REMOTE6, addr6, sizeof(*addr6));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+#define IFLA_IPVLAN_FLAGS 2
+#define IPVLAN_MODE_L3S 2
+#undef IPVLAN_F_VEPA
+#define IPVLAN_F_VEPA 2
+
+static void netlink_add_ipvlan(struct nlmsg* nlmsg, int sock, const char* name,
+                               const char* link, uint16_t mode, uint16_t flags)
+{
+  netlink_add_device_impl(nlmsg, "ipvlan", name);
+  netlink_nest(nlmsg, IFLA_INFO_DATA);
+  netlink_attr(nlmsg, IFLA_IPVLAN_MODE, &mode, sizeof(mode));
+  netlink_attr(nlmsg, IFLA_IPVLAN_FLAGS, &flags, sizeof(flags));
+  netlink_done(nlmsg);
+  netlink_done(nlmsg);
+  int ifindex = if_nametoindex(link);
+  netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static void netlink_device_change(struct nlmsg* nlmsg, int sock,
+                                  const char* name, bool up, const char* master,
+                                  const void* mac, int macsize,
+                                  const char* new_name)
+{
+  struct ifinfomsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  if (up)
+    hdr.ifi_flags = hdr.ifi_change = IFF_UP;
+  hdr.ifi_index = if_nametoindex(name);
+  netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
+  if (new_name)
+    netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
+  if (master) {
+    int ifindex = if_nametoindex(master);
+    netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
+  }
+  if (macsize)
+    netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
+  int err = netlink_send(nlmsg, sock);
+  (void)err;
+}
+
+static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev,
+                            const void* addr, int addrsize)
+{
+  struct ifaddrmsg hdr;
+  memset(&hdr, 0, sizeof(hdr));
+  hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6;
+  hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120;
+  hdr.ifa_scope = RT_SCOPE_UNIVERSE;
+  hdr.ifa_index = if_nametoindex(dev);
+  netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr,
+               sizeof(hdr));
+  netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize);
+  netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize);
+  return netlink_send(nlmsg, sock);
+}
+
+static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in_addr in_addr;
+  inet_pton(AF_INET, addr, &in_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr));
+  (void)err;
+}
+
+static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev,
+                              const char* addr)
+{
+  struct in6_addr in6_addr;
+  inet_pton(AF_INET6, addr, &in6_addr);
+  int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr));
+  (void)err;
+}
+
+const int kInitNetNsFd = 239;
+
+#define DEVLINK_FAMILY_NAME "devlink"
+
+#define DEVLINK_CMD_PORT_GET 5
+#define DEVLINK_CMD_RELOAD 37
+#define DEVLINK_ATTR_BUS_NAME 1
+#define DEVLINK_ATTR_DEV_NAME 2
+#define DEVLINK_ATTR_NETDEV_NAME 7
+#define DEVLINK_ATTR_NETNS_FD 138
+
+static int netlink_devlink_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME,
+               strlen(DEVLINK_FAMILY_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_devlink_netns_move(const char* bus_name,
+                                       const char* dev_name, int netns_fd)
+{
+  struct genlmsghdr genlhdr;
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_RELOAD;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd));
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+error:
+  close(sock);
+}
+
+static struct nlmsg nlmsg2;
+
+static void initialize_devlink_ports(const char* bus_name, const char* dev_name,
+                                     const char* netdev_prefix)
+{
+  struct genlmsghdr genlhdr;
+  int len, total_len, id, err, offset;
+  uint16_t netdev_index;
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (rtsock == -1)
+    exit(1);
+  id = netlink_devlink_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = DEVLINK_CMD_PORT_GET;
+  netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1);
+  netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1);
+  err = netlink_send_ext(&nlmsg, sock, id, &total_len);
+  if (err) {
+    goto error;
+  }
+  offset = 0;
+  netdev_index = 0;
+  while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) {
+    struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN +
+                                           NLMSG_ALIGN(sizeof(genlhdr)));
+    for (; (char*)attr < nlmsg.buf + offset + len;
+         attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+      if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) {
+        char* port_name;
+        char netdev_name[IFNAMSIZ];
+        port_name = (char*)(attr + 1);
+        snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix,
+                 netdev_index);
+        netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0,
+                              netdev_name);
+        break;
+      }
+    }
+    offset += len;
+    netdev_index++;
+  }
+error:
+  close(rtsock);
+  close(sock);
+}
+
+static void initialize_devlink_pci(void)
+{
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  int ret = setns(kInitNetNsFd, 0);
+  if (ret == -1)
+    exit(1);
+  netlink_devlink_netns_move("pci", "0000:00:10.0", netns);
+  ret = setns(netns, 0);
+  if (ret == -1)
+    exit(1);
+  close(netns);
+  initialize_devlink_ports("pci", "0000:00:10.0", "netpci");
+}
+
+#define DEV_IPV4 "172.20.20.%d"
+#define DEV_IPV6 "fe80::%02x"
+#define DEV_MAC 0x00aaaaaaaaaa
+
+static void netdevsim_add(unsigned int addr, unsigned int port_count)
+{
+  char buf[16];
+  sprintf(buf, "%u %u", addr, port_count);
+  if (write_file("/sys/bus/netdevsim/new_device", buf)) {
+    snprintf(buf, sizeof(buf), "netdevsim%d", addr);
+    initialize_devlink_ports("netdevsim", buf, "netdevsim");
+  }
+}
+
+#define WG_GENL_NAME "wireguard"
+enum wg_cmd {
+  WG_CMD_GET_DEVICE,
+  WG_CMD_SET_DEVICE,
+};
+enum wgdevice_attribute {
+  WGDEVICE_A_UNSPEC,
+  WGDEVICE_A_IFINDEX,
+  WGDEVICE_A_IFNAME,
+  WGDEVICE_A_PRIVATE_KEY,
+  WGDEVICE_A_PUBLIC_KEY,
+  WGDEVICE_A_FLAGS,
+  WGDEVICE_A_LISTEN_PORT,
+  WGDEVICE_A_FWMARK,
+  WGDEVICE_A_PEERS,
+};
+enum wgpeer_attribute {
+  WGPEER_A_UNSPEC,
+  WGPEER_A_PUBLIC_KEY,
+  WGPEER_A_PRESHARED_KEY,
+  WGPEER_A_FLAGS,
+  WGPEER_A_ENDPOINT,
+  WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+  WGPEER_A_LAST_HANDSHAKE_TIME,
+  WGPEER_A_RX_BYTES,
+  WGPEER_A_TX_BYTES,
+  WGPEER_A_ALLOWEDIPS,
+  WGPEER_A_PROTOCOL_VERSION,
+};
+enum wgallowedip_attribute {
+  WGALLOWEDIP_A_UNSPEC,
+  WGALLOWEDIP_A_FAMILY,
+  WGALLOWEDIP_A_IPADDR,
+  WGALLOWEDIP_A_CIDR_MASK,
+};
+
+static int netlink_wireguard_id_get(struct nlmsg* nlmsg, int sock)
+{
+  struct genlmsghdr genlhdr;
+  struct nlattr* attr;
+  int err, n;
+  uint16_t id = 0;
+  memset(&genlhdr, 0, sizeof(genlhdr));
+  genlhdr.cmd = CTRL_CMD_GETFAMILY;
+  netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, WG_GENL_NAME,
+               strlen(WG_GENL_NAME) + 1);
+  err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n);
+  if (err) {
+    return -1;
+  }
+  attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN +
+                          NLMSG_ALIGN(sizeof(genlhdr)));
+  for (; (char*)attr < nlmsg->buf + n;
+       attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+    if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
+      id = *(uint16_t*)(attr + 1);
+      break;
+    }
+  }
+  if (!id) {
+    return -1;
+  }
+  recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0); /* recv ack */
+  return id;
+}
+
+static void netlink_wireguard_setup(void)
+{
+  const char ifname_a[] = "wg0";
+  const char ifname_b[] = "wg1";
+  const char ifname_c[] = "wg2";
+  const char private_a[] =
+      "\xa0\x5c\xa8\x4f\x6c\x9c\x8e\x38\x53\xe2\xfd\x7a\x70\xae\x0f\xb2\x0f\xa1"
+      "\x52\x60\x0c\xb0\x08\x45\x17\x4f\x08\x07\x6f\x8d\x78\x43";
+  const char private_b[] =
+      "\xb0\x80\x73\xe8\xd4\x4e\x91\xe3\xda\x92\x2c\x22\x43\x82\x44\xbb\x88\x5c"
+      "\x69\xe2\x69\xc8\xe9\xd8\x35\xb1\x14\x29\x3a\x4d\xdc\x6e";
+  const char private_c[] =
+      "\xa0\xcb\x87\x9a\x47\xf5\xbc\x64\x4c\x0e\x69\x3f\xa6\xd0\x31\xc7\x4a\x15"
+      "\x53\xb6\xe9\x01\xb9\xff\x2f\x51\x8c\x78\x04\x2f\xb5\x42";
+  const char public_a[] =
+      "\x97\x5c\x9d\x81\xc9\x83\xc8\x20\x9e\xe7\x81\x25\x4b\x89\x9f\x8e\xd9\x25"
+      "\xae\x9f\x09\x23\xc2\x3c\x62\xf5\x3c\x57\xcd\xbf\x69\x1c";
+  const char public_b[] =
+      "\xd1\x73\x28\x99\xf6\x11\xcd\x89\x94\x03\x4d\x7f\x41\x3d\xc9\x57\x63\x0e"
+      "\x54\x93\xc2\x85\xac\xa4\x00\x65\xcb\x63\x11\xbe\x69\x6b";
+  const char public_c[] =
+      "\xf4\x4d\xa3\x67\xa8\x8e\xe6\x56\x4f\x02\x02\x11\x45\x67\x27\x08\x2f\x5c"
+      "\xeb\xee\x8b\x1b\xf5\xeb\x73\x37\x34\x1b\x45\x9b\x39\x22";
+  const uint16_t listen_a = 20001;
+  const uint16_t listen_b = 20002;
+  const uint16_t listen_c = 20003;
+  const uint16_t af_inet = AF_INET;
+  const uint16_t af_inet6 = AF_INET6;
+  /* Unused, but useful in case we change this:
+  const struct sockaddr_in endpoint_a_v4 = {
+      .sin_family = AF_INET,
+      .sin_port = htons(listen_a),
+      .sin_addr = {htonl(INADDR_LOOPBACK)}};*/
+  const struct sockaddr_in endpoint_b_v4 = {
+      .sin_family = AF_INET,
+      .sin_port = htons(listen_b),
+      .sin_addr = {htonl(INADDR_LOOPBACK)}};
+  const struct sockaddr_in endpoint_c_v4 = {
+      .sin_family = AF_INET,
+      .sin_port = htons(listen_c),
+      .sin_addr = {htonl(INADDR_LOOPBACK)}};
+  struct sockaddr_in6 endpoint_a_v6 = {.sin6_family = AF_INET6,
+                                       .sin6_port = htons(listen_a)};
+  endpoint_a_v6.sin6_addr = in6addr_loopback;
+  /* Unused, but useful in case we change this:
+  const struct sockaddr_in6 endpoint_b_v6 = {
+      .sin6_family = AF_INET6,
+      .sin6_port = htons(listen_b)};
+  endpoint_b_v6.sin6_addr = in6addr_loopback; */
+  struct sockaddr_in6 endpoint_c_v6 = {.sin6_family = AF_INET6,
+                                       .sin6_port = htons(listen_c)};
+  endpoint_c_v6.sin6_addr = in6addr_loopback;
+  const struct in_addr first_half_v4 = {0};
+  const struct in_addr second_half_v4 = {htonl(128 << 24)};
+  const struct in6_addr first_half_v6 = {{{0}}};
+  const struct in6_addr second_half_v6 = {{{0x80}}};
+  const uint8_t half_cidr = 1;
+  const uint16_t persistent_keepalives[] = {1, 3, 7, 9, 14, 19};
+  struct genlmsghdr genlhdr = {.cmd = WG_CMD_SET_DEVICE, .version = 1};
+  int sock;
+  int id, err;
+  sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+  if (sock == -1)
+    exit(1);
+  id = netlink_wireguard_id_get(&nlmsg, sock);
+  if (id == -1)
+    goto error;
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_a, strlen(ifname_a) + 1);
+  netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_a, 32);
+  netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_a, 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_b, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_b_v4,
+               sizeof(endpoint_b_v4));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[0], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
+               sizeof(first_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
+               sizeof(first_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_c, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_c_v6,
+               sizeof(endpoint_c_v6));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[1], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
+               sizeof(second_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
+               sizeof(second_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_b, strlen(ifname_b) + 1);
+  netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_b, 32);
+  netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_b, 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_a, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_a_v6,
+               sizeof(endpoint_a_v6));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[2], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
+               sizeof(first_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
+               sizeof(first_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_c, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_c_v4,
+               sizeof(endpoint_c_v4));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[3], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
+               sizeof(second_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
+               sizeof(second_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+  netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr));
+  netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_c, strlen(ifname_c) + 1);
+  netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_c, 32);
+  netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_c, 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_a, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_a_v6,
+               sizeof(endpoint_a_v6));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[4], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4,
+               sizeof(first_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6,
+               sizeof(first_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_b, 32);
+  netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_b_v4,
+               sizeof(endpoint_b_v4));
+  netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+               &persistent_keepalives[5], 2);
+  netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4,
+               sizeof(second_half_v4));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_nest(&nlmsg, NLA_F_NESTED | 0);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2);
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6,
+               sizeof(second_half_v6));
+  netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  netlink_done(&nlmsg);
+  err = netlink_send(&nlmsg, sock);
+  if (err) {
+  }
+
+error:
+  close(sock);
+}
+static void initialize_netdevices(void)
+{
+  char netdevsim[16];
+  sprintf(netdevsim, "netdevsim%d", (int)procid);
+  struct {
+    const char* type;
+    const char* dev;
+  } devtypes[] = {
+      {"ip6gretap", "ip6gretap0"}, {"bridge", "bridge0"},
+      {"vcan", "vcan0"},           {"bond", "bond0"},
+      {"team", "team0"},           {"dummy", "dummy0"},
+      {"nlmon", "nlmon0"},         {"caif", "caif0"},
+      {"batadv", "batadv0"},       {"vxcan", "vxcan1"},
+      {"netdevsim", netdevsim},    {"veth", 0},
+      {"xfrm", "xfrm0"},           {"wireguard", "wg0"},
+      {"wireguard", "wg1"},        {"wireguard", "wg2"},
+  };
+  const char* devmasters[] = {"bridge", "bond", "team", "batadv"};
+  struct {
+    const char* name;
+    int macsize;
+    bool noipv6;
+  } devices[] = {
+      {"lo", ETH_ALEN},
+      {"sit0", 0},
+      {"bridge0", ETH_ALEN},
+      {"vcan0", 0, true},
+      {"tunl0", 0},
+      {"gre0", 0},
+      {"gretap0", ETH_ALEN},
+      {"ip_vti0", 0},
+      {"ip6_vti0", 0},
+      {"ip6tnl0", 0},
+      {"ip6gre0", 0},
+      {"ip6gretap0", ETH_ALEN},
+      {"erspan0", ETH_ALEN},
+      {"bond0", ETH_ALEN},
+      {"veth0", ETH_ALEN},
+      {"veth1", ETH_ALEN},
+      {"team0", ETH_ALEN},
+      {"veth0_to_bridge", ETH_ALEN},
+      {"veth1_to_bridge", ETH_ALEN},
+      {"veth0_to_bond", ETH_ALEN},
+      {"veth1_to_bond", ETH_ALEN},
+      {"veth0_to_team", ETH_ALEN},
+      {"veth1_to_team", ETH_ALEN},
+      {"veth0_to_hsr", ETH_ALEN},
+      {"veth1_to_hsr", ETH_ALEN},
+      {"hsr0", 0},
+      {"dummy0", ETH_ALEN},
+      {"nlmon0", 0},
+      {"vxcan0", 0, true},
+      {"vxcan1", 0, true},
+      {"caif0", ETH_ALEN},
+      {"batadv0", ETH_ALEN},
+      {netdevsim, ETH_ALEN},
+      {"xfrm0", ETH_ALEN},
+      {"veth0_virt_wifi", ETH_ALEN},
+      {"veth1_virt_wifi", ETH_ALEN},
+      {"virt_wifi0", ETH_ALEN},
+      {"veth0_vlan", ETH_ALEN},
+      {"veth1_vlan", ETH_ALEN},
+      {"vlan0", ETH_ALEN},
+      {"vlan1", ETH_ALEN},
+      {"macvlan0", ETH_ALEN},
+      {"macvlan1", ETH_ALEN},
+      {"ipvlan0", ETH_ALEN},
+      {"ipvlan1", ETH_ALEN},
+      {"veth0_macvtap", ETH_ALEN},
+      {"veth1_macvtap", ETH_ALEN},
+      {"macvtap0", ETH_ALEN},
+      {"macsec0", ETH_ALEN},
+      {"veth0_to_batadv", ETH_ALEN},
+      {"veth1_to_batadv", ETH_ALEN},
+      {"batadv_slave_0", ETH_ALEN},
+      {"batadv_slave_1", ETH_ALEN},
+      {"geneve0", ETH_ALEN},
+      {"geneve1", ETH_ALEN},
+      {"wg0", 0},
+      {"wg1", 0},
+      {"wg2", 0},
+  };
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++)
+    netlink_add_device(&nlmsg, sock, devtypes[i].type, devtypes[i].dev);
+  for (i = 0; i < sizeof(devmasters) / (sizeof(devmasters[0])); i++) {
+    char master[32], slave0[32], veth0[32], slave1[32], veth1[32];
+    sprintf(slave0, "%s_slave_0", devmasters[i]);
+    sprintf(veth0, "veth0_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave0, veth0);
+    sprintf(slave1, "%s_slave_1", devmasters[i]);
+    sprintf(veth1, "veth1_to_%s", devmasters[i]);
+    netlink_add_veth(&nlmsg, sock, slave1, veth1);
+    sprintf(master, "%s0", devmasters[i]);
+    netlink_device_change(&nlmsg, sock, slave0, false, master, 0, 0, NULL);
+    netlink_device_change(&nlmsg, sock, slave1, false, master, 0, 0, NULL);
+  }
+  netlink_device_change(&nlmsg, sock, "bridge_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "bridge_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_0", "veth0_to_hsr");
+  netlink_add_veth(&nlmsg, sock, "hsr_slave_1", "veth1_to_hsr");
+  netlink_add_hsr(&nlmsg, sock, "hsr0", "hsr_slave_0", "hsr_slave_1");
+  netlink_device_change(&nlmsg, sock, "hsr_slave_0", true, 0, 0, 0, NULL);
+  netlink_device_change(&nlmsg, sock, "hsr_slave_1", true, 0, 0, 0, NULL);
+  netlink_add_veth(&nlmsg, sock, "veth0_virt_wifi", "veth1_virt_wifi");
+  netlink_add_linked(&nlmsg, sock, "virt_wifi", "virt_wifi0",
+                     "veth1_virt_wifi");
+  netlink_add_veth(&nlmsg, sock, "veth0_vlan", "veth1_vlan");
+  netlink_add_vlan(&nlmsg, sock, "vlan0", "veth0_vlan", 0, htons(ETH_P_8021Q));
+  netlink_add_vlan(&nlmsg, sock, "vlan1", "veth0_vlan", 1, htons(ETH_P_8021AD));
+  netlink_add_macvlan(&nlmsg, sock, "macvlan0", "veth1_vlan");
+  netlink_add_macvlan(&nlmsg, sock, "macvlan1", "veth1_vlan");
+  netlink_add_ipvlan(&nlmsg, sock, "ipvlan0", "veth0_vlan", IPVLAN_MODE_L2, 0);
+  netlink_add_ipvlan(&nlmsg, sock, "ipvlan1", "veth0_vlan", IPVLAN_MODE_L3S,
+                     IPVLAN_F_VEPA);
+  netlink_add_veth(&nlmsg, sock, "veth0_macvtap", "veth1_macvtap");
+  netlink_add_linked(&nlmsg, sock, "macvtap", "macvtap0", "veth0_macvtap");
+  netlink_add_linked(&nlmsg, sock, "macsec", "macsec0", "veth1_macvtap");
+  char addr[32];
+  sprintf(addr, DEV_IPV4, 14 + 10);
+  struct in_addr geneve_addr4;
+  if (inet_pton(AF_INET, addr, &geneve_addr4) <= 0)
+    exit(1);
+  struct in6_addr geneve_addr6;
+  if (inet_pton(AF_INET6, "fc00::01", &geneve_addr6) <= 0)
+    exit(1);
+  netlink_add_geneve(&nlmsg, sock, "geneve0", 0, &geneve_addr4, 0);
+  netlink_add_geneve(&nlmsg, sock, "geneve1", 1, 0, &geneve_addr6);
+  netdevsim_add((int)procid, 4);
+  netlink_wireguard_setup();
+  for (i = 0; i < sizeof(devices) / (sizeof(devices[0])); i++) {
+    char addr[32];
+    sprintf(addr, DEV_IPV4, i + 10);
+    netlink_add_addr4(&nlmsg, sock, devices[i].name, addr);
+    if (!devices[i].noipv6) {
+      sprintf(addr, DEV_IPV6, i + 10);
+      netlink_add_addr6(&nlmsg, sock, devices[i].name, addr);
+    }
+    uint64_t macaddr = DEV_MAC + ((i + 10ull) << 40);
+    netlink_device_change(&nlmsg, sock, devices[i].name, true, 0, &macaddr,
+                          devices[i].macsize, NULL);
+  }
+  close(sock);
+}
+static void initialize_netdevices_init(void)
+{
+  int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  if (sock == -1)
+    exit(1);
+  struct {
+    const char* type;
+    int macsize;
+    bool noipv6;
+    bool noup;
+  } devtypes[] = {
+      {"nr", 7, true},
+      {"rose", 5, true, true},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++) {
+    char dev[32], addr[32];
+    sprintf(dev, "%s%d", devtypes[i].type, (int)procid);
+    sprintf(addr, "172.30.%d.%d", i, (int)procid + 1);
+    netlink_add_addr4(&nlmsg, sock, dev, addr);
+    if (!devtypes[i].noipv6) {
+      sprintf(addr, "fe88::%02x:%02x", i, (int)procid + 1);
+      netlink_add_addr6(&nlmsg, sock, dev, addr);
+    }
+    int macsize = devtypes[i].macsize;
+    uint64_t macaddr = 0xbbbbbb +
+                       ((unsigned long long)i << (8 * (macsize - 2))) +
+                       (procid << (8 * (macsize - 1)));
+    netlink_device_change(&nlmsg, sock, dev, !devtypes[i].noup, 0, &macaddr,
+                          macsize, NULL);
+  }
+  close(sock);
+}
+
+#define MAX_FDS 30
+
+#define XT_TABLE_SIZE 1536
+#define XT_MAX_ENTRIES 10
+
+struct xt_counters {
+  uint64_t pcnt, bcnt;
+};
+
+struct ipt_getinfo {
+  char name[32];
+  unsigned int valid_hooks;
+  unsigned int hook_entry[5];
+  unsigned int underflow[5];
+  unsigned int num_entries;
+  unsigned int size;
+};
+
+struct ipt_get_entries {
+  char name[32];
+  unsigned int size;
+  void* entrytable[XT_TABLE_SIZE / sizeof(void*)];
+};
+
+struct ipt_replace {
+  char name[32];
+  unsigned int valid_hooks;
+  unsigned int num_entries;
+  unsigned int size;
+  unsigned int hook_entry[5];
+  unsigned int underflow[5];
+  unsigned int num_counters;
+  struct xt_counters* counters;
+  char entrytable[XT_TABLE_SIZE];
+};
+
+struct ipt_table_desc {
+  const char* name;
+  struct ipt_getinfo info;
+  struct ipt_replace replace;
+};
+
+static struct ipt_table_desc ipv4_tables[] = {
+    {.name = "filter"}, {.name = "nat"},      {.name = "mangle"},
+    {.name = "raw"},    {.name = "security"},
+};
+
+static struct ipt_table_desc ipv6_tables[] = {
+    {.name = "filter"}, {.name = "nat"},      {.name = "mangle"},
+    {.name = "raw"},    {.name = "security"},
+};
+
+#define IPT_BASE_CTL 64
+#define IPT_SO_SET_REPLACE (IPT_BASE_CTL)
+#define IPT_SO_GET_INFO (IPT_BASE_CTL)
+#define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1)
+
+struct arpt_getinfo {
+  char name[32];
+  unsigned int valid_hooks;
+  unsigned int hook_entry[3];
+  unsigned int underflow[3];
+  unsigned int num_entries;
+  unsigned int size;
+};
+
+struct arpt_get_entries {
+  char name[32];
+  unsigned int size;
+  void* entrytable[XT_TABLE_SIZE / sizeof(void*)];
+};
+
+struct arpt_replace {
+  char name[32];
+  unsigned int valid_hooks;
+  unsigned int num_entries;
+  unsigned int size;
+  unsigned int hook_entry[3];
+  unsigned int underflow[3];
+  unsigned int num_counters;
+  struct xt_counters* counters;
+  char entrytable[XT_TABLE_SIZE];
+};
+
+struct arpt_table_desc {
+  const char* name;
+  struct arpt_getinfo info;
+  struct arpt_replace replace;
+};
+
+static struct arpt_table_desc arpt_tables[] = {
+    {.name = "filter"},
+};
+
+#define ARPT_BASE_CTL 96
+#define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL)
+#define ARPT_SO_GET_INFO (ARPT_BASE_CTL)
+#define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1)
+
+static void checkpoint_iptables(struct ipt_table_desc* tables, int num_tables,
+                                int family, int level)
+{
+  struct ipt_get_entries entries;
+  socklen_t optlen;
+  int fd, i;
+  fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < num_tables; i++) {
+    struct ipt_table_desc* table = &tables[i];
+    strcpy(table->info.name, table->name);
+    strcpy(table->replace.name, table->name);
+    optlen = sizeof(table->info);
+    if (getsockopt(fd, level, IPT_SO_GET_INFO, &table->info, &optlen)) {
+      switch (errno) {
+      case EPERM:
+      case ENOENT:
+      case ENOPROTOOPT:
+        continue;
+      }
+      exit(1);
+    }
+    if (table->info.size > sizeof(table->replace.entrytable))
+      exit(1);
+    if (table->info.num_entries > XT_MAX_ENTRIES)
+      exit(1);
+    memset(&entries, 0, sizeof(entries));
+    strcpy(entries.name, table->name);
+    entries.size = table->info.size;
+    optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
+    if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
+      exit(1);
+    table->replace.valid_hooks = table->info.valid_hooks;
+    table->replace.num_entries = table->info.num_entries;
+    table->replace.size = table->info.size;
+    memcpy(table->replace.hook_entry, table->info.hook_entry,
+           sizeof(table->replace.hook_entry));
+    memcpy(table->replace.underflow, table->info.underflow,
+           sizeof(table->replace.underflow));
+    memcpy(table->replace.entrytable, entries.entrytable, table->info.size);
+  }
+  close(fd);
+}
+
+static void reset_iptables(struct ipt_table_desc* tables, int num_tables,
+                           int family, int level)
+{
+  struct xt_counters counters[XT_MAX_ENTRIES];
+  struct ipt_get_entries entries;
+  struct ipt_getinfo info;
+  socklen_t optlen;
+  int fd, i;
+  fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < num_tables; i++) {
+    struct ipt_table_desc* table = &tables[i];
+    if (table->info.valid_hooks == 0)
+      continue;
+    memset(&info, 0, sizeof(info));
+    strcpy(info.name, table->name);
+    optlen = sizeof(info);
+    if (getsockopt(fd, level, IPT_SO_GET_INFO, &info, &optlen))
+      exit(1);
+    if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
+      memset(&entries, 0, sizeof(entries));
+      strcpy(entries.name, table->name);
+      entries.size = table->info.size;
+      optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
+      if (getsockopt(fd, level, IPT_SO_GET_ENTRIES, &entries, &optlen))
+        exit(1);
+      if (memcmp(table->replace.entrytable, entries.entrytable,
+                 table->info.size) == 0)
+        continue;
+    }
+    table->replace.num_counters = info.num_entries;
+    table->replace.counters = counters;
+    optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) +
+             table->replace.size;
+    if (setsockopt(fd, level, IPT_SO_SET_REPLACE, &table->replace, optlen))
+      exit(1);
+  }
+  close(fd);
+}
+
+static void checkpoint_arptables(void)
+{
+  struct arpt_get_entries entries;
+  socklen_t optlen;
+  unsigned i;
+  int fd;
+  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < sizeof(arpt_tables) / sizeof(arpt_tables[0]); i++) {
+    struct arpt_table_desc* table = &arpt_tables[i];
+    strcpy(table->info.name, table->name);
+    strcpy(table->replace.name, table->name);
+    optlen = sizeof(table->info);
+    if (getsockopt(fd, SOL_IP, ARPT_SO_GET_INFO, &table->info, &optlen)) {
+      switch (errno) {
+      case EPERM:
+      case ENOENT:
+      case ENOPROTOOPT:
+        continue;
+      }
+      exit(1);
+    }
+    if (table->info.size > sizeof(table->replace.entrytable))
+      exit(1);
+    if (table->info.num_entries > XT_MAX_ENTRIES)
+      exit(1);
+    memset(&entries, 0, sizeof(entries));
+    strcpy(entries.name, table->name);
+    entries.size = table->info.size;
+    optlen = sizeof(entries) - sizeof(entries.entrytable) + table->info.size;
+    if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
+      exit(1);
+    table->replace.valid_hooks = table->info.valid_hooks;
+    table->replace.num_entries = table->info.num_entries;
+    table->replace.size = table->info.size;
+    memcpy(table->replace.hook_entry, table->info.hook_entry,
+           sizeof(table->replace.hook_entry));
+    memcpy(table->replace.underflow, table->info.underflow,
+           sizeof(table->replace.underflow));
+    memcpy(table->replace.entrytable, entries.entrytable, table->info.size);
+  }
+  close(fd);
+}
+
+static void reset_arptables()
+{
+  struct xt_counters counters[XT_MAX_ENTRIES];
+  struct arpt_get_entries entries;
+  struct arpt_getinfo info;
+  socklen_t optlen;
+  unsigned i;
+  int fd;
+  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < sizeof(arpt_tables) / sizeof(arpt_tables[0]); i++) {
+    struct arpt_table_desc* table = &arpt_tables[i];
+    if (table->info.valid_hooks == 0)
+      continue;
+    memset(&info, 0, sizeof(info));
+    strcpy(info.name, table->name);
+    optlen = sizeof(info);
+    if (getsockopt(fd, SOL_IP, ARPT_SO_GET_INFO, &info, &optlen))
+      exit(1);
+    if (memcmp(&table->info, &info, sizeof(table->info)) == 0) {
+      memset(&entries, 0, sizeof(entries));
+      strcpy(entries.name, table->name);
+      entries.size = table->info.size;
+      optlen = sizeof(entries) - sizeof(entries.entrytable) + entries.size;
+      if (getsockopt(fd, SOL_IP, ARPT_SO_GET_ENTRIES, &entries, &optlen))
+        exit(1);
+      if (memcmp(table->replace.entrytable, entries.entrytable,
+                 table->info.size) == 0)
+        continue;
+    } else {
+    }
+    table->replace.num_counters = info.num_entries;
+    table->replace.counters = counters;
+    optlen = sizeof(table->replace) - sizeof(table->replace.entrytable) +
+             table->replace.size;
+    if (setsockopt(fd, SOL_IP, ARPT_SO_SET_REPLACE, &table->replace, optlen))
+      exit(1);
+  }
+  close(fd);
+}
+
+#define NF_BR_NUMHOOKS 6
+#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN 32
+#define EBT_BASE_CTL 128
+#define EBT_SO_SET_ENTRIES (EBT_BASE_CTL)
+#define EBT_SO_GET_INFO (EBT_BASE_CTL)
+#define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO + 1)
+#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES + 1)
+#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO + 1)
+
+struct ebt_replace {
+  char name[EBT_TABLE_MAXNAMELEN];
+  unsigned int valid_hooks;
+  unsigned int nentries;
+  unsigned int entries_size;
+  struct ebt_entries* hook_entry[NF_BR_NUMHOOKS];
+  unsigned int num_counters;
+  struct ebt_counter* counters;
+  char* entries;
+};
+
+struct ebt_entries {
+  unsigned int distinguisher;
+  char name[EBT_CHAIN_MAXNAMELEN];
+  unsigned int counter_offset;
+  int policy;
+  unsigned int nentries;
+  char data[0] __attribute__((aligned(__alignof__(struct ebt_replace))));
+};
+
+struct ebt_table_desc {
+  const char* name;
+  struct ebt_replace replace;
+  char entrytable[XT_TABLE_SIZE];
+};
+
+static struct ebt_table_desc ebt_tables[] = {
+    {.name = "filter"},
+    {.name = "nat"},
+    {.name = "broute"},
+};
+
+static void checkpoint_ebtables(void)
+{
+  socklen_t optlen;
+  unsigned i;
+  int fd;
+  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < sizeof(ebt_tables) / sizeof(ebt_tables[0]); i++) {
+    struct ebt_table_desc* table = &ebt_tables[i];
+    strcpy(table->replace.name, table->name);
+    optlen = sizeof(table->replace);
+    if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_INFO, &table->replace,
+                   &optlen)) {
+      switch (errno) {
+      case EPERM:
+      case ENOENT:
+      case ENOPROTOOPT:
+        continue;
+      }
+      exit(1);
+    }
+    if (table->replace.entries_size > sizeof(table->entrytable))
+      exit(1);
+    table->replace.num_counters = 0;
+    table->replace.entries = table->entrytable;
+    optlen = sizeof(table->replace) + table->replace.entries_size;
+    if (getsockopt(fd, SOL_IP, EBT_SO_GET_INIT_ENTRIES, &table->replace,
+                   &optlen))
+      exit(1);
+  }
+  close(fd);
+}
+
+static void reset_ebtables()
+{
+  struct ebt_replace replace;
+  char entrytable[XT_TABLE_SIZE];
+  socklen_t optlen;
+  unsigned i, j, h;
+  int fd;
+  fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (fd == -1) {
+    switch (errno) {
+    case EAFNOSUPPORT:
+    case ENOPROTOOPT:
+      return;
+    }
+    exit(1);
+  }
+  for (i = 0; i < sizeof(ebt_tables) / sizeof(ebt_tables[0]); i++) {
+    struct ebt_table_desc* table = &ebt_tables[i];
+    if (table->replace.valid_hooks == 0)
+      continue;
+    memset(&replace, 0, sizeof(replace));
+    strcpy(replace.name, table->name);
+    optlen = sizeof(replace);
+    if (getsockopt(fd, SOL_IP, EBT_SO_GET_INFO, &replace, &optlen))
+      exit(1);
+    replace.num_counters = 0;
+    table->replace.entries = 0;
+    for (h = 0; h < NF_BR_NUMHOOKS; h++)
+      table->replace.hook_entry[h] = 0;
+    if (memcmp(&table->replace, &replace, sizeof(table->replace)) == 0) {
+      memset(&entrytable, 0, sizeof(entrytable));
+      replace.entries = entrytable;
+      optlen = sizeof(replace) + replace.entries_size;
+      if (getsockopt(fd, SOL_IP, EBT_SO_GET_ENTRIES, &replace, &optlen))
+        exit(1);
+      if (memcmp(table->entrytable, entrytable, replace.entries_size) == 0)
+        continue;
+    }
+    for (j = 0, h = 0; h < NF_BR_NUMHOOKS; h++) {
+      if (table->replace.valid_hooks & (1 << h)) {
+        table->replace.hook_entry[h] =
+            (struct ebt_entries*)table->entrytable + j;
+        j++;
+      }
+    }
+    table->replace.entries = table->entrytable;
+    optlen = sizeof(table->replace) + table->replace.entries_size;
+    if (setsockopt(fd, SOL_IP, EBT_SO_SET_ENTRIES, &table->replace, optlen))
+      exit(1);
+  }
+  close(fd);
+}
+
+static void checkpoint_net_namespace(void)
+{
+  checkpoint_ebtables();
+  checkpoint_arptables();
+  checkpoint_iptables(ipv4_tables, sizeof(ipv4_tables) / sizeof(ipv4_tables[0]),
+                      AF_INET, SOL_IP);
+  checkpoint_iptables(ipv6_tables, sizeof(ipv6_tables) / sizeof(ipv6_tables[0]),
+                      AF_INET6, SOL_IPV6);
+}
+
+static void reset_net_namespace(void)
+{
+  reset_ebtables();
+  reset_arptables();
+  reset_iptables(ipv4_tables, sizeof(ipv4_tables) / sizeof(ipv4_tables[0]),
+                 AF_INET, SOL_IP);
+  reset_iptables(ipv6_tables, sizeof(ipv6_tables) / sizeof(ipv6_tables[0]),
+                 AF_INET6, SOL_IPV6);
+}
+
+static void setup_common()
+{
+  if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) {
+  }
+}
+
+static void loop();
+
+static void sandbox_common()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  setsid();
+  int netns = open("/proc/self/ns/net", O_RDONLY);
+  if (netns == -1)
+    exit(1);
+  if (dup2(netns, kInitNetNsFd) < 0)
+    exit(1);
+  close(netns);
+  struct rlimit rlim;
+  rlim.rlim_cur = rlim.rlim_max = (200 << 20);
+  setrlimit(RLIMIT_AS, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 32 << 20;
+  setrlimit(RLIMIT_MEMLOCK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 136 << 20;
+  setrlimit(RLIMIT_FSIZE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+  setrlimit(RLIMIT_STACK, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 0;
+  setrlimit(RLIMIT_CORE, &rlim);
+  rlim.rlim_cur = rlim.rlim_max = 256;
+  setrlimit(RLIMIT_NOFILE, &rlim);
+  if (unshare(CLONE_NEWNS)) {
+  }
+  if (unshare(CLONE_NEWIPC)) {
+  }
+  if (unshare(0x02000000)) {
+  }
+  if (unshare(CLONE_NEWUTS)) {
+  }
+  if (unshare(CLONE_SYSVSEM)) {
+  }
+  typedef struct {
+    const char* name;
+    const char* value;
+  } sysctl_t;
+  static const sysctl_t sysctls[] = {
+      {"/proc/sys/kernel/shmmax", "16777216"},
+      {"/proc/sys/kernel/shmall", "536870912"},
+      {"/proc/sys/kernel/shmmni", "1024"},
+      {"/proc/sys/kernel/msgmax", "8192"},
+      {"/proc/sys/kernel/msgmni", "1024"},
+      {"/proc/sys/kernel/msgmnb", "1024"},
+      {"/proc/sys/kernel/sem", "1024 1048576 500 1024"},
+  };
+  unsigned i;
+  for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++)
+    write_file(sysctls[i].name, sysctls[i].value);
+}
+
+int wait_for_loop(int pid)
+{
+  if (pid < 0)
+    exit(1);
+  int status = 0;
+  while (waitpid(-1, &status, __WALL) != pid) {
+  }
+  return WEXITSTATUS(status);
+}
+
+static void drop_caps(void)
+{
+  struct __user_cap_header_struct cap_hdr = {};
+  struct __user_cap_data_struct cap_data[2] = {};
+  cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
+  cap_hdr.pid = getpid();
+  if (syscall(SYS_capget, &cap_hdr, &cap_data))
+    exit(1);
+  const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE);
+  cap_data[0].effective &= ~drop;
+  cap_data[0].permitted &= ~drop;
+  cap_data[0].inheritable &= ~drop;
+  if (syscall(SYS_capset, &cap_hdr, &cap_data))
+    exit(1);
+}
+
+static int do_sandbox_none(void)
+{
+  if (unshare(CLONE_NEWPID)) {
+  }
+  int pid = fork();
+  if (pid != 0)
+    return wait_for_loop(pid);
+  setup_common();
+  sandbox_common();
+  drop_caps();
+  initialize_netdevices_init();
+  if (unshare(CLONE_NEWNET)) {
+  }
+  initialize_devlink_pci();
+  initialize_netdevices();
+  loop();
+  exit(1);
+}
+
+#define FS_IOC_SETFLAGS _IOW('f', 2, long)
+static void remove_dir(const char* dir)
+{
+  DIR* dp;
+  struct dirent* ep;
+  int iter = 0;
+retry:
+  while (umount2(dir, MNT_DETACH) == 0) {
+  }
+  dp = opendir(dir);
+  if (dp == NULL) {
+    if (errno == EMFILE) {
+      exit(1);
+    }
+    exit(1);
+  }
+  while ((ep = readdir(dp))) {
+    if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+      continue;
+    char filename[FILENAME_MAX];
+    snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
+    while (umount2(filename, MNT_DETACH) == 0) {
+    }
+    struct stat st;
+    if (lstat(filename, &st))
+      exit(1);
+    if (S_ISDIR(st.st_mode)) {
+      remove_dir(filename);
+      continue;
+    }
+    int i;
+    for (i = 0;; i++) {
+      if (unlink(filename) == 0)
+        break;
+      if (errno == EPERM) {
+        int fd = open(filename, O_RDONLY);
+        if (fd != -1) {
+          long flags = 0;
+          if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) {
+          }
+          close(fd);
+          continue;
+        }
+      }
+      if (errno == EROFS) {
+        break;
+      }
+      if (errno != EBUSY || i > 100)
+        exit(1);
+      if (umount2(filename, MNT_DETACH))
+        exit(1);
+    }
+  }
+  closedir(dp);
+  int i;
+  for (i = 0;; i++) {
+    if (rmdir(dir) == 0)
+      break;
+    if (i < 100) {
+      if (errno == EPERM) {
+        int fd = open(dir, O_RDONLY);
+        if (fd != -1) {
+          long flags = 0;
+          if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) {
+          }
+          close(fd);
+          continue;
+        }
+      }
+      if (errno == EROFS) {
+        break;
+      }
+      if (errno == EBUSY) {
+        if (umount2(dir, MNT_DETACH))
+          exit(1);
+        continue;
+      }
+      if (errno == ENOTEMPTY) {
+        if (iter < 100) {
+          iter++;
+          goto retry;
+        }
+      }
+    }
+    exit(1);
+  }
+}
+
+static void kill_and_wait(int pid, int* status)
+{
+  kill(-pid, SIGKILL);
+  kill(pid, SIGKILL);
+  int i;
+  for (i = 0; i < 100; i++) {
+    if (waitpid(-1, status, WNOHANG | __WALL) == pid)
+      return;
+    usleep(1000);
+  }
+  DIR* dir = opendir("/sys/fs/fuse/connections");
+  if (dir) {
+    for (;;) {
+      struct dirent* ent = readdir(dir);
+      if (!ent)
+        break;
+      if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
+        continue;
+      char abort[300];
+      snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort",
+               ent->d_name);
+      int fd = open(abort, O_WRONLY);
+      if (fd == -1) {
+        continue;
+      }
+      if (write(fd, abort, 1) < 0) {
+      }
+      close(fd);
+    }
+    closedir(dir);
+  } else {
+  }
+  while (waitpid(-1, status, __WALL) != pid) {
+  }
+}
+
+static void setup_loop()
+{
+  checkpoint_net_namespace();
+}
+
+static void reset_loop()
+{
+  reset_net_namespace();
+}
+
+static void setup_test()
+{
+  prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
+  setpgrp();
+  write_file("/proc/self/oom_score_adj", "1000");
+}
+
+static void close_fds()
+{
+  int fd;
+  for (fd = 3; fd < MAX_FDS; fd++)
+    close(fd);
+}
+
+struct thread_t {
+  int created, call;
+  event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+  struct thread_t* th = (struct thread_t*)arg;
+  for (;;) {
+    event_wait(&th->ready);
+    event_reset(&th->ready);
+    execute_call(th->call);
+    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+    event_set(&th->done);
+  }
+  return 0;
+}
+
+static void execute_one(void)
+{
+  int i, call, thread;
+  int collide = 0;
+again:
+  for (call = 0; call < 3; call++) {
+    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+         thread++) {
+      struct thread_t* th = &threads[thread];
+      if (!th->created) {
+        th->created = 1;
+        event_init(&th->ready);
+        event_init(&th->done);
+        event_set(&th->done);
+        thread_start(thr, th);
+      }
+      if (!event_isset(&th->done))
+        continue;
+      event_reset(&th->done);
+      th->call = call;
+      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+      event_set(&th->ready);
+      if (collide && (call % 2) == 0)
+        break;
+      event_timedwait(&th->done, 45);
+      break;
+    }
+  }
+  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+    sleep_ms(1);
+  close_fds();
+  if (!collide) {
+    collide = 1;
+    goto again;
+  }
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS __WALL
+
+static void loop(void)
+{
+  setup_loop();
+  int iter;
+  for (iter = 0;; iter++) {
+    char cwdbuf[32];
+    sprintf(cwdbuf, "./%d", iter);
+    if (mkdir(cwdbuf, 0777))
+      exit(1);
+    reset_loop();
+    int pid = fork();
+    if (pid < 0)
+      exit(1);
+    if (pid == 0) {
+      if (chdir(cwdbuf))
+        exit(1);
+      setup_test();
+      execute_one();
+      exit(0);
+    }
+    int status = 0;
+    uint64_t start = current_time_ms();
+    for (;;) {
+      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+        break;
+      sleep_ms(1);
+      if (current_time_ms() - start < 5 * 1000)
+        continue;
+      kill_and_wait(pid, &status);
+      break;
+    }
+    remove_dir(cwdbuf);
+  }
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void execute_call(int call)
+{
+  intptr_t res;
+  switch (call) {
+  case 0:
+    break;
+  case 1:
+    res = syscall(__NR_socket, 0xaul, 1ul, 0ul);
+    if (res != -1)
+      r[0] = res;
+    break;
+  case 2:
+    NONFAILING(memcpy(
+        (void*)0x20000000,
+        "\x72\x61\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x03"
+        "\x00\x00\x03\x00\x00\x00\x30\x05\x00\x00\x00\x00\x00\x00\x68\x02\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x02\x00\x00\x60\x04\x00\x00"
+        "\x60\x04\x00\x00\x60\x04\x00\x00\x60\x04\x00\x00\x60\x04\x00\x00\x03"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x02"
+        "\x68\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x01\x68\x61\x73\x68\x6c\x69"
+        "\x6d\x69\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x02\x68\x73\x72\x30\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\x9f\x14\x52\x5e\xe3"
+        "\x22\xc8\x05\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x28\x00\x72\x70\x66\x69\x6c\x74\x65\x72\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x43\x54\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x01\x00"
+        "\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\xfe\x80"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\xff\x02\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+        "\xff\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x0c"
+        "\x39\x66\x0c\xff\x00\x00\xff\x00\x00\x00\x00\x77\x67\x32\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x74\x65\x61\x6d\x30\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x02\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\xd0\x00\xf8\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x69\x70"
+        "\x76\x36\x68\x65\x61\x64\x65\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x28\x01\x53\x45\x43\x4d\x41\x52\x4b\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x73\x79\x73\x74\x65\x6d\x5f\x75\x3a"
+        "\x6f\x62\x6a\x65\x63\x74\x5f\x72\x3a\x75\x70\x64\x61\x74\x65\x5f\x6d"
+        "\x6f\x64\x75\x6c\x65\x73\x5f\x65\x78\x65\x63\x5f\x74\x3a\x73\x30\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\x00\xd0\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\xfe\xff\xff\xff",
+        1420));
+    syscall(__NR_setsockopt, r[0], 0x29ul, 0x40ul, 0x20000000ul, 1ul);
+    break;
+  }
+}
+int main(void)
+{
+  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x32ul, -1, 0);
+  install_segv_handler();
+  use_temporary_dir();
+  do_sandbox_none();
+  return 0;
+}
diff --git a/syzkaller-repros/linux/13c53700ac03326096676d67fb7627427bef4972.c b/syzkaller-repros/linux/13c53700ac03326096676d67fb7627427bef4972.c
new file mode 100644
index 0000000..ae6ace0
--- /dev/null
+++ b/syzkaller-repros/linux/13c53700ac03326096676d67fb7627427bef4972.c
@@ -0,0 +1,460 @@
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/genetlink.h>
+#include <linux/if_addr.h>
+#include <linux/if_link.h>
+#include <linux/in6.h>
+#include <linux/neighbour.h>
+#include <linux/net.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/veth.h>
+
+static void sleep_ms(uint64_t ms)
+{
+  usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts))
+    exit(1);
+  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static bool write_file(const char* file, const char* what, ...)
+{
+  char buf[1024];
+  va_list args;
+  va_start(args, what);
+  vsnprintf(buf, sizeof(buf), what, args);
+  va_end(args);
+  buf[sizeof(buf) - 1] = 0;
+  int len = strlen(buf);
+  int fd = open(file, O_WRONLY | O_CLOEXEC);
+  if (fd == -1)
+    return false;
+  if (write(fd, buf, len) != len) {
+    int err = errno;
+    close(fd);
+    errno = err;
+    return false;
+  }
+  close(fd);
+  return true;
+}
+
+struct nlmsg {
+  char* pos;
+  int nesting;
+  struct nlattr* nested[8];
+  char buf[1024];
+};
+
+static struct nlmsg nlmsg;
+
+static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
+                         const void* data, int size)
+{
+  memset(nlmsg, 0, sizeof(*nlmsg));
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_type = typ;
+  hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
+  memcpy(hdr + 1, data, size);
+  nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
+}
+
+static void netlink_attr(struct nlmsg* nlmsg, int typ, const void* data,
+                         int size)
+{
+  struct nlattr* attr = (struct nlattr*)nlmsg->pos;
+  attr->nla_len = sizeof(*attr) + size;
+  attr->nla_type = typ;
+  memcpy(attr + 1, data, size);
+  nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
+}
+
+static int netlink_send_ext(struct nlmsg* nlmsg, int sock, uint16_t reply_type,
+                            int* reply_len)
+{
+  if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
+    exit(1);
+  struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
+  hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
+  struct sockaddr_nl addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.nl_family = AF_NETLINK;
+  unsigned n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0,
+                      (struct sockaddr*)&addr, sizeof(addr));
+  if (n != hdr->nlmsg_len)
+    exit(1);
+  n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
+  if (hdr->nlmsg_type == NLMSG_DONE) {
+    *reply_len = 0;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr))
+    exit(1);
+  if (reply_len && hdr->nlmsg_type == reply_type) {
+    *reply_len = n;
+    return 0;
+  }
+  if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))
+    exit(1);
+  if (hdr->nlmsg_type != NLMSG_ERROR)
+    exit(1);
+  return -((struct nlmsgerr*)(hdr + 1))->error;
+}
+
+static int netlink_send(struct nlmsg* nlmsg, int sock)