// https://syzkaller.appspot.com/bug?id=2eb1f35d6525fa4a74d75b4244971e5b1411c95a
// 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 <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/futex.h>
#include <linux/usb/ch9.h>

static 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 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 = 0;
  for (; 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_ACQUIRE))
      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;
}

#define MAX_FDS 30

#define USB_MAX_IFACE_NUM 4
#define USB_MAX_EP_NUM 32
#define USB_MAX_FDS 6

struct usb_endpoint_index {
  struct usb_endpoint_descriptor desc;
  int handle;
};

struct usb_iface_index {
  struct usb_interface_descriptor* iface;
  uint8_t bInterfaceNumber;
  uint8_t bAlternateSetting;
  uint8_t bInterfaceClass;
  struct usb_endpoint_index eps[USB_MAX_EP_NUM];
  int eps_num;
};

struct usb_device_index {
  struct usb_device_descriptor* dev;
  struct usb_config_descriptor* config;
  uint8_t bDeviceClass;
  uint8_t bMaxPower;
  int config_length;
  struct usb_iface_index ifaces[USB_MAX_IFACE_NUM];
  int ifaces_num;
  int iface_cur;
};

struct usb_info {
  int fd;
  struct usb_device_index index;
};

static struct usb_info usb_devices[USB_MAX_FDS];
static int usb_devices_num;

static bool parse_usb_descriptor(const char* buffer, size_t length,
                                 struct usb_device_index* index)
{
  if (length < sizeof(*index->dev) + sizeof(*index->config))
    return false;
  memset(index, 0, sizeof(*index));
  index->dev = (struct usb_device_descriptor*)buffer;
  index->config = (struct usb_config_descriptor*)(buffer + sizeof(*index->dev));
  index->bDeviceClass = index->dev->bDeviceClass;
  index->bMaxPower = index->config->bMaxPower;
  index->config_length = length - sizeof(*index->dev);
  index->iface_cur = -1;
  size_t offset = 0;
  while (true) {
    if (offset + 1 >= length)
      break;
    uint8_t desc_length = buffer[offset];
    uint8_t desc_type = buffer[offset + 1];
    if (desc_length <= 2)
      break;
    if (offset + desc_length > length)
      break;
    if (desc_type == USB_DT_INTERFACE &&
        index->ifaces_num < USB_MAX_IFACE_NUM) {
      struct usb_interface_descriptor* iface =
          (struct usb_interface_descriptor*)(buffer + offset);
      index->ifaces[index->ifaces_num].iface = iface;
      index->ifaces[index->ifaces_num].bInterfaceNumber =
          iface->bInterfaceNumber;
      index->ifaces[index->ifaces_num].bAlternateSetting =
          iface->bAlternateSetting;
      index->ifaces[index->ifaces_num].bInterfaceClass = iface->bInterfaceClass;
      index->ifaces_num++;
    }
    if (desc_type == USB_DT_ENDPOINT && index->ifaces_num > 0) {
      struct usb_iface_index* iface = &index->ifaces[index->ifaces_num - 1];
      if (iface->eps_num < USB_MAX_EP_NUM) {
        memcpy(&iface->eps[iface->eps_num].desc, buffer + offset,
               sizeof(iface->eps[iface->eps_num].desc));
        iface->eps_num++;
      }
    }
    offset += desc_length;
  }
  return true;
}

static struct usb_device_index* add_usb_index(int fd, const char* dev,
                                              size_t dev_len)
{
  int i = __atomic_fetch_add(&usb_devices_num, 1, __ATOMIC_RELAXED);
  if (i >= USB_MAX_FDS)
    return NULL;
  if (!parse_usb_descriptor(dev, dev_len, &usb_devices[i].index))
    return NULL;
  __atomic_store_n(&usb_devices[i].fd, fd, __ATOMIC_RELEASE);
  return &usb_devices[i].index;
}

static struct usb_device_index* lookup_usb_index(int fd)
{
  for (int i = 0; i < USB_MAX_FDS; i++) {
    if (__atomic_load_n(&usb_devices[i].fd, __ATOMIC_ACQUIRE) == fd)
      return &usb_devices[i].index;
  }
  return NULL;
}

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 const char default_string[] = {8, USB_DT_STRING, 's', 0, 'y', 0, 'z', 0};

static const char default_lang_id[] = {4, USB_DT_STRING, 0x09, 0x04};

static bool
lookup_connect_response_in(int fd, const struct vusb_connect_descriptors* descs,
                           const struct usb_ctrlrequest* ctrl,
                           struct usb_qualifier_descriptor* qual,
                           char** response_data, uint32_t* response_length)
{
  struct usb_device_index* index = lookup_usb_index(fd);
  uint8_t str_idx;
  if (!index)
    return false;
  switch (ctrl->bRequestType & USB_TYPE_MASK) {
  case USB_TYPE_STANDARD:
    switch (ctrl->bRequest) {
    case USB_REQ_GET_DESCRIPTOR:
      switch (ctrl->wValue >> 8) {
      case USB_DT_DEVICE:
        *response_data = (char*)index->dev;
        *response_length = sizeof(*index->dev);
        return true;
      case USB_DT_CONFIG:
        *response_data = (char*)index->config;
        *response_length = index->config_length;
        return true;
      case USB_DT_STRING:
        str_idx = (uint8_t)ctrl->wValue;
        if (descs && str_idx < descs->strs_len) {
          *response_data = descs->strs[str_idx].str;
          *response_length = descs->strs[str_idx].len;
          return true;
        }
        if (str_idx == 0) {
          *response_data = (char*)&default_lang_id[0];
          *response_length = default_lang_id[0];
          return true;
        }
        *response_data = (char*)&default_string[0];
        *response_length = default_string[0];
        return true;
      case USB_DT_BOS:
        *response_data = descs->bos;
        *response_length = descs->bos_len;
        return true;
      case USB_DT_DEVICE_QUALIFIER:
        if (!descs->qual) {
          qual->bLength = sizeof(*qual);
          qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
          qual->bcdUSB = index->dev->bcdUSB;
          qual->bDeviceClass = index->dev->bDeviceClass;
          qual->bDeviceSubClass = index->dev->bDeviceSubClass;
          qual->bDeviceProtocol = index->dev->bDeviceProtocol;
          qual->bMaxPacketSize0 = index->dev->bMaxPacketSize0;
          qual->bNumConfigurations = index->dev->bNumConfigurations;
          qual->bRESERVED = 0;
          *response_data = (char*)qual;
          *response_length = sizeof(*qual);
          return true;
        }
        *response_data = descs->qual;
        *response_length = descs->qual_len;
        return true;
      default:
        break;
      }
      break;
    default:
      break;
    }
    break;
  default:
    break;
  }
  return false;
}

typedef bool (*lookup_connect_out_response_t)(
    int fd, const struct vusb_connect_descriptors* descs,
    const struct usb_ctrlrequest* ctrl, bool* done);

static bool lookup_connect_response_out_generic(
    int fd, const struct vusb_connect_descriptors* descs,
    const struct usb_ctrlrequest* ctrl, bool* done)
{
  switch (ctrl->bRequestType & USB_TYPE_MASK) {
  case USB_TYPE_STANDARD:
    switch (ctrl->bRequest) {
    case USB_REQ_SET_CONFIGURATION:
      *done = true;
      return true;
    default:
      break;
    }
    break;
  }
  return false;
}

#define UDC_NAME_LENGTH_MAX 128

struct usb_raw_init {
  __u8 driver_name[UDC_NAME_LENGTH_MAX];
  __u8 device_name[UDC_NAME_LENGTH_MAX];
  __u8 speed;
};

enum usb_raw_event_type {
  USB_RAW_EVENT_INVALID = 0,
  USB_RAW_EVENT_CONNECT = 1,
  USB_RAW_EVENT_CONTROL = 2,
};

struct usb_raw_event {
  __u32 type;
  __u32 length;
  __u8 data[0];
};

struct usb_raw_ep_io {
  __u16 ep;
  __u16 flags;
  __u32 length;
  __u8 data[0];
};

#define USB_RAW_EPS_NUM_MAX 30
#define USB_RAW_EP_NAME_MAX 16
#define USB_RAW_EP_ADDR_ANY 0xff

struct usb_raw_ep_caps {
  __u32 type_control : 1;
  __u32 type_iso : 1;
  __u32 type_bulk : 1;
  __u32 type_int : 1;
  __u32 dir_in : 1;
  __u32 dir_out : 1;
};

struct usb_raw_ep_limits {
  __u16 maxpacket_limit;
  __u16 max_streams;
  __u32 reserved;
};

struct usb_raw_ep_info {
  __u8 name[USB_RAW_EP_NAME_MAX];
  __u32 addr;
  struct usb_raw_ep_caps caps;
  struct usb_raw_ep_limits limits;
};

struct usb_raw_eps_info {
  struct usb_raw_ep_info eps[USB_RAW_EPS_NUM_MAX];
};

#define USB_RAW_IOCTL_INIT _IOW('U', 0, struct usb_raw_init)
#define USB_RAW_IOCTL_RUN _IO('U', 1)
#define USB_RAW_IOCTL_EVENT_FETCH _IOR('U', 2, struct usb_raw_event)
#define USB_RAW_IOCTL_EP0_WRITE _IOW('U', 3, struct usb_raw_ep_io)
#define USB_RAW_IOCTL_EP0_READ _IOWR('U', 4, struct usb_raw_ep_io)
#define USB_RAW_IOCTL_EP_ENABLE _IOW('U', 5, struct usb_endpoint_descriptor)
#define USB_RAW_IOCTL_EP_DISABLE _IOW('U', 6, __u32)
#define USB_RAW_IOCTL_EP_WRITE _IOW('U', 7, struct usb_raw_ep_io)
#define USB_RAW_IOCTL_EP_READ _IOWR('U', 8, struct usb_raw_ep_io)
#define USB_RAW_IOCTL_CONFIGURE _IO('U', 9)
#define USB_RAW_IOCTL_VBUS_DRAW _IOW('U', 10, __u32)
#define USB_RAW_IOCTL_EPS_INFO _IOR('U', 11, struct usb_raw_eps_info)
#define USB_RAW_IOCTL_EP0_STALL _IO('U', 12)
#define USB_RAW_IOCTL_EP_SET_HALT _IOW('U', 13, __u32)
#define USB_RAW_IOCTL_EP_CLEAR_HALT _IOW('U', 14, __u32)
#define USB_RAW_IOCTL_EP_SET_WEDGE _IOW('U', 15, __u32)

static int usb_raw_open()
{
  return open("/dev/raw-gadget", O_RDWR);
}

static int usb_raw_init(int fd, uint32_t speed, const char* driver,
                        const char* device)
{
  struct usb_raw_init arg;
  strncpy((char*)&arg.driver_name[0], driver, sizeof(arg.driver_name));
  strncpy((char*)&arg.device_name[0], device, sizeof(arg.device_name));
  arg.speed = speed;
  return ioctl(fd, USB_RAW_IOCTL_INIT, &arg);
}

static int usb_raw_run(int fd)
{
  return ioctl(fd, USB_RAW_IOCTL_RUN, 0);
}

static int usb_raw_event_fetch(int fd, struct usb_raw_event* event)
{
  return ioctl(fd, USB_RAW_IOCTL_EVENT_FETCH, event);
}

static int usb_raw_ep0_write(int fd, struct usb_raw_ep_io* io)
{
  return ioctl(fd, USB_RAW_IOCTL_EP0_WRITE, io);
}

static int usb_raw_ep0_read(int fd, struct usb_raw_ep_io* io)
{
  return ioctl(fd, USB_RAW_IOCTL_EP0_READ, io);
}

static int usb_raw_ep_enable(int fd, struct usb_endpoint_descriptor* desc)
{
  return ioctl(fd, USB_RAW_IOCTL_EP_ENABLE, desc);
}

static int usb_raw_ep_disable(int fd, int ep)
{
  return ioctl(fd, USB_RAW_IOCTL_EP_DISABLE, ep);
}

static int usb_raw_configure(int fd)
{
  return ioctl(fd, USB_RAW_IOCTL_CONFIGURE, 0);
}

static int usb_raw_vbus_draw(int fd, uint32_t power)
{
  return ioctl(fd, USB_RAW_IOCTL_VBUS_DRAW, power);
}

static int usb_raw_ep0_stall(int fd)
{
  return ioctl(fd, USB_RAW_IOCTL_EP0_STALL, 0);
}

static void set_interface(int fd, int n)
{
  struct usb_device_index* index = lookup_usb_index(fd);
  if (!index)
    return;
  if (index->iface_cur >= 0 && index->iface_cur < index->ifaces_num) {
    for (int ep = 0; ep < index->ifaces[index->iface_cur].eps_num; ep++) {
      int rv = usb_raw_ep_disable(
          fd, index->ifaces[index->iface_cur].eps[ep].handle);
      if (rv < 0) {
      } else {
      }
    }
  }
  if (n >= 0 && n < index->ifaces_num) {
    for (int ep = 0; ep < index->ifaces[n].eps_num; ep++) {
      int rv = usb_raw_ep_enable(fd, &index->ifaces[n].eps[ep].desc);
      if (rv < 0) {
      } else {
        index->ifaces[n].eps[ep].handle = rv;
      }
    }
    index->iface_cur = n;
  }
}

static int configure_device(int fd)
{
  struct usb_device_index* index = lookup_usb_index(fd);
  if (!index)
    return -1;
  int rv = usb_raw_vbus_draw(fd, index->bMaxPower);
  if (rv < 0) {
    return rv;
  }
  rv = usb_raw_configure(fd);
  if (rv < 0) {
    return rv;
  }
  set_interface(fd, 0);
  return 0;
}

#define USB_MAX_PACKET_SIZE 4096

struct usb_raw_control_event {
  struct usb_raw_event inner;
  struct usb_ctrlrequest ctrl;
  char data[USB_MAX_PACKET_SIZE];
};

struct usb_raw_ep_io_data {
  struct usb_raw_ep_io inner;
  char data[USB_MAX_PACKET_SIZE];
};

static volatile long
syz_usb_connect_impl(uint64_t speed, uint64_t dev_len, const char* dev,
                     const struct vusb_connect_descriptors* descs,
                     lookup_connect_out_response_t lookup_connect_response_out)
{
  if (!dev) {
    return -1;
  }
  int fd = usb_raw_open();
  if (fd < 0) {
    return fd;
  }
  if (fd >= MAX_FDS) {
    close(fd);
    return -1;
  }
  struct usb_device_index* index = add_usb_index(fd, dev, dev_len);
  if (!index) {
    return -1;
  }
  char device[32];
  sprintf(&device[0], "dummy_udc.%llu", procid);
  int rv = usb_raw_init(fd, speed, "dummy_udc", &device[0]);
  if (rv < 0) {
    return rv;
  }
  rv = usb_raw_run(fd);
  if (rv < 0) {
    return rv;
  }
  bool done = false;
  while (!done) {
    struct usb_raw_control_event event;
    event.inner.type = 0;
    event.inner.length = sizeof(event.ctrl);
    rv = usb_raw_event_fetch(fd, (struct usb_raw_event*)&event);
    if (rv < 0) {
      return rv;
    }
    if (event.inner.type != USB_RAW_EVENT_CONTROL)
      continue;
    char* response_data = NULL;
    uint32_t response_length = 0;
    struct usb_qualifier_descriptor qual;
    if (event.ctrl.bRequestType & USB_DIR_IN) {
      if (!lookup_connect_response_in(fd, descs, &event.ctrl, &qual,
                                      &response_data, &response_length)) {
        usb_raw_ep0_stall(fd);
        continue;
      }
    } else {
      if (!lookup_connect_response_out(fd, descs, &event.ctrl, &done)) {
        usb_raw_ep0_stall(fd);
        continue;
      }
      response_data = NULL;
      response_length = event.ctrl.wLength;
    }
    if ((event.ctrl.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
        event.ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
      rv = configure_device(fd);
      if (rv < 0) {
        return rv;
      }
    }
    struct usb_raw_ep_io_data response;
    response.inner.ep = 0;
    response.inner.flags = 0;
    if (response_length > sizeof(response.data))
      response_length = 0;
    if (event.ctrl.wLength < response_length)
      response_length = event.ctrl.wLength;
    response.inner.length = response_length;
    if (response_data)
      memcpy(&response.data[0], response_data, response_length);
    else
      memset(&response.data[0], 0, response_length);
    if (event.ctrl.bRequestType & USB_DIR_IN) {
      rv = usb_raw_ep0_write(fd, (struct usb_raw_ep_io*)&response);
    } else {
      rv = usb_raw_ep0_read(fd, (struct usb_raw_ep_io*)&response);
    }
    if (rv < 0) {
      return rv;
    }
  }
  sleep_ms(200);
  return fd;
}

static volatile long syz_usb_connect(volatile long a0, volatile long a1,
                                     volatile long a2, volatile long a3)
{
  uint64_t speed = a0;
  uint64_t dev_len = a1;
  const char* dev = (const char*)a2;
  const struct vusb_connect_descriptors* descs =
      (const struct vusb_connect_descriptors*)a3;
  return syz_usb_connect_impl(speed, dev_len, dev, descs,
                              &lookup_connect_response_out_generic);
}

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);
  }
}

static void kill_and_wait(int pid, int* status)
{
  kill(-pid, SIGKILL);
  kill(pid, SIGKILL);
  for (int 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 setup_sysctl()
{
  char mypid[32];
  snprintf(mypid, sizeof(mypid), "%d", getpid());
  struct {
    const char* name;
    const char* data;
  } files[] = {
      {"/sys/kernel/debug/x86/nmi_longest_ns", "10000000000"},
      {"/proc/sys/kernel/hung_task_check_interval_secs", "20"},
      {"/proc/sys/net/core/bpf_jit_kallsyms", "1"},
      {"/proc/sys/net/core/bpf_jit_harden", "0"},
      {"/proc/sys/kernel/kptr_restrict", "0"},
      {"/proc/sys/kernel/softlockup_all_cpu_backtrace", "1"},
      {"/proc/sys/fs/mount-max", "100"},
      {"/proc/sys/vm/oom_dump_tasks", "0"},
      {"/proc/sys/debug/exception-trace", "0"},
      {"/proc/sys/kernel/printk", "7 4 1 3"},
      {"/proc/sys/kernel/keys/gc_delay", "1"},
      {"/proc/sys/vm/oom_kill_allocating_task", "1"},
      {"/proc/sys/kernel/ctrl-alt-del", "0"},
      {"/proc/sys/kernel/cad_pid", mypid},
  };
  for (size_t i = 0; i < sizeof(files) / sizeof(files[0]); i++) {
    if (!write_file(files[i].name, files[i].data))
      printf("write to %s failed: %s\n", files[i].name, strerror(errno));
  }
}

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 < 5; 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, 50 + (call == 2 ? 3000 : 0));
      break;
    }
  }
  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
    sleep_ms(1);
}

static void execute_one(void);

#define WAIT_FLAGS __WALL

static void loop(void)
{
  int iter = 0;
  for (;; 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 < 5000)
        continue;
      kill_and_wait(pid, &status);
      break;
    }
  }
}

uint64_t r[1] = {0xffffffffffffffff};

void execute_call(int call)
{
  intptr_t res = 0;
  switch (call) {
  case 0:
    memcpy((void*)0x20000000, "/dev/usbmon#\000", 13);
    res = -1;
    res = syz_open_dev(0x20000000, 0, 0x1a02);
    if (res != -1)
      r[0] = res;
    break;
  case 1:
    syscall(__NR_mmap, 0x20000000ul, 0x800000ul, 0x1800003ul, 0x11ul, r[0],
            0ul);
    break;
  case 2:
    memcpy(
        (void*)0x20000040,
        "\x12\x01\x00\x00\x00\x00\x18\x10\x5e\x04\xda\x07\x00\x00\x00\x00\x00"
        "\x01\x09\x02\x24\x00\x01\x00\x00\x00\x00\x09\x04\x00\x00\x09\x03\x00"
        "\x00\x00\x09\x21\x00\x00\x00\x01\x22\x22\x00\x09\x05\x81\x03\x08",
        50);
    syz_usb_connect(0, 0x36, 0x20000040, 0);
    break;
  case 3:
    *(uint32_t*)0x20001940 = r[0];
    *(uint64_t*)0x20001948 = 0;
    *(uint64_t*)0x20001950 = 2;
    *(uint64_t*)0x20001958 = 0;
    *(uint64_t*)0x20001960 = 0;
    memcpy(
        (void*)0x20001978,
        "\x48\xc4\x3a\xea\x3a\x62\xa4\xc6\x0c\x02\x7a\x91\xbf\x05\x09\xe4\xc1"
        "\xaa\xe5\xb0\xa6\x06\xd3\x57\xc3\x42\xc3\x24\x56\x5d\xba\x3b\x40\x89"
        "\xd7\xda\xf2\x7f\x27\x53\xa5\x06\xf4\x3d\x74\x4c\x24\xdc\x0f\xf8\x8c"
        "\x74\xa0\xdb\x47\x4b\x9f\xce\x5e\xc7\xe4\x56\x43\xcf\x25\x07\x71\x7f"
        "\xb2\x3e\x2d\x73\xf7\xc8\x2d\x72\x40\x59\x2f\x67\xcc\xd5\x5c\xfd\xd7"
        "\x2a\x69\x78\xf5\x2f\xc3\x94\x09\x46\xe2\xfa\x7c\x22\x48\xb9\x41\xa5"
        "\xa0\x1f\xc7\x22\x7a\x9c\x43\x81\xe7\xc9\x2c\xcf\x69\x06\x2e\xf9\x9b"
        "\x18\x47\xab\xdb\xe3\x6c\x25\x39\x3a\xb3\xfc\xc3\x7f\x23\x4f\x63\x3a"
        "\xa3\x96\xba\xe3\x23\x8b\x4a\xe2\xd0\xfa\xe0\x20\x47\x36\xec\xde\x52"
        "\x24\x77\xf7\xbf\xb6\x37\x58\x72\xf1\x05\x4d\x4d\x74\x53\x6f\x38\x8d"
        "\x04\x5f\x85\x05\x62\x75\xe4\x51\xb5\x91\xff\xc4\x2c\x4e\x25\xc9\xeb"
        "\xa7\xc8\xc7\x6a\x41\x00\x6b\x83\x7e\xa3\x91\xff\xa3\xac\x8f\xa5\xce"
        "\xa7\x29\x54\xd1\x29\x25\x87\xd7\x79\xbb\x81\x6f\x63\xac\x7d\x1f\x76"
        "\x93\x7d\xdb\x03\x42\x3e\x72\x29\x43\xb7\x3f\x47\xbc\x3d\x3a\x11\x69"
        "\x0f\xd4\x0d\xfd\x8b\xb3\xe6\x7a\xcc\x37\xdf\xca\x70\xc5\xa7\x03\x74"
        "\x62\xf2\x81\x5b\xd0\xa2\x81\xae\x93\x56\x05\x11\x6f\x24\xd9\x4f\xbb"
        "\xcb\x8f\xa7\x88\x3c\xf2\x58\xc5\x5d\x25\xcb\x0a\x51\x87\xff\x09\xf0"
        "\x19\xb8\xe7\x05\xf0\x1d\x0f\x1a\x41\x21\xfd\xc0\x8e\xd2\x26\x64\xbc"
        "\xf8\x67\x6e\x13\x36\x00\x54\xd4\x68\x24\xa2\xef\x27\x1c\x94\x83\x5f"
        "\xc4\x47\xee\x03\xaa\x19\x6c\x0b\x9d\xec\xf4\xb7\x21\x6e\x6f\xd8\xd9"
        "\x5e\x1f\x78\x23\xc2\x31\x48\x28\xfc\x8c\x38\x3c\x52\x35\xd3\x38\xbc"
        "\xc0\x91\xb0\x47\xd7\x2d\xc4\xba\xd2\xc8\x3c\x86\x70\x43\xac\xba\xa4"
        "\xf7\x55\x4d\x20\x85\x4b\xc8\x6d\x49\x39\x39\xb5\x72\x8a\x2e\xa7\xc6"
        "\x00\x7a\xc3\xdf\x54\xbb\x4a\x2b\xcd\x69\x26\xce\xcc\x91\xa6\x72\x18"
        "\xbb\x56\x68\x38\x32\xe0\x41\x86\xb8\x30\x98\x1c\x56\xd8\x1e\xea\x11"
        "\xaa\xac\x6d\x7c\xd3\xbc\x33\x65\x8f\xe1\x0c\x6e\x97\x76\x17\xf8\x4f"
        "\xf0\x12\x9d\xbe\x04\xdb\x1f\x4e\x01\xef\xe3\x17\x00\xcb\x59\x3a\x68"
        "\xf0\x07\xc1\xb1\xf2\x49\x28\xea\xed\xbd\xca\xdd\x6f\xbb\xb9\x2e\xf6"
        "\xce\x11\x15\xfb\x2a\x50\xd9\x90\x61\x28\x10\xb2\x1b\xe6\x92\x5a\x56"
        "\x27\x20\xf5\x4b\x94\xcd\x23\x9e\x99\x2a\x7e\x72\x14\x13\x1d\x12\xd1"
        "\xcc\x14\x66\x3e\xf1\x92\xb9\xfa\x6c\x2a\xa4\x82\xbf\x48\xe2\x79\x7f"
        "\x4b\x6b\x65\x30\xa0\x56\x80\xa8\x3d\xb0\x9c\x44\xf6\x8f\x46\xbf\x94"
        "\xee\xa6\x48\x44\xa1\xa9\x2a\x80\x92\xc1\x0c\x6f\x1b\x07\x84\x1c\x40"
        "\x41\xb5\xd8\x42\x7d\xb2\xd7\xc7\xe4\x1d\x50\x8a\xda\xf4\xb6\x0e\x4a"
        "\x54\xbf\x97\xbb\x52\x93\x19\x40\xe6\x98\xec\xe8\x90\x58\xc6\x82\xb0"
        "\x75\x27\xbe\x0b\xa2\x8d\x4c\xfa\xef\x4d\x53\x4b\x00\xe5\xa8\x59\x12"
        "\x3b\x02\xe6\x84\x25\x3c\xc3\x08\x2e\x05\x71\xfa\xe7\x38\xe6\x79\x3e"
        "\x90\x18\x54\xf3\x0b\xfc\x83\x21\x75\x0d\x09\xc6\x5d\x4a\x35\x2b\xe1"
        "\xf7\x9d\x5b\x42\x5d\xf9\x98\xed\x4a\x59\x31\xc6\x2a\x12\x66\x76\xf3"
        "\x65\xcf\xd8\x8b\xc3\xab\xff\x19\x51\xd4\xda\xa6\x80\x0a\xbe\x1a\x6a"
        "\xe1\xe8\xc8\xa8\x91\x62\x48\x0d\x5c\x15\x2e\x70\x47\xbf\x51\x14\x1a"
        "\xd4\x3e\xb5\xb3\x5e\xce\x39\x55\xae\x49\x23\xb2\x0f\xb6\x3d\x39\x73"
        "\xec\x33\x94\x84\x87\x31\xaa\x89\x55\x2f\xe9\x7e\x2f\x48\x76\x34\x1e"
        "\xd4\x16\x40\xfc\x64\xef\x0c\xa7\x0d\x3c\x21\x05\x81\x05\x75\x9c\x52"
        "\x82\x19\xf4\xe5\xf5\x0a\x70\x20\xc6\x4d\x06\x62\xd7\x93\xde\x52\x10"
        "\x8d\x7f\x92\xe6\x50\xe1\x1b\x98\xf2\x09\x62\x0b\x76\x73\x99\x23\x74"
        "\x46\xb1\x66\x1b\xd0\xf0\x56\xe5\x49\x92\xf3\x8f\x2a\x87\x10\x4d\xbb"
        "\x80\xb6\xef\xe3\xd3\x31\x56\x23\x55\xcd\x55\x6a\xec\x1f\xe3\x17\xe9"
        "\xb9\x75\x7d\xc2\x00\x22\x18\x8d\x2c\x10\xe1\x82\x03\x98\xe3\x87\x5e"
        "\x7f\xb3\xdf\x1c\xfa\xbd\xf9\x93\x04\x1f\x2f\xba\x9a\xae\x01\xb3\x99"
        "\xfe\x3b\x3a\x64\xf3\x32\x5d\x8a\x05\x8d\x9b\x61\x4b\x83\xda\x22\x53"
        "\x52\xf7\xd5\x51\x62\xa8\x9f\xbb\x1f\xc9\x9c\x0e\x16\x90\x8d\x30\x96"
        "\x04\x93\xc8\x43\xa9\xf1\x47\x15\x8f\x2d\x0f\x62\x14\x9f\x20\xeb\x6a"
        "\x5c\x9f\x32\x96\x14\x08\xbc\x11\xf4\x9b\x72\xc5\xbe\xc5\xb9\x49\x62"
        "\xe2\x4c\x71\xc4\x66\x00\xe9\xbf\x09\xde\xdd\x90\x8b\x71\x00\x69\x20"
        "\x0c\xd2\xda\x76\x78\xb8\x62\x20\x87\xc0\xac\xb4\x05\xa0\x83\xe1\xdd"
        "\x9b\x2a\x11\xc5\x35\xca\x9e\x9a\x43\x30\x4d\xea\x30\xd8\x70\x98\xeb"
        "\x47\x98\xf9\x87\x7b\x9b\x54\xa9\x98\x5a\x03\xc7\xaa\x64\x04\x5e\xbf"
        "\xbe\xb4\xa1\xdd\xbd\xc1\xe7\x1d\x14\x83\xd7\xaf\x7f\xaa\x0c\x55\x89"
        "\xda\x1e\x41\x0d\x66\x8b\xbd\xd8\x39\xb4\xaf\x39\xc0\xd8\x6e\xae\xce"
        "\x33\xc3\xa0\xac\x16\x8e\x27\xc6\xf9\xe5\x37\x18\x0c\x83\x00\x5a\x25"
        "\xcd\xc0\xe4\x22\xc8\x5d\x50\xb3\x0e\x09\x01\xb2\xfc\x88\x10\x57\x28"
        "\x50\x66\x00\x67\x0a\xb3\x08\x57\xb0\xa3\xcd\x5c\x80\x31\x49\xc1\x40"
        "\x04\xa8\xa1\xdc\xa1\x9e\x0f\xc5\xde\x0e\xfb\x4c\x39\xfe\x34\xdf\x42"
        "\x3a\x93\x06\xde\xea\x10\xd5\x34\x74\xbf\x6b\x37\xaa\x23\x8e\x2e\x1b"
        "\x2b\xa2\x52\x78\x46\x78\x2f\x0e\xa7\x22\x32\x01\x87\xaf\x15\x3f\xa5"
        "\x2c\xb7\x35\xa6\x8f\x97\xb5\x1d\xd2\xe8\x07\x1b\xac\xb7\xe8\x0b\xc2"
        "\xa9\xd3\x9f\x13\x02\xfe\xed\x95\x4a\x65\x89\x31\xfd\xbd\xd8\xd2\xd2"
        "\x3f\x2e\x14\x5b\x04\xb6\x61\x63\x1c\x14\x4a\x4f\xa3\xc9\x78\x62\x69"
        "\x1d\x33\x66\x17\xb4\x65\x93\x97\x05\xab\xa9\xbd\x19\x7e\x5d\x75\x9b"
        "\xf5\xfc\x8c\x58\x5c\x53\xe9\x7a\x18\xd0\x61\x8d\x06\xb2\x2f\x0c\x0c"
        "\xae\x58\xcc\xca\xc3\xcb\x04\x63\x06\x30\x1a\xbf\xef\x07\x86\x07\x07"
        "\x1a\x5f\x32\x40\xca\xa6\xc5\x85\xd3\x2a\xaa\x8c\x7a\x48\x2c\x64\xa3"
        "\xe7\xca\xba\x6e\x95\x84\x61\xb2\xf4\xce\x86\xe5\xbe\x47\xc0\x46\xbc"
        "\xb8\x57\xa2\xeb\x37\xee\x88\x12\x30\x7a\xfa\xca\x14\x4f\x83\x97\x19"
        "\x34\xd9\x38\x93\xe1\x40\x32\x3e\xe3\xf8\xce\x19\x1b\xa9\xa1\x16\x3f"
        "\x30\x7b\xd0\xfc\xc1\x44\xfe\x6e\x86\x4a\xf9\x51\xed\x4b\x39\xb4\xb9"
        "\xf4\x06\x16\x93\x6b\xeb\x0f\x5f\x6a\x4c\x43\x75\x9e\x2f\x1c\x95\xdf"
        "\x59\xfb\xf0\x55\x96\xf3\x32\x37\x9f\x26\xd7\xeb\x30\x96\x72\x46\x26"
        "\x2f\x11\x50\xae\x19\xc2\xa3\x91\xcb\x54\xab\x4e\xce\x52\xf2\x19\xd5"
        "\x4c\xaa\xb3\xcd\x2c\xf1\x73\xac\xc7\x52\x11\x7c\xc4\x29\xb5\x74\x7f"
        "\xfd\x47\x3a\x44\x81\xa9\x84\xa5\x81\x40\x46\xa7\x47\x38\x15\x30\x0f"
        "\x95\x83\x9c\x7f\x38\x83\x27\xdf\xa5\xe3\x36\xc2\x9c\x63\xa6\xcc\xdf"
        "\xf4\x00\xf6\xf5\xe0\x58\x69\xda\xb5\x2e\x7d\x73\xea\x73\x3b\x9a\xd2"
        "\xf4\x57\xbc\x41\x6b\xe6\x39\x64\xfb\x00\x9b\xa8\xce\x57\xa8\x94\x5d"
        "\x26\x17\xc7\x6b\x37\xe3\x1f\x2d\x45\x06\x5e\x42\xbb\x54\xb8\xc2\x69"
        "\xcd\x53\x86\x91\xe5\xf8\xb4\x34\xfd\xf3\xf3\xb4\xe0\xfd\x88\x81\x6f"
        "\xb4\x4d\x14\xeb\x93\x60\xda\x1a\xf4\x93\x61\xb0\xc3\x83\xd0\xc9\xb1"
        "\xf8\x61\x74\xc2\x6e\xd9\x08\xd9\x25\xf3\x15\x14\xe8\x1a\x7b\xc3\x78"
        "\xac\xa4\xdb\xaf\x0a\x08\x4a\x1f\x77\xad\x17\xe8\xc7\x0a\xb9\x84\xac"
        "\xbc\xa2\x16\xab\xca\x15\x7f\x13\x84\x30\xe3\x1a\xd6\xe6\x2a\xf9\x0f"
        "\xd2\x97\xfa\xc0\x53\x8e\xf4\x37\xde\x67\xda\xab\xb5\x45\xba\x66\x4b"
        "\x0a\xce\x16\x14\x2c\x0f\x2f\x2f\x47\xf7\xe2\xe4\x98\x86\x45\xc1\x2f"
        "\x54\x48\xb0\xae\xed\x6f\xb3\xba\xc3\x6e\xab\x02\x34\x53\xd1\xfa\x52"
        "\xa1\x41\x19\x04\xd9\x6e\xa3\xb2\xe2\xab\x7c\x61\xc6\x4f\xd8\x7f\xac"
        "\xb2\xed\xea\x8a\x62\xc8\xfc\x64\x69\x39\x02\x79\x81\x91\xf2\x9e\x30"
        "\x64\x74\x71\xac\xb2\x63\x0a\x80\x2f\xc8\xad\x37\x49\x85\x0e\xd8\x3d"
        "\xdd\x4d\xfa\x49\x4d\x83\x5c\x80\x2e\x92\x98\x6e\xf8\xae\x39\x7d\x3b"
        "\xc3\x9e\xda\x4d\x22\x06\xdf\xa8\x10\xef\xa4\x76\xc7\x45\x04\x82\x6e"
        "\x7d\x03\xc5\xd5\x03\xdc\xa5\xa3\xd8\xea\x0d\xbf\xad\x7d\x79\x1a\x85"
        "\xe3\xca\x8b\x31\x00\xd6\x1d\xe3\x87\x89\x2f\xb7\xd4\x71\xa9\x21\xdb"
        "\xd5\x56\x25\x6e\x8d\x6a\xe4\xa6\xdc\x5b\x46\x04\x6f\x73\x8a\x5e\x51"
        "\x01\x82\x70\x59\x7a\xed\x14\x61\xeb\xe6\xfe\xb5\x5e\xb3\x9d\x9c\x83"
        "\x6e\xa2\xe3\x5e\x51\x1c\x91\xd7\xd8\xcc\x66\x33\xef\xf2\x97\x2b\xce"
        "\x67\x5a\xc4\x91\xd6\xb8\x29\xac\xa2\x9d\x56\x7f\x31\x1c\x80\x93\x77"
        "\xde\x3f\x3b\xe1\x5a\xb3\xc5\x64\x9d\xd5\x23\xb2\xde\xc3\x97\x11\xe1"
        "\xff\xa5\x1c\x2f\x7c\x2c\xa3\x85\xc6\xb4\x3d\xef\xc9\x2f\xb2\xf5\xbc"
        "\xdb\xd6\xfb\x00\xf0\x6e\x4e\xe4\x3f\x64\x6e\xe1\xc5\x14\x78\xfa\x31"
        "\xf2\xcf\x54\xe9\x3e\xd6\x9c\xaa\x78\x74\x5b\x86\xcc\x63\x41\xb4\x56"
        "\xb4\xb5\xfb\xa4\x7d\x74\x54\x72\x01\x84\xb4\x67\xbb\x8b\xf5\xbd\x32"
        "\x41\x29\x53\x49\x7e\xd3\x38\xb7\x01\x65\x42\x95\x96\x9f\x87\x6b\x61"
        "\xed\xe4\x2c\xce\x82\x31\xe1\x17\x0d\x0a\x50\x41\xa9\xfc\x62\xef\x60"
        "\x74\x62\xe3\xf7\xf7\xab\xb5\xf7\xcc\x69\x7c\x66\x2b\x50\x9b\xa1\x43"
        "\x29\xed\xad\x64\x96\x90\xf8\xfb\xb0\x4a\x28\x78\xc8\xf3\x9f\x8f\x14"
        "\x2f\xf5\xd5\x79\x73\xfa\xf1\x10\x3e\x82\x35\xcb\xa6\xd8\x95\xb3\x9b"
        "\x30\x21\x94\x90\x29\xaf\x2a\x73\xf5\xcb\x03\xe2\x0c\x57\x31\x47\x46"
        "\x76\x56\x76\x53\x84\x11\x53\xe1\x0c\x3d\xfe\xaf\xb5\x1b\xab\xed\xa3"
        "\x84\x5a\xfb\xa7\xaf\xd3\x11\x2c\xdf\xf2\x8b\x56\x9a\xf2\x0f\x0a\x97"
        "\xd4\x28\x61\x16\x3c\xb0\xaf\xb0\xc4\x91\xb2\xdd\xaa\x5e\xaa\x92\x7c"
        "\xdc\xd8\x7d\x99\x8c\xce\x8f\x7c\x4b\x13\x67\x39\x28\x46\xaf\xd9\x96"
        "\xb4\xa0\xbe\xc0\x91\x72\x60\xf7\x03\x4b\x32\xb3\xa5\x48\xe3\xec\xcb"
        "\x5b\xfe\x6c\x81\xe7\xb9\xf6\x80\xb9\x55\x97\x8c\x80\x31\x49\x29\xf7"
        "\xd9\xb3\xda\x19\x22\x6f\xe0\x83\x83\x4f\x35\xad\xa4\x17\x43\x9e\x88"
        "\x1d\xb5\xf1\xef\x93\x52\x1e\x11\x68\x0f\x2e\x1f\xda\x27\x88\x3a\x68"
        "\x0a\xfb\xa8\x7a\xdd\x54\xeb\x85\xc4\xf4\x37\xd4\x33\x71\x3e\xf0\xbe"
        "\x5e\xff\xd5\x73\x52\x94\x5c\x1b\x7d\xba\x09\x60\x24\x5d\xa1\xa1\x88"
        "\x47\xc1\x3d\xd7\x7a\x62\xee\x0f\x9d\x2c\x5e\x52\x68\x2e\x99\x47\xbf"
        "\xf0\xe2\x1b\x0a\x35\x5c\xdc\x96\x5c\xc7\x71\x9b\x4c\x78\x12\x77\x1c"
        "\x70\xa3\x92\x2a\xef\xda\x90\x4d\x7d\x11\x2a\xac\xbb\x74\x00\x4a\x8f"
        "\xb3\xdc\xa7\x71\xd2\x41\x93\x2c\x4e\x81\x45\x7a\x19\x09\x0c\xa3\x68"
        "\x82\xd2\xa7\xb7\x25\xef\x5c\xb7\x5f\x17\x02\xe2\x7d\x93\xc3\x1f\x15"
        "\x63\x2d\x85\xfe\xc9\x2b\x28\xab\x05\xe8\x69\x33\x46\x80\xc8\xde\xf9"
        "\xaa\x81\xd7\xa6\x1b\x31\x48\x9c\x66\x1a\x16\x3c\x8c\x02\x15\xf5\x3b"
        "\x26\xe1\xda\x29\x39\x47\x42\x09\xdb\x19\x6f\xc6\x19\x38\xcd\x5c\x2c"
        "\x9d\xb4\xd1\x72\x05\xe1\x27\x76\xf5\xc9\x14\x20\x5b\xad\x23\x7f\x96"
        "\x59\x81\x7b\x56\x83\x9a\x8d\x3c\xfa\xc4\x2e\xed\x1c\xf2\xd2\xe1\xda"
        "\x6d\xd1\x83\x46\x4a\xc1\x2a\x34\x68\xad\x6c\x0d\x89\xfb\x6d\x51\x7a"
        "\x35\x40\xa4\x49\xdd\x2e\xbd\x65\xf3\x44\xb4\xe8\x8d\x02\xa2\xa2\xa3"
        "\xe4\xee\x14\xc5\xff\x21\x25\x3f\x37\x20\xeb\xb9\x1b\x47\xfb\xa2\xf0"
        "\xa5\xae\x8d\xc9\xbc\xfa\x86\x0e\x04\xff\x3a\xfc\x87\x34\xec\x19\x11"
        "\x20\x34\xa7\x4a\x17\x33\xd3\x1c\xa1\x45\x87\xaf\xb2\x72\xad\x20\x4b"
        "\x71\x24\x63\x72\x48\x75\x47\x3a\xdf\x14\xcc\xea\x5f\xc9\x79\xd1\x1d"
        "\xb4\xea\x47\x04\x8b\xb7\x51\xb8\x3f\x50\x21\x1b\x2d\x3e\x29\x99\x38"
        "\x2d\x3e\xc7\x5a\x6f\xa3\x3e\xa2\xaa\xd5\xc2\xa2\x8e\x1b\xcd\xfc\xb5"
        "\xf3\x0c\x4d\x0a\x9e\x4a\x61\x5d\xb1\xbf\xc5\x80\x60\x71\x6f\xa5\xc7"
        "\x03\x07\x4f\xa9\xf5\x86\xa9\x4e\xb8\x44\x3f\x77\xbc\x43\x5c\x56\x22"
        "\x3c\xbb\x89\xa9\x1d\x68\x85\xf2\x57\xe7\x83\x64\xcf\x62\xbf\x92\xa2"
        "\x46\x45\x44\x92\x08\x19\x6d\xd2\xa8\x68\xd8\xca\xa8\xa9\x63\xc0\xd6"
        "\xa5\x5f\x78\xa3\x0f\x97\x98\x74\xec\x02\xbc\x5a\x65\x7a\xb0\x79\x8c"
        "\xcc\x1f\xdc\x8b\x74\x61\xbf\x0a\xfd\x7a\xa8\x83\xf5\x0e\x0d\x46\xd0"
        "\x27\x8f\xc4\x10\xf5\x3b\xac\xcd\x4f\x8b\x7c\xaf\x51\x7c\x42\xb4\xa8"
        "\x45\x83\xf5\x70\x21\x87\x7d\x99\x94\x2b\x0c\x74\x64\x73\x68\x26\x65"
        "\xec\xc0\xb3\x90\x84\x48\x70\xdf\x50\x14\x9b\x10\x92\xe4\xf7\x14\x01"
        "\x4e\x46\x6c\x84\x3b\x68\x84\x57\x58\x03\x4e\x4c\xbd\xb6\x64\xb8\xdf"
        "\x54\x94\x9e\xd9\x57\xb2\xfe\xcf\x9d\xe1\xb2\x68\x95\xf3\xc4\x94\x2f"
        "\xbe\x35\x2a\xd8\xdd\x24\x33\xae\x55\xb4\xd9\xd1\xb1\x27\xf3\xac\xab"
        "\x84\x81\x2c\xab\x96\x4a\xe7\x79\x64\x84\x31\x52\x0a\xb0\xdf\x2f\x08"
        "\x05\x68\xa4\x1c\xc8\xdf\x01\xc8\x6c\x28\x3e\xc3\xc4\x13\xa4\x93\xf4"
        "\x8d\x95\x6d\xca\x54\xc1\x64\xf6\xcf\x82\xef\xa9\x38\xe2\x2f\x19\x2d"
        "\x8b\x4b\x50\x2f\x69\x9e\xc3\x18\xc9\x33\x0f\x2b\xac\x89\xc3\x47\xd9"
        "\x0a\xde\x91\x11\xff\xd5\x1e\x94\xcf\xef\xaf\x84\xdf\x5f\x46\xe3\xf7"
        "\x5c\x60\x23\xcc\x63\xfe\xe7\xcd\xab\x59\xe5\xc7\xbe\x7e\x81\x34\xd0"
        "\x84\x2b\xca\x27\xd5\x7c\xba\xed\x20\xf1\x2f\x42\x54\xb1\x7d\xca\xc7"
        "\xfe\x23\xdb\xa1\x5a\x79\xb5\xb9\x4a\xbb\xdf\xf4\x3a\x4b\x3c\x8d\xaf"
        "\xb0\x36\xad\xf6\xb5\x39\x43\x53\xe8\xed\x4c\x4b\x0d\x42\x22\x21\x4c"
        "\xcd\x5f\x4c\x2b\x0d\xba\xdc\xd9\x13\x0a\x1e\x11\x05\xc8\xb6\xc5\x6c"
        "\xc0\x83\x47\x23\x27\xf7\x1d\x2a\x60\x13\xaa\x91\x13\x7e\x01\x40\x7d"
        "\xd4\x6d\x2f\xfa\x59\x8b\xbb\xc3\x1a\x5c\x0a\x05\x1e\xe5\x4a\x0f\x41"
        "\x97\x35\x5d\x1a\xab\x9a\x84\xfd\xe2\x65\x0a\xd6\x37\x73\xbe\x21\x4e"
        "\x48\x90\x50\x48\x9d\xab\x2f\x9e\x8f\x25\x60\x7a\xe9\x71\x87\xd7\xbd"
        "\xc0\x7b\x0a\x94\xa2\x6b\xd2\x59\x7d\xc1\x61\x49\xc1\x16\x6e\x1a\x17"
        "\xc9\x4c\x72\x24\x9d\x0b\x11\x4f\xa0\x27\x96\xb3\x3e\x83\xab\x3a\xf6"
        "\x6c\xae\xb5\x95\x58\x03\x58\x71\x75\xd2\xd6\xab\x88\x4b\x55\x29\x0c"
        "\x36\xc2\xcd\x98\x60\x7d\xc8\x8f\xca\x0e\xcb\xe2\xa8\xb2\x27\x6a\x92"
        "\x15\xb3\xd4\xa5\xea\x40\x7a\x80\x3d\xcb\x25\xdf\x4f\xe6\x70\xf9\xd5"
        "\x28\x11\x59\x55\x2f\xa4\x9b\x4a\x4d\xb5\x4d\x21\x4b\xe1\x31\x0e\x5f"
        "\x0d\xdd\xfa\x33\x56\x86\x85\xd1\x07\x7c\x0f\xfb\xf5\x03\xc3\xb9\x2b"
        "\x6c\xa4\x9a\x02\xe1\x30\xe9\x46\x96\x25\x2b\x03\x7c\xa8\xc5\x85\xbf"
        "\x87\xd6\xe4\x09\x78\xf6\x97\xe7\x2b\x4a\x8b\x67\x6f\x93\x78\xd8\x3a"
        "\x6b\x3d\xc5\x86\x76\x1c\x1b\x43\xd5\x18\xb7\x95\xe8\x46\x99\x47\x2c"
        "\xf9\x11\x94\x5e\xb5\x7b\xba\xa4\xc4\x58\x92\x13\x4e\x15\x91\xcb\x16"
        "\xd2\x76\xae\x04\x6f\x4c\x31\x99\x1c\x70\x60\x41\x4e\xc0\x51\x5f\xe3"
        "\xd4\x45\x75\x9e\x0a\xaa\x5b\xec\x8c\x20\xa5\x4d\xd8\x58\xc3\x94\x49"
        "\x97\x42\x40\xd7\x63\x31\x55\x63\x6d\x7e\x1c\xe0\xab\x7d\x5d\xee\x1e"
        "\xd9\x2f\xa9\x4a\x1c\x67\xf5\xea\x77\x92\xdf\x96\xa3\x57\x50\x49\x96"
        "\xb0\x08\x9a\x4e\xc3\x45\x2f\x24\xac\x9d\x6c\x31\xa2\x78\x36\x97\xcc"
        "\xf9\x6d\x48\x5a\x1f\x1e\x1b\x24\xd6\xbf\x75\x0a\x8e\x45\x0b\xdf\x3c"
        "\x9e\x46\xe5\x06\x50\xa9\x80\x75\xc3\x09\x4d\xfb\x9f\xff\x36\x3c\xbe"
        "\x3f\xdd\x8d\x05\xa9\xf4\x13\xea\x55\x6c\xe7\xd7\xf9\xcf\xb8\xd9\x65"
        "\x75\xbb\x1a\x26\x9c\xae\xc9\x86\x45\x2f\xc6\xaa\x36\x3c\x50\x00\xc1"
        "\x45\x13\x82\x72\x87\x9c\xa8\x10\x74\x01\x5f\x55\x9e\x84\x11\x49\xd6"
        "\xf9\x5b\xbf\xae\x0a\x08\x75\x4c\x72\x40\x62\xf9\xa5\xcc\x0d\xdc\xa4"
        "\xa9\xf4\x56\x5f\xb8\x88\xd9\x90\x81\xe7\xac\x17\x00\x5d\xa8\xdf\x81"
        "\x0b\x6e\x6c\x06\x2b\x1f\xf3\xad\x5a\x3b\xb8\x1f\x91\x11\x16\x8f\xda"
        "\x80\xec\xcc\xb4\x8c\x68\xa0\xd0\xca\x5b\x63\xb9\xf3\xbb\xe3\xa7\x42"
        "\xd8\x2f\x55\x8f\xba\x86\x47\xc8\xcd\x99\x5f\x91\x9f\xc6\xd8\xab\x46"
        "\x02\x18\xa5\x63\x4e\x65\xff\x9a\x04\x0b\x3b\x89\x70\xae\x38\x5d\x2f"
        "\x15\xba\x43\x5a\x5e\x55\x14\xf0\x17\x9e\xa4\x30\xc6\x7a\x8b\x79\x34"
        "\x5f\x8e\x33\x96\x90\x39\xed\xb0\x9e\x0a\xeb\x6d\x4c\xfb\x34\x64\xee"
        "\xc2\x4c\xfb\x8a\x92\x42\x26\x8f\xaf\xa9\x0c\xcc\x91\xe2\x2b\x54\xa4"
        "\x58\x1c\x83\x92\x37\x69\xb2\x02\x2c\x99\xb3\x2b\x64\x03\xa3\x7b\x56"
        "\x50\x8d\xe2\xae\x58\xe2\x57\x34\xed\x62\x63\xd8\xf1\x25\xc0\x59\xbf"
        "\xc3\x16\x97\xa9\x6d\xca\xb0\x2f\xa2\xd8\x00\xf3\xde\xfc\x74\x06\x39"
        "\xc7\x59\x0a\x00\x63\x5b\xaf\x9f\x5a\x0e\x18\x8f\x92\xd4\x5d\x51\xe7"
        "\x59\xc4\xda\x6f\x6b\xb4\xca\x4a\x5e\x13\x8e\x36\x20\x8a\x1f\x00\x77"
        "\x10\xa4\x59\xaa\x4b\xfd\x29\xb2\xf8\xcd\x06\x84\x6a\xb1\x47\xe4\xa3"
        "\x2d\x17\x6d\xff\x33\xe8\xe5\x6a\x26\xe2\x1c\x76\x1f\xea\xf7\x36\xe6"
        "\xe2\x0a\xab\x60\xd6\xa0\xbb\xb4\xd0\x1e\x7a\x59\x66\x53\x82\xa2\x35"
        "\xa8\x01\x65\xcc\x32\x8e\x34\x61\xdb\xd7\x10\xb8\x4e\xc3\x2b\x41\x3f"
        "\xfe\xd4\xfe\x37\x15\xf6\x01\x9c\x5f\x81\xa5\x4b\x34\x44\xe5\xbb\x79"
        "\x1a\xfb\x6d\x0a\x7f\xb2\x47\xef\xb7\x3a\x54\x39\xe1\x04\x15\x38\xd6"
        "\xe6\x73\x79\xa2\x45\x07\xa7\x93\xa9\xfe\xa7\xbf\x9f\x7d\xc1\x0b\x02"
        "\xcc\x87\xe9\xad\xdf\x5e\x61\xf5\x9e\xc7\xc4\x67\xf6\x14\x49\x3a\x3e"
        "\x5f\xfe\x00\xda\x7f\x89\x58\x90\x99\xdc\x24\x64\xb8\x9d\x5e\x95\xf2"
        "\x2a\xf6\x76\x5f\xe0\x1b\xa1\x5c\x43\x17\xe2\x25\xd8\x89\xc1\xbb\xdb"
        "\x0b\xde\x90\xd1\xa3\x4a\xd8\x0e\xd6\x48\xf0\x38\xc5\xa2\x76\x89\x0a"
        "\x1f\x12\xc1\x48\xea\xc9\x7c\x01\x17\xbd\x65\xca\xfe\xdb\xb1\xa8\xea"
        "\xa3\x82\x27\xff\x1f\xb9\x23\xa5\xf5\x3f\xc1\x46\xad\x37\x9a\x5e\x64"
        "\x6a\x1f\x03\x24\xc9\x13\x17\x88\x88\x65\x6c\x49\x8a\x20\x3c\x4c\x69"
        "\x6a\x1c\xbc\x78\x7e\x80\x3c\x5b\x1c\xb8\xfc\x37\x68\xc2\x7e\xa7\x6e"
        "\x4f\x4e\xae\x52\x02\x4a\x4a\x6e\xa1\xae\x5d\x25\xe6\x29\x24\x6e\xc3"
        "\xbd\x3f\xc9\x05\x48\xb8\x2f\xcb\x2b\x2e\x65\xd3\x7d\xd8\xfa\xa1\x04"
        "\xc1\x49\x3c\x44\xbf\xa9\xf2\x74\xaf\x32\xc2\x58\x15\x65\xd0\xfd\x86"
        "\x90\x62\x80\x6e\x69\x24\x9c\x5b\xb4\x06\x5a\x39\x98\x43\xe1\x88\x4c"
        "\x29\xbb\xec\xba\x39\x19\x66\x2d\x30\x93\xb0\x75\x2d\x09\xdd\x52\xde"
        "\xee\xc7\x5a\x44\x66\xdb\xa0\x37\xd8\xb0\x82\x67\x90\x48\xc6\x57\x42"
        "\x16\xc3\x0b\xe1\x0b\xde\x07\xe6\x74\xc8\x83\x2b\x33\x3c\xc3\xc4\x42"
        "\xdf\x5b\xc0\xec\xe3\xa7\x01\x4d\x60\xb7\xdb\x4c\x68\x94\xd4\x21\xc3"
        "\x8a\xa6\x17\x6a\x94\x8b\x76\x61\x53\x46\xa6\x46\x72\x65\x80\x50\x65"
        "\x5d\x53\xab\x5b\x16\x37\xa9\xe9\xa1\xb0\x6c\xfe\xe5\xa4\x6a\x12\x22"
        "\x5a\xca\xc7\x41\xba\x44\xd4\x94\x18\x26\xbf\x25\xfd\x07\xde\x50\x75"
        "\x62\x53\xa7\x5d\x6a\x03\xdc\x78\xd5\xae\xf4\x37\x3a\xde\x48\xd9\xd7"
        "\x6f\x1f\xad\xc5\x53\x25\x53\xec\xb0\x4f\x1a\x94\xdf\xb8\x1f\x0b\x07"
        "\x3f\xb7\x73\x3e\x9d\xc3\xe9\xea\x1f\x81\xb8\xf5\xa6\x3b\x6a\x31\xef"
        "\x9e\x57\xcf\xa1\x2e\xb5\x80\x63\x84\xbc\xca\x5b\x0c\xd6\x1c\xc7\xde"
        "\xac\x91\xac\x6b\x21\x8a\x4c\xcd\x3d\x47\x0c\xa1\x8f\x85\x45\x10\xdf"
        "\xd7\x01\x51\xda\xec\xb5\x76\xae\x71\x45\x29\xb4\x76\x74\x0b\xd3\xc6"
        "\xa6\x14\x74\xb6\x68\xac\x90\x20\xf1\xeb\x88",
        4040);
    syscall(__NR_ioctl, -1, 0x50009417, 0x20001940ul);
    break;
  case 4:
    syscall(__NR_ioctl, r[0], 0x9208, 6ul);
    break;
  }
}
int main(void)
{
  syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
  syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  setup_sysctl();
  for (procid = 0; procid < 6; procid++) {
    if (fork() == 0) {
      loop();
    }
  }
  sleep(1000000);
  return 0;
}