text: // kernel BUG at fs/f2fs/node.c:LINE!
  // https://syzkaller.appspot.com/bug?id=255273ac0964bf0423f2
  // status:0
  // autogenerated by syzkaller (https://github.com/google/syzkaller)
  
  #define _GNU_SOURCE
  
  #include <endian.h>
  #include <errno.h>
  #include <fcntl.h>
  #include <stddef.h>
  #include <stdint.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/ioctl.h>
  #include <sys/mount.h>
  #include <sys/stat.h>
  #include <sys/syscall.h>
  #include <sys/types.h>
  #include <unistd.h>
  
  #include <linux/loop.h>
  
  static unsigned long long procid;
  
  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,
                                              struct fs_image_segment* segs)
  {
    if (nsegs > IMAGE_MAX_SEGMENTS)
      nsegs = IMAGE_MAX_SEGMENTS;
    for (size_t 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 int setup_loop_device(long unsigned size, long unsigned nsegs,
                               struct fs_image_segment* segs,
                               const char* loopname, int* memfd_p, int* loopfd_p)
  {
    int err = 0, loopfd = -1;
    size = fs_image_segment_check(size, nsegs, segs);
    int memfd = syscall(sys_memfd_create, "syzkaller", 0);
    if (memfd == -1) {
      err = errno;
      goto error;
    }
    if (ftruncate(memfd, size)) {
      err = errno;
      goto error_close_memfd;
    }
    for (size_t i = 0; i < nsegs; i++) {
      if (pwrite(memfd, segs[i].data, segs[i].size, segs[i].offset) < 0) {
      }
    }
    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;
      }
    }
    *memfd_p = memfd;
    *loopfd_p = loopfd;
    return 0;
  
  error_close_loop:
    close(loopfd);
  error_close_memfd:
    close(memfd);
  error:
    errno = err;
    return -1;
  }
  
  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)
  {
    struct fs_image_segment* segs = (struct fs_image_segment*)segments;
    int res = -1, err = 0, loopfd = -1, memfd = -1, need_loop_device = !!segs;
    char* mount_opts = (char*)optsarg;
    char* target = (char*)dir;
    char* fs = (char*)fsarg;
    char* source = NULL;
    char loopname[64];
    if (need_loop_device) {
      memset(loopname, 0, sizeof(loopname));
      snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid);
      if (setup_loop_device(size, nsegs, segs, loopname, &memfd, &loopfd) == -1)
        return -1;
      source = loopname;
    }
    mkdir(target, 0777);
    char opts[256];
    memset(opts, 0, sizeof(opts));
    if (strlen(mount_opts) > (sizeof(opts) - 32)) {
    }
    strncpy(opts, mount_opts, 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");
    }
    res = mount(source, target, fs, flags, opts);
    if (res == -1) {
      err = errno;
      goto error_clear_loop;
    }
    res = open(target, O_RDONLY | O_DIRECTORY);
    if (res == -1) {
      err = errno;
    }
  
  error_clear_loop:
    if (need_loop_device) {
      ioctl(loopfd, LOOP_CLR_FD, 0);
      close(loopfd);
      close(memfd);
    }
    errno = err;
    return res;
  }
  
  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);
  
    memcpy((void*)0x20000000, "f2fs\000", 5);
    memcpy((void*)0x20000100, "./file0\000", 8);
    *(uint64_t*)0x20000200 = 0x20010000;
    memcpy((void*)0x20010000,
           "\x10\x20\xf5\xf2\x01\x00\x0b\x00\x09\x00\x00\x00\x03\x00\x00\x00\x0c"
           "\x00\x00\x00\x09\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00"
           "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x1f\x00\x00"
           "\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00"
           "\x18\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00"
           "\x0a\x00\x00\x00\x0e\x00\x00\x00\x10\x00\x00\x03\x00\x00\x00\x01\x00"
           "\x00\x00\x02",
           105);
    *(uint64_t*)0x20000208 = 0x69;
    *(uint64_t*)0x20000210 = 0x400;
    *(uint64_t*)0x20000218 = 0x20010a00;
    memcpy((void*)0x20010a00,
           "\x17\x97\xf9\x6f\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x02"
           "\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x10\x00\x00\x00\x12\x00"
           "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\xff\xff\xff"
           "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
           "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"
           "\x00\x00\x00\x0b\x00\x00\x00\x05\x00\x00\x00\xff\xff\xff\xff\xff\xff"
           "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00"
           "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x01\x00\x00"
           "\x06\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x04"
           "\x00\x00\x00\x40\x00\x00\x00\x40\x00\x00\x00\xfc\x0f",
           166);
    *(uint64_t*)0x20000220 = 0xa6;
    *(uint64_t*)0x20000228 = 0x200000;
    *(uint64_t*)0x20000230 = 0x20010b00;
    memcpy((void*)0x20010b00, "\x00\x00\x00\x00\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\xd8\x7d\x5a\x01\x00\x03\x00"
                              "\x00\x00\x00\x03\x00\x00\x00\x00\x10",
           45);
    *(uint64_t*)0x20000238 = 0x2d;
    *(uint64_t*)0x20000240 = 0x200fe0;
    *(uint64_t*)0x20000248 = 0x20010c00;
    memcpy((void*)0x20010c00, "\x00\x00\x00\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\x01\x0c\x80",
           36);
    *(uint64_t*)0x20000250 = 0x24;
    *(uint64_t*)0x20000258 = 0x2011e0;
    *(uint64_t*)0x20000260 = 0x20010d00;
    memcpy((void*)0x20010d00, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
           12);
    *(uint64_t*)0x20000268 = 0xc;
    *(uint64_t*)0x20000270 = 0x201240;
    *(uint64_t*)0x20000278 = 0x20010e00;
    memcpy((void*)0x20010e00, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                              "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                              "\x00\x02",
           26);
    *(uint64_t*)0x20000280 = 0x1a;
    *(uint64_t*)0x20000288 = 0x201280;
    *(uint64_t*)0x20000290 = 0x20010f00;
    memcpy((void*)0x20010f00, "\x00\x00\x00\x00\x00\x00\x00\x03", 8);
    *(uint64_t*)0x20000298 = 8;
    *(uint64_t*)0x200002a0 = 0x2012e0;
    *(uint64_t*)0x200002a8 = 0x20011000;
    memcpy((void*)0x20011000, "\000\000\000\000\000\000\000\000\000\000\000\000"
                              "\000\000\000\000\000\000\000\000\000\v",
           22);
    *(uint64_t*)0x200002b0 = 0x16;
    *(uint64_t*)0x200002b8 = 0x201320;
    *(uint64_t*)0x200002c0 = 0x20011100;
    memcpy((void*)0x20011100, "\x00\x00\x00\x05", 4);
    *(uint64_t*)0x200002c8 = 4;
    *(uint64_t*)0x200002d0 = 0x201380;
    *(uint64_t*)0x200002d8 = 0x20011600;
    memcpy((void*)0x20011600,
           "\x00\x00\x00\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\x00\x17\x97"
           "\xf9\x6f\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x02\x00\x00"
           "\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x10\x00\x00\x00\x12\x00\x00\x00"
           "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\xff\xff\xff\xff\xff"
           "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00"
           "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00"
           "\x00\x0b\x00\x00\x00\x05\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff"
           "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\x00"
           "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x01\x00\x00\x06\x00"
           "\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00"
           "\x00\x40\x00\x00\x00\x40\x00\x00\x00\xfc\x0f",
           198);
    *(uint64_t*)0x200002e0 = 0xc6;
    *(uint64_t*)0x200002e8 = 0x204fe0;
    *(uint64_t*)0x200002f0 = 0x20011700;
    memcpy((void*)0x20011700, "\x00\x00\x00\x00\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\xd8\x7d\x5a",
           32);
    *(uint64_t*)0x200002f8 = 0x20;
    *(uint64_t*)0x20000300 = 0x205fe0;
    *(uint64_t*)0x20000308 = 0;
    *(uint64_t*)0x20000310 = 0;
    *(uint64_t*)0x20000318 = 0x3ff000;
    *(uint64_t*)0x20000320 = 0;
    *(uint64_t*)0x20000328 = 0;
    *(uint64_t*)0x20000330 = 0x3ff040;
    *(uint64_t*)0x20000338 = 0x20000380;
    memcpy((void*)0x20000380, "\xed\x62\x00\x00\x5c\x00\x00\x00\x02\x00\x00\x00"
                              "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                              "\x00\x10",
           26);
    *(uint64_t*)0x20000340 = 0x1a;
    *(uint64_t*)0x20000348 = 0x1000000;
    *(uint64_t*)0x20000350 = 0x20012100;
    memcpy((void*)0x20012100,
           "\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03", 13);
    *(uint64_t*)0x20000358 = 0xd;
    *(uint64_t*)0x20000360 = 0x1000fe0;
    *(uint8_t*)0x20000040 = 0;
    syz_mount_image(0x20000000, 0x20000100, 0, 0xf, 0x20000200, 0, 0x20000040);
    return 0;
  }
  