// https://syzkaller.appspot.com/bug?id=8cce7c2c0566b3a1bdb55c5b1026833a88cf8b0f
// 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>

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

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

#define KMEMLEAK_FILE "/sys/kernel/debug/kmemleak"

static void setup_leak()
{
  if (!write_file(KMEMLEAK_FILE, "scan"))
    exit(1);
  sleep(5);
  if (!write_file(KMEMLEAK_FILE, "scan"))
    exit(1);
  if (!write_file(KMEMLEAK_FILE, "clear"))
    exit(1);
}

static void check_leaks(void)
{
  int fd = open(KMEMLEAK_FILE, O_RDWR);
  if (fd == -1)
    exit(1);
  uint64_t start = current_time_ms();
  if (write(fd, "scan", 4) != 4)
    exit(1);
  sleep(1);
  while (current_time_ms() - start < 4 * 1000)
    sleep(1);
  if (write(fd, "scan", 4) != 4)
    exit(1);
  static char buf[128 << 10];
  ssize_t n = read(fd, buf, sizeof(buf) - 1);
  if (n < 0)
    exit(1);
  int nleaks = 0;
  if (n != 0) {
    sleep(1);
    if (write(fd, "scan", 4) != 4)
      exit(1);
    if (lseek(fd, 0, SEEK_SET) < 0)
      exit(1);
    n = read(fd, buf, sizeof(buf) - 1);
    if (n < 0)
      exit(1);
    buf[n] = 0;
    char* pos = buf;
    char* end = buf + n;
    while (pos < end) {
      char* next = strstr(pos + 1, "unreferenced object");
      if (!next)
        next = end;
      char prev = *next;
      *next = 0;
      fprintf(stderr, "BUG: memory leak\n%s\n", pos);
      *next = prev;
      pos = next;
      nleaks++;
    }
  }
  if (write(fd, "clear", 5) != 5)
    exit(1);
  close(fd);
  if (nleaks)
    exit(1);
}

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

uint64_t r[1] = {0xffffffffffffffff};

void execute_one(void)
{
  intptr_t res = 0;
  res = syscall(__NR_socket, 0xa, 0x80003, 0x2c);
  if (res != -1)
    r[0] = res;
  *(uint16_t*)0x20000040 = 0xa;
  *(uint16_t*)0x20000042 = htobe16(0);
  *(uint32_t*)0x20000044 = htobe32(0);
  *(uint8_t*)0x20000048 = 0xfe;
  *(uint8_t*)0x20000049 = 0x80;
  *(uint8_t*)0x2000004a = 0;
  *(uint8_t*)0x2000004b = 0;
  *(uint8_t*)0x2000004c = 0;
  *(uint8_t*)0x2000004d = 0;
  *(uint8_t*)0x2000004e = 0;
  *(uint8_t*)0x2000004f = 0;
  *(uint8_t*)0x20000050 = 0;
  *(uint8_t*)0x20000051 = 0;
  *(uint8_t*)0x20000052 = 0;
  *(uint8_t*)0x20000053 = 0;
  *(uint8_t*)0x20000054 = 0;
  *(uint8_t*)0x20000055 = 0;
  *(uint8_t*)0x20000056 = 0;
  *(uint8_t*)0x20000057 = 0xaa;
  *(uint32_t*)0x20000058 = 7;
  syscall(__NR_connect, r[0], 0x20000040, 0x1c);
  *(uint64_t*)0x20000c40 = 0;
  *(uint32_t*)0x20000c48 = 0;
  *(uint64_t*)0x20000c50 = 0x20000000;
  *(uint64_t*)0x20000000 = 0x20000c80;
  memcpy(
      (void*)0x20000c80,
      "\x66\x16\xea\xf1\xe0\x2d\xee\x09\x5d\x4c\x8a\x42\x11\x5f\x90\x76\xf2\xe7"
      "\x3d\xce\x3f\xb3\x8a\x92\xa7\x29\xb7\x27\x26\xaa\xae\x23\x46\xb9\x92\x66"
      "\x38\x70\x06\xd3\xf1\xb8\x32\x33\xa7\x22\x35\x64\xc3\x67\xb8\xa9\x41\x3e"
      "\x61\xd8\x3e\xfb\x0d\x1c\xb4\x35\x51\xe1\xf4\x65\x4d\xb8\x08\x02\x76\xf6"
      "\x29\x1d\x06\xbc\x48\x25\x07\xc5\x23\x3d\x0e\x5a\x00\xbb\x0e\x62\x48\xc7"
      "\x42\xcb\x86\x72\xa7\xbc\x88\x68\x8f\x4d\xc1\xe6\x9e\x5d\x41\x85\xb3\xe0"
      "\xca\x27\xe6\xe1\x5a\xb5\x1e\x8c\xba\xb7\x97\xef\x90\x1b\x4f\xa4\x1c\x70"
      "\xff\xad\xde\x3a\xe3\xc5\x8d\x72\x43\xc8\xa8\x74\x35\x71\x92\x83\x60\xb7"
      "\x6c\x5f\xc2\x35\xed\x1e\x9f\xd6\x6c\xf8\x8c\xa2\xff\x9a\x39\xfb\x3f\x49"
      "\x25\x38\x77\x09\xaf\x3c\xee\xaa\x13\xe2\x28\xc1\x5b\x20\x6d\x54\x31\xfe"
      "\x76\x05\x9e\x9d\x03\x1e\xab\x80\x94\x7e\x4f\x6c\xe6\xdf\x5a\xf2\xd0\xd8"
      "\x59\x55\x9b\x57\xbd\x86\xa1\xf2\x5a\xbb\x22\x91\xc3\xc9\x0e\xe0\x34\x86"
      "\x40\xcf\xd3\xd0\xf3\x4a\x38\x5e\xcc\xa1\x7d\xe6\x28\x06\x1c\x09\x79\x44"
      "\x35\x62\x9a\xf7\x6d\xbb\xa6\xdd\xaf\x03\x20\xeb\x74\x80\xc2\xd8\x81\x0a"
      "\x50\xc2\x97\x18\xf5\xcc\xaa\x58\xa2\xcf\x1b\x4f\xd6\x1e\x45\xbe\x0a\x88"
      "\x21\x32\xa5\x39\xdf\xb7\x9f\x1a\xd6\xe4\xba\xf2\x86\xda\x91\xfd\xd9\x49"
      "\xd1\x3d\x48\xdb\x75\x6c\x76\x39\xe3\xb5\x4c\xc7\x0c\xf5\xcb\xb6\xeb\xe3"
      "\x14\xda\x00\x7d\x6e\x24\x66\xb7\xd7\x00\xf7\xb6\xd5\x35\x72\x6d\x9c\xd6"
      "\xca\x5c\x5c\xc7\x8a\x44\xf7\x01\xe5\x39\xcb\xe6\xfc\x1e\x48\xf1\xba\x6e"
      "\x04\x4f\xf1\xbd\x1a\x96\xa4\xc7\x1b\xd9\x31\xf9\x2a\xa3\x35\x9e\x3a\x77"
      "\x82\x56\xaa\xfb\xd5\x53\x01\x2f\x4f\xcf\x23\x67\xc0\xc6\x1b\x1b\x4d\x22"
      "\x91\x4a\x4e\x46\x70\x3c\xff\xd9\x1e\x39\x05\xd1\x91\x5c\xa2\xd9\xf1\x0b"
      "\x52\xf2\x1d\x4b\x5f\x4a\x2b\xba\x39\xe8\xe4\xc5\x62\x88\xf1\xc2\x54\xd3"
      "\x7e\xd6\x2f\xb5\xaa\x3e\xc8\x10\xd2\x0f\x60\x42\x26\x86\xdf\xc0\x80\x34"
      "\x6e\x4d\xaa\x90\xfc\x2a\x33\x05\xce\xad\xd8\xf7\xeb\xbd\x42\xa3\xda\xb4"
      "\xbe\x32\xf3\xc7\x27\x30\x43\xbd\xfa\x1b\x82\xa6\x71\x73\xf8\x92\x18\x0d"
      "\x68\xb1\x9c\xf9\x83\xbf\x14\x8a\x27\xe2\x02\x51\xe7\x16\x24\xe1\x31\xf2"
      "\xf1\x89\x92\x93\x89\x7a\xc0\x10\xa9\x1c\xe4\x11\x60\x35\xcf\x8b\x0f\x8f"
      "\xea\x64\x94\x74\xc7\x3e\x7a\x05\x76\x8c\x18\x99\x69\x41\x49\xb6\xf3\x1f"
      "\xd5\xfa\xe5\x6c\xe0\xb7\xd7\x2b\x5c\x9c\x81\xf8\x11\xe4\x30\x96\x9f\xf0"
      "\x46\xc1\xb9\xfd\x74\x8b\xd6\x9b\x80\x72\x7e\x9f\x5c\xe0\x14\xc9\x34\x24"
      "\xa7\xaa\xd8\x1f\x1f\x22\x55\x6f\xbd\x13\xdc\xcd\x5d\xf8\x4d\x8e\x97\x2a"
      "\xeb\x7c\x2c\xe0\x72\x0b\x8a\x60\x5b\xb0\xe1\x8e\x08\x25\x62\xa7\x79\x17"
      "\x4d\x53\xcb\xe0\x96\x08\xbd\x6b\x33\xb0\xc3\x00\x43\x31\xfd\xe6\x10\x29"
      "\x1e\xa9\x77\x61\x9b\x7b\xff\x2b\xf5\x34\x3e\x0e\xc1\x6f\xc7\x6a\x56\xc0"
      "\x30\xe1\xa1\x3a\x7e\xd1\xa6\x83\x77\x47\xe8\xe1\x35\x5c\xd8\xc7\x99\x0c"
      "\xd4\x80\x56\x39\x6d\x84\xaa\x33\xa3\xb7\x83\x5f\x78\x67\xa9\xd0\x57\xaf"
      "\xf5\xa6\x41\xa3\xd4\x12\xb1\xac\x03\x34\xbd\xb0\xdf\x0d\xe2\x69\x45\x3a"
      "\xe8\x5c\x98\xa2\x14\x3e\x10\xab\xfa\xd6\x73\x1b\xd7\xa3\x0e\xac\xf8\x87"
      "\x7d\x09\x9d\xfd\x9a\x6b\x76\x9a\x87\x75\x8b\x81\x8e\xa2\x1e\xd1\x9e\x9c"
      "\x58\xf9\x41\x78\xe9\x8a\xb7\xb8\x4b\x92\x61\x16\x8b\x82\x54\x50\xad\xdb"
      "\x57\xa6\x80\xac\x7a\x45\x6d\xb8\x30\xa6\x0e\x88\x99\x6f\xb0\xaa\x4c\x11"
      "\xff\xd0\xc9\x5d\x82\x1e\x35\x89\x15\xf9\x0c\xe8\x66\x0a\x4a\xd7\x3f\x7e"
      "\xc7\xfd\x3a\xfd\x46\xbc\x36\x22\x5f\xe7\x5a\xa8\x8a\x8f\x9f\x07\xdf\x4c"
      "\xd5\x9e\xa0\x6a\x78\x35\xd9\xc7\x97\x32\x1e\x2d\x74\xdb\x4e\xad\x3b\xee"
      "\x1d\x40\xe2\xa0\x7c\xdc\x8e\x38\x54\xe4\x7c\xb4\xf9\xbf\x6e\x2f\xb0\x07"
      "\x14\x6d\x83\x74\x4c\x55\x05\x47\x29\x72\x79\x36\x58\x12\x2f\xf8\xf0\xba"
      "\x4a\x3d\x08\x9a\x7f\x4d\xcc\xe7\x8b\x4d\x39\xdd\xbb\x32\x50\xa0\x3d\x58"
      "\x74\x24\x70\xef\x22\xe7\x30\x6d\x27\x02\x29\x3e\x38\xe4\x32\xe9\x6b\xdc"
      "\x9e\xaf\x44\xf4\x8e\x31\x54\x22\x55\x91\x29\xcf\x7d\x10\x4b\x0a\x4b\x3d"
      "\xd6\xcc\xf9\x14\x97\xed\x01\x8a\xc6\x71\x3a\x62\x2a\xfd\xbc\x35\xd9\x46"
      "\xec\xff\xc3\xac\x80\x4d\xef\x42\xb9\x1c\xa1\x40\x8e\x4e\xbb\xd5\x2f\x34"
      "\x14\x4e\xb1\xda\xdf\x0c\x89\xd1\x31\xf9\x9e\xbe\xa2\xc2\xff\xd0\xcb\xfd"
      "\xff\xe9\x02\x03\x35\xca\x9b\x3f\xe1\x46\x49\x34\x4e\xf5\x71\x81\x9f\xe3"
      "\x00\xfa\xb7\xcc\xd8\xc1\x65\x5b\x31\x92\xb6\xd5\x97\x1c\xcc\xdd\xe8\x8e"
      "\x0d\x9d\x76\x76\x33\x46\x4a\x7b\xe6\x59\x91\x3d\x9e\xb4\x09\xa9\xcd\xb3"
      "\x9b\xd9\x96\x91\x8e\x64\x72\xdd\xcd\x5e\x7b\x85\x7a\x8c\x5e\xc9\x24\x5a"
      "\xe9\x15\x22\xd2\xe0\x29\xa0\xa8\xa4\x14\x4a\x96\x2e\x7a\x35\x10\x9a\x47"
      "\x02\x73\x84\x95\xab\x12\xf4\x32\x79\x78\xc5\x39\x9b\x18\xda\x7d\x56\xc7"
      "\x37\x22\x0a\xcf\xb9\x23\x11\xea\xa8\xd1\x59\xb0\x3f\x87\xde\x11\xd4\xd1"
      "\x6c\x4f\x79\x44\x23\xe5\xf2\x64\xf3\xb2\x19\x86\xd7\x6e\x3e\x8b\x52\xf8"
      "\xaa\x71\x18\xbd\x8a\x68\x86\xac\x8b\xd4\xd2\x38\x01\x63\x9a\xed\x87\xf6"
      "\x36\x6a\xbf\xc1\xca\x21\x34\xe8\x8e\x15\x9d\x7e\x6d\x0e\xd7\xa0\x9e\x30"
      "\x58\x15\x83\xd0\xc0\xf2\xe8\x34\xcb\x61\x03\xc6\xf3\x70\xff\xf2\xe1\xa7"
      "\x74\x41\x78\x1e\x22\xc3\x94\xea\x11\x69\xec\x8a\xb5\xd1\x7a\x56\x2f\x6a"
      "\x2c\xa1\xad\x93\xe0\xd6\xe1\xf5\xe5\x4f\x19\x5e\x9c\x25\xdf\x57\xde\x2e"
      "\x40\x64\xa7\x48\xaf\xa5\x3a\x89\x72\x51\xe9\x32\x34\xee\x93\x5a\x2e\x52"
      "\xde\xec\xa0\x48\xff\x75\xda\x22\x3e\x86\xb7\x41\x23\xbc\x67\x19\x23\x9b"
      "\x4c\xcb\x29\xf5\x1d\x40\x11\xf7\x39\x63\xa9\x37\x06\x7a\x16\xef",
      1240);
  *(uint64_t*)0x20000008 = 0x4d8;
  *(uint64_t*)0x20000c58 = 1;
  *(uint64_t*)0x20000c60 = 0;
  *(uint64_t*)0x20000c68 = 0;
  *(uint32_t*)0x20000c70 = 0;
  *(uint32_t*)0x20000c78 = 0;
  syscall(__NR_sendmmsg, r[0], 0x20000c40, 1, 0);
}
int main(void)
{
  syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0);
  setup_leak();
  for (procid = 0; procid < 8; procid++) {
    if (fork() == 0) {
      loop();
    }
  }
  sleep(1000000);
  return 0;
}