text: // WARNING in refcount_inc (2)
  // https://syzkaller.appspot.com/bug?id=1e6a79c578a129a99e6b7cc2c00004bc64f598f0
  // status:invalid
  // autogenerated by syzkaller (http://github.com/google/syzkaller)
  
  #define _GNU_SOURCE
  #include <dirent.h>
  #include <endian.h>
  #include <errno.h>
  #include <signal.h>
  #include <stdarg.h>
  #include <stdio.h>
  #include <sys/mount.h>
  #include <sys/prctl.h>
  #include <sys/syscall.h>
  #include <sys/time.h>
  #include <sys/wait.h>
  #include <time.h>
  #include <unistd.h>
  
  __attribute__((noreturn)) static void doexit(int status)
  {
    volatile unsigned i;
    syscall(__NR_exit_group, status);
    for (i = 0;; i++) {
    }
  }
  #include <errno.h>
  #include <stdarg.h>
  #include <stdint.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/stat.h>
  
  const int kFailStatus = 67;
  const int kRetryStatus = 69;
  
  static void fail(const char* msg, ...)
  {
    int e = errno;
    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 exitf(const char* msg, ...)
  {
    int e = errno;
    va_list args;
    va_start(args, msg);
    vfprintf(stderr, msg, args);
    va_end(args);
    fprintf(stderr, " (errno %d)\n", e);
    doexit(kRetryStatus);
  }
  
  #define BITMASK_LEN(type, bf_len) (type)((1ull << (bf_len)) - 1)
  
  #define BITMASK_LEN_OFF(type, bf_off, bf_len)                                  \
    (type)(BITMASK_LEN(type, (bf_len)) << (bf_off))
  
  #define STORE_BY_BITMASK(type, addr, val, bf_off, bf_len)                      \
    if ((bf_off) == 0 && (bf_len) == 0) {                                        \
      *(type*)(addr) = (type)(val);                                              \
    } else {                                                                     \
      type new_val = *(type*)(addr);                                             \
      new_val &= ~BITMASK_LEN_OFF(type, (bf_off), (bf_len));                     \
      new_val |= ((type)(val)&BITMASK_LEN(type, (bf_len))) << (bf_off);          \
      *(type*)(addr) = new_val;                                                  \
    }
  
  struct csum_inet {
    uint32_t acc;
  };
  
  static void csum_inet_init(struct csum_inet* csum)
  {
    csum->acc = 0;
  }
  
  static void csum_inet_update(struct csum_inet* csum, const uint8_t* data,
                               size_t length)
  {
    if (length == 0)
      return;
  
    size_t i;
    for (i = 0; i < length - 1; i += 2)
      csum->acc += *(uint16_t*)&data[i];
  
    if (length & 1)
      csum->acc += (uint16_t)data[length - 1];
  
    while (csum->acc > 0xffff)
      csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16);
  }
  
  static uint16_t csum_inet_digest(struct csum_inet* csum)
  {
    return ~csum->acc;
  }
  
  static uint64_t current_time_ms()
  {
    struct timespec ts;
  
    if (clock_gettime(CLOCK_MONOTONIC, &ts))
      fail("clock_gettime failed");
    return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
  }
  
  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");
  }
  
  static void remove_dir(const char* dir)
  {
    DIR* dp;
    struct dirent* ep;
    int iter = 0;
  retry:
    dp = opendir(dir);
    if (dp == NULL) {
      if (errno == EMFILE) {
        exitf("opendir(%s) failed due to NOFILE, exiting", dir);
      }
      exitf("opendir(%s) failed", dir);
    }
    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);
      struct stat st;
      if (lstat(filename, &st))
        exitf("lstat(%s) failed", filename);
      if (S_ISDIR(st.st_mode)) {
        remove_dir(filename);
        continue;
      }
      int i;
      for (i = 0;; i++) {
        if (unlink(filename) == 0)
          break;
        if (errno == EROFS) {
          break;
        }
        if (errno != EBUSY || i > 100)
          exitf("unlink(%s) failed", filename);
        if (umount2(filename, MNT_DETACH))
          exitf("umount(%s) failed", filename);
      }
    }
    closedir(dp);
    int i;
    for (i = 0;; i++) {
      if (rmdir(dir) == 0)
        break;
      if (i < 100) {
        if (errno == EROFS) {
          break;
        }
        if (errno == EBUSY) {
          if (umount2(dir, MNT_DETACH))
            exitf("umount(%s) failed", dir);
          continue;
        }
        if (errno == ENOTEMPTY) {
          if (iter < 100) {
            iter++;
            goto retry;
          }
        }
      }
      exitf("rmdir(%s) failed", dir);
    }
  }
  
  static void test();
  
  void loop()
  {
    int iter;
    for (iter = 0;; iter++) {
      char cwdbuf[256];
      sprintf(cwdbuf, "./%d", iter);
      if (mkdir(cwdbuf, 0777))
        fail("failed to mkdir");
      int pid = fork();
      if (pid < 0)
        fail("loop fork failed");
      if (pid == 0) {
        prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
        setpgrp();
        if (chdir(cwdbuf))
          fail("failed to chdir");
        test();
        doexit(0);
      }
      int status = 0;
      uint64_t start = current_time_ms();
      for (;;) {
        int res = waitpid(-1, &status, __WALL | WNOHANG);
        if (res == pid)
          break;
        usleep(1000);
        if (current_time_ms() - start > 5 * 1000) {
          kill(-pid, SIGKILL);
          kill(pid, SIGKILL);
          while (waitpid(-1, &status, __WALL) != pid) {
          }
          break;
        }
      }
      remove_dir(cwdbuf);
    }
  }
  
  #ifndef __NR_socket
  #define __NR_socket 359
  #endif
  #ifndef __NR_connect
  #define __NR_connect 362
  #endif
  #ifndef __NR_setsockopt
  #define __NR_setsockopt 366
  #endif
  #ifndef __NR_mmap
  #define __NR_mmap 192
  #endif
  #undef __NR_mmap
  #define __NR_mmap __NR_mmap2
  
  long r[2];
  void test()
  {
    memset(r, -1, sizeof(r));
    syscall(__NR_mmap, 0x20000000, 0xfff000, 3, 0x32, -1, 0);
    r[0] = syscall(__NR_socket, 0xa, 2, 0);
    *(uint16_t*)0x20e6f000 = 0xa;
    *(uint16_t*)0x20e6f002 = htobe16(0x4e22);
    *(uint32_t*)0x20e6f004 = 0;
    *(uint8_t*)0x20e6f008 = 0;
    *(uint8_t*)0x20e6f009 = 0;
    *(uint8_t*)0x20e6f00a = 0;
    *(uint8_t*)0x20e6f00b = 0;
    *(uint8_t*)0x20e6f00c = 0;
    *(uint8_t*)0x20e6f00d = 0;
    *(uint8_t*)0x20e6f00e = 0;
    *(uint8_t*)0x20e6f00f = 0;
    *(uint8_t*)0x20e6f010 = 0;
    *(uint8_t*)0x20e6f011 = 0;
    *(uint8_t*)0x20e6f012 = -1;
    *(uint8_t*)0x20e6f013 = -1;
    *(uint8_t*)0x20e6f014 = 0xac;
    *(uint8_t*)0x20e6f015 = 0x14;
    *(uint8_t*)0x20e6f016 = 0;
    *(uint8_t*)0x20e6f017 = 0xaa;
    *(uint32_t*)0x20e6f018 = 1;
    syscall(__NR_connect, r[0], 0x20e6f000, 0x1c);
    r[1] = syscall(__NR_socket, 0x18, 1, 1);
    *(uint16_t*)0x205fafd2 = 0x18;
    *(uint32_t*)0x205fafd4 = 1;
    *(uint32_t*)0x205fafd8 = 0;
    *(uint32_t*)0x205fafdc = r[0];
    *(uint16_t*)0x205fafe0 = 2;
    *(uint16_t*)0x205fafe2 = htobe16(0x4e21);
    *(uint32_t*)0x205fafe4 = htobe32(0xe0000002);
    *(uint8_t*)0x205fafe8 = 0;
    *(uint8_t*)0x205fafe9 = 0;
    *(uint8_t*)0x205fafea = 0;
    *(uint8_t*)0x205fafeb = 0;
    *(uint8_t*)0x205fafec = 0;
    *(uint8_t*)0x205fafed = 0;
    *(uint8_t*)0x205fafee = 0;
    *(uint8_t*)0x205fafef = 0;
    *(uint32_t*)0x205faff0 = 4;
    *(uint32_t*)0x205faff4 = 0;
    *(uint32_t*)0x205faff8 = 2;
    *(uint32_t*)0x205faffc = 0;
    syscall(__NR_connect, r[1], 0x205fafd2, 0x2e);
    *(uint32_t*)0x20a5a000 = 2;
    syscall(__NR_setsockopt, r[0], 0x29, 1, 0x20a5a000, 4);
    *(uint8_t*)0x2018f000 = -1;
    *(uint8_t*)0x2018f001 = -1;
    *(uint8_t*)0x2018f002 = -1;
    *(uint8_t*)0x2018f003 = -1;
    *(uint8_t*)0x2018f004 = -1;
    *(uint8_t*)0x2018f005 = -1;
    *(uint8_t*)0x2018f006 = 0;
    *(uint8_t*)0x2018f007 = 0;
    *(uint8_t*)0x2018f008 = 0x14;
    *(uint8_t*)0x2018f009 = 0;
    *(uint8_t*)0x2018f00a = 0;
    *(uint8_t*)0x2018f00b = 0;
    *(uint16_t*)0x2018f00c = htobe16(0x800);
    STORE_BY_BITMASK(uint8_t, 0x2018f00e, 5, 0, 4);
    STORE_BY_BITMASK(uint8_t, 0x2018f00e, 4, 4, 4);
    STORE_BY_BITMASK(uint8_t, 0x2018f00f, 0, 0, 2);
    STORE_BY_BITMASK(uint8_t, 0x2018f00f, 0, 2, 6);
    *(uint16_t*)0x2018f010 = htobe16(0x24);
    *(uint16_t*)0x2018f012 = 0;
    *(uint16_t*)0x2018f014 = htobe16(0);
    *(uint8_t*)0x2018f016 = 0;
    *(uint8_t*)0x2018f017 = 0x11;
    *(uint16_t*)0x2018f018 = 0;
    *(uint8_t*)0x2018f01a = 0xac;
    *(uint8_t*)0x2018f01b = 0x14;
    *(uint8_t*)0x2018f01c = 0;
    *(uint8_t*)0x2018f01d = 0xbb;
    *(uint32_t*)0x2018f01e = htobe32(0xe0000001);
    *(uint16_t*)0x2018f022 = 0;
    *(uint16_t*)0x2018f024 = htobe16(0x4e21);
    *(uint8_t*)0x2018f026 = 4;
    STORE_BY_BITMASK(uint8_t, 0x2018f027, 1, 0, 4);
    STORE_BY_BITMASK(uint8_t, 0x2018f027, 0, 4, 4);
    *(uint16_t*)0x2018f028 = 0;
    STORE_BY_BITMASK(uint8_t, 0x2018f02a, 0, 0, 1);
    STORE_BY_BITMASK(uint8_t, 0x2018f02a, 0, 1, 4);
    STORE_BY_BITMASK(uint8_t, 0x2018f02a, 0, 5, 3);
    memcpy((void*)0x2018f02b, "\xd7\x3c\xde", 3);
    *(uint8_t*)0x2018f02e = 0;
    memcpy((void*)0x2018f02f, "\xf5\x34\x75", 3);
    struct csum_inet csum_1;
    csum_inet_init(&csum_1);
    csum_inet_update(&csum_1, (const uint8_t*)0x2018f01a, 4);
    csum_inet_update(&csum_1, (const uint8_t*)0x2018f01e, 4);
    uint16_t csum_1_chunk_2 = 0x2100;
    csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2);
    uint16_t csum_1_chunk_3 = 0x1000;
    csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2);
    csum_inet_update(&csum_1, (const uint8_t*)0x2018f022, 16);
    *(uint16_t*)0x2018f028 = csum_inet_digest(&csum_1);
    struct csum_inet csum_2;
    csum_inet_init(&csum_2);
    csum_inet_update(&csum_2, (const uint8_t*)0x2018f00e, 20);
    *(uint16_t*)0x2018f018 = csum_inet_digest(&csum_2);
  }
  
  int main()
  {
    char* cwd = get_current_dir_name();
    for (;;) {
      if (chdir(cwd))
        fail("failed to chdir");
      use_temporary_dir();
      loop();
    }
  }
  