Re: [syzbot] [block?] possible deadlock in blkdev_put (4)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2023-10-16 at 14:55 -0700, syzbot wrote:
> Hello,
> 
> syzbot found the following issue on:
> 
> HEAD commit:    401644852d0b Merge tag 'fs_for_v6.6-rc6' of git://git.kern..
> git tree:       upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=1516d9c1680000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=1531f6ad09decf37
> dashboard link: https://syzkaller.appspot.com/bug?extid=0c538bd7f64c3c6e9a3c
> compiler:       gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for
> Debian) 2.40
> 
> Unfortunately, I don't have any reproducer for this issue yet.

Dear all,

For some experimentation, I have been running fuzzing campaigns and I
noticed the same possible deadlock in blkdev_put as well.

As I found a C reproducer in my setup, it could be bisected being introduced
with the following merge:

commit 511fb5bafed197ff76d9adf5448de67f1d0558ae
Merge: de16588a7737 cd4284cfd3e1
Author: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Date:   Mon Aug 28 11:04:18 2023 -0700

    Merge tag 'v6.6-vfs.super' of
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
    
    Pull superblock updates from Christian Brauner:
     "This contains the super rework that was ready for this cycle. The
      first part changes the order of how we open block devices and allocate
      superblocks, contains various cleanups, simplifications, and a new
      mechanism to wait on superblock state changes.
...


It was reproducible on v6.6.16. The C reproducer is automatically generated by
syzkaller and included below.

If you need any further information, just let me know.

Best,
Simone

Sample Crash
------------
loop503808: rw=0, sector=2, nr_sectors = 2 limit=0
EXT4-fs (loop0): couldn't read superblock of external journal
======================================================
WARNING: possible circular locking dependency detected
6.6.16-eb-corbos-standard-syzkaller-geb3e299184cc #0 Not tainted
------------------------------------------------------
syz-executor244/1037 is trying to acquire lock:
ffff00000b0254c8 (&disk->open_mutex){+.+.}-{3:3}, at: blkdev_put+0xa8/0x748
block/bdev.c:886

but task is already holding lock:
ffff00000adce0e0 (&type->s_umount_key#24){++++}-{3:3}, at:
ext4_get_journal_blkdev fs/ext4/super.c:5862 [inline]
ffff00000adce0e0 (&type->s_umount_key#24){++++}-{3:3}, at: ext4_open_dev_journal
fs/ext4/super.c:5934 [inline]
ffff00000adce0e0 (&type->s_umount_key#24){++++}-{3:3}, at: ext4_load_journal
fs/ext4/super.c:5997 [inline]
ffff00000adce0e0 (&type->s_umount_key#24){++++}-{3:3}, at:
ext4_load_and_init_journal+0x7c8/0x230c fs/ext4/super.c:4907

which lock already depends on the new lock.


the existing dependency chain (in reverse order) is:

-> #2 (&type->s_umount_key#24){++++}-{3:3}:
       down_read+0xb4/0x334 kernel/locking/rwsem.c:1520
       __super_lock fs/super.c:58 [inline]
       super_lock+0x1fc/0x2fc fs/super.c:117
       super_lock_shared fs/super.c:146 [inline]
       super_lock_shared_active fs/super.c:1431 [inline]
       fs_bdev_mark_dead+0x8c/0x1fc fs/super.c:1447
       bdev_mark_dead+0x88/0x1e4 block/bdev.c:965
       disk_force_media_change+0x50/0xbc block/disk-events.c:302
       __loop_clr_fd+0x49c/0x74c drivers/block/loop.c:1172
       loop_clr_fd drivers/block/loop.c:1255 [inline]
       lo_ioctl+0x50c/0x1748 drivers/block/loop.c:1561
       blkdev_ioctl+0x248/0x2e7c block/ioctl.c:631
       vfs_ioctl fs/ioctl.c:51 [inline]
       __do_sys_ioctl fs/ioctl.c:871 [inline]
       __se_sys_ioctl fs/ioctl.c:857 [inline]
       __arm64_sys_ioctl+0xa0c/0x2c38 fs/ioctl.c:857
       __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline]
       invoke_syscall.constprop.0+0x88/0x21c arch/arm64/kernel/syscall.c:51
       el0_svc_common arch/arm64/kernel/syscall.c:136 [inline]
       do_el0_svc+0xf0/0x218 arch/arm64/kernel/syscall.c:155
       el0_svc+0x58/0x140 arch/arm64/kernel/entry-common.c:678
       el0t_64_sync_handler+0x100/0x12c arch/arm64/kernel/entry-common.c:696
       el0t_64_sync+0x194/0x198 arch/arm64/kernel/entry.S:599

-> #1 (&bdev->bd_holder_lock){+.+.}-{3:3}:
       __mutex_lock_common kernel/locking/mutex.c:603 [inline]
       __mutex_lock+0x124/0x838 kernel/locking/mutex.c:747
       mutex_lock_nested+0x24/0x30 kernel/locking/mutex.c:799
       bdev_mark_dead+0x34/0x1e4 block/bdev.c:963
       disk_force_media_change+0x50/0xbc block/disk-events.c:302
       __loop_clr_fd+0x2cc/0x74c drivers/block/loop.c:1172
       lo_release+0x188/0x1b8 drivers/block/loop.c:1741
       blkdev_put_whole+0xb8/0x12c block/bdev.c:665
       blkdev_put+0x328/0x748 block/bdev.c:900
       kill_block_super+0x58/0x74 fs/super.c:1649
       ext4_kill_sb+0x60/0xb8 fs/ext4/super.c:7320
       deactivate_locked_super+0xa0/0x1a8 fs/super.c:481
       deactivate_super fs/super.c:514 [inline]
       deactivate_super+0x118/0x148 fs/super.c:510
       cleanup_mnt+0x1b8/0x338 fs/namespace.c:1254
       __cleanup_mnt+0x20/0x30 fs/namespace.c:1261
       task_work_run+0x148/0x254 kernel/task_work.c:180
       resume_user_mode_work include/linux/resume_user_mode.h:49 [inline]
       do_notify_resume+0xe04/0x18f4 arch/arm64/kernel/signal.c:1305
       exit_to_user_mode_prepare arch/arm64/kernel/entry-common.c:137 [inline]
       exit_to_user_mode arch/arm64/kernel/entry-common.c:144 [inline]
       el0_svc+0x11c/0x140 arch/arm64/kernel/entry-common.c:679
       el0t_64_sync_handler+0x100/0x12c arch/arm64/kernel/entry-common.c:696
       el0t_64_sync+0x194/0x198 arch/arm64/kernel/entry.S:599

-> #0 (&disk->open_mutex){+.+.}-{3:3}:
       check_prev_add kernel/locking/lockdep.c:3134 [inline]
       check_prevs_add kernel/locking/lockdep.c:3253 [inline]
       validate_chain kernel/locking/lockdep.c:3869 [inline]
       __lock_acquire+0x2a88/0x6344 kernel/locking/lockdep.c:5137
       lock_acquire kernel/locking/lockdep.c:5754 [inline]
       lock_acquire+0x47c/0x770 kernel/locking/lockdep.c:5719
       __mutex_lock_common kernel/locking/mutex.c:603 [inline]
       __mutex_lock+0x124/0x838 kernel/locking/mutex.c:747
       mutex_lock_nested+0x24/0x30 kernel/locking/mutex.c:799
       blkdev_put+0xa8/0x748 block/bdev.c:886
       ext4_get_journal_blkdev fs/ext4/super.c:5921 [inline]
       ext4_open_dev_journal fs/ext4/super.c:5934 [inline]
       ext4_load_journal fs/ext4/super.c:5997 [inline]
       ext4_load_and_init_journal+0x19a4/0x230c fs/ext4/super.c:4907
       __ext4_fill_super fs/ext4/super.c:5375 [inline]
       ext4_fill_super+0x7f08/0x9298 fs/ext4/super.c:5704
       get_tree_bdev+0x334/0x538 fs/super.c:1577
       ext4_get_tree+0x28/0x38 fs/ext4/super.c:5736
       vfs_get_tree+0x7c/0x2c0 fs/super.c:1750
       do_new_mount fs/namespace.c:3346 [inline]
       path_mount+0x1228/0x1b68 fs/namespace.c:3673
       do_mount fs/namespace.c:3686 [inline]
       __do_sys_mount fs/namespace.c:3895 [inline]
       __se_sys_mount fs/namespace.c:3872 [inline]
       __arm64_sys_mount+0x5dc/0x6f8 fs/namespace.c:3872
       __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline]
       invoke_syscall.constprop.0+0x88/0x21c arch/arm64/kernel/syscall.c:51
       el0_svc_common arch/arm64/kernel/syscall.c:136 [inline]
       do_el0_svc+0xf0/0x218 arch/arm64/kernel/syscall.c:155
       el0_svc+0x58/0x140 arch/arm64/kernel/entry-common.c:678
       el0t_64_sync_handler+0x100/0x12c arch/arm64/kernel/entry-common.c:696
       el0t_64_sync+0x194/0x198 arch/arm64/kernel/entry.S:599

other info that might help us debug this:

Chain exists of:
  &disk->open_mutex --> &bdev->bd_holder_lock --> &type->s_umount_key#24

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(&type->s_umount_key#24);
                               lock(&bdev->bd_holder_lock);
                               lock(&type->s_umount_key#24);
  lock(&disk->open_mutex);

 *** DEADLOCK ***

1 lock held by syz-executor244/1037:
 #0: ffff00000adce0e0 (&type->s_umount_key#24){++++}-{3:3}, at:
ext4_get_journal_blkdev fs/ext4/super.c:5862 [inline]
 #0: ffff00000adce0e0 (&type->s_umount_key#24){++++}-{3:3}, at:
ext4_open_dev_journal fs/ext4/super.c:5934 [inline]
 #0: ffff00000adce0e0 (&type->s_umount_key#24){++++}-{3:3}, at:
ext4_load_journal fs/ext4/super.c:5997 [inline]
 #0: ffff00000adce0e0 (&type->s_umount_key#24){++++}-{3:3}, at:
ext4_load_and_init_journal+0x7c8/0x230c fs/ext4/super.c:4907

stack backtrace:
CPU: 1 PID: 1037 Comm: syz-executor244 Not tainted 6.6.16-eb-corbos-standard-
syzkaller-geb3e299184cc #0
Hardware name: linux,dummy-virt (DT)
Call trace:
 dump_backtrace+0x128/0x214 arch/arm64/kernel/stacktrace.c:233
 show_stack+0x2c/0x44 arch/arm64/kernel/stacktrace.c:240
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0xac/0x128 lib/dump_stack.c:106
 dump_stack+0x20/0x2c lib/dump_stack.c:113
 print_circular_bug+0x420/0x6f8 kernel/locking/lockdep.c:2060
 check_noncircular+0x2d0/0x358 kernel/locking/lockdep.c:2187
 check_prev_add kernel/locking/lockdep.c:3134 [inline]
 check_prevs_add kernel/locking/lockdep.c:3253 [inline]
 validate_chain kernel/locking/lockdep.c:3869 [inline]
 __lock_acquire+0x2a88/0x6344 kernel/locking/lockdep.c:5137
 lock_acquire kernel/locking/lockdep.c:5754 [inline]
 lock_acquire+0x47c/0x770 kernel/locking/lockdep.c:5719
 __mutex_lock_common kernel/locking/mutex.c:603 [inline]
 __mutex_lock+0x124/0x838 kernel/locking/mutex.c:747
 mutex_lock_nested+0x24/0x30 kernel/locking/mutex.c:799
 blkdev_put+0xa8/0x748 block/bdev.c:886
 ext4_get_journal_blkdev fs/ext4/super.c:5921 [inline]
 ext4_open_dev_journal fs/ext4/super.c:5934 [inline]
 ext4_load_journal fs/ext4/super.c:5997 [inline]
 ext4_load_and_init_journal+0x19a4/0x230c fs/ext4/super.c:4907
 __ext4_fill_super fs/ext4/super.c:5375 [inline]
 ext4_fill_super+0x7f08/0x9298 fs/ext4/super.c:5704
 get_tree_bdev+0x334/0x538 fs/super.c:1577
 ext4_get_tree+0x28/0x38 fs/ext4/super.c:5736
 vfs_get_tree+0x7c/0x2c0 fs/super.c:1750
 do_new_mount fs/namespace.c:3346 [inline]
 path_mount+0x1228/0x1b68 fs/namespace.c:3673
 do_mount fs/namespace.c:3686 [inline]
 __do_sys_mount fs/namespace.c:3895 [inline]
 __se_sys_mount fs/namespace.c:3872 [inline]
 __arm64_sys_mount+0x5dc/0x6f8 fs/namespace.c:3872
 __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline]
 invoke_syscall.constprop.0+0x88/0x21c arch/arm64/kernel/syscall.c:51
 el0_svc_common arch/arm64/kernel/syscall.c:136 [inline]
 do_el0_svc+0xf0/0x218 arch/arm64/kernel/syscall.c:155
 el0_svc+0x58/0x140 arch/arm64/kernel/entry-common.c:678
 el0t_64_sync_handler+0x100/0x12c arch/arm64/kernel/entry-common.c:696
 el0t_64_sync+0x194/0x198 arch/arm64/kernel/entry.S:599

Reproducer
----------
// https://None.appspot.com/bug?id=fb8efc3dbc2fee279ba7e4ab75cfd31ba665c6e5
// 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 <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.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>

#ifndef __NR_memfd_create
#define __NR_memfd_create 279
#endif
#ifndef __NR_mmap
#define __NR_mmap 222
#endif

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

//% This code is derived from puff.{c,h}, found in the zlib development. The
//% original files come with the following copyright notice:

//% Copyright (C) 2002-2013 Mark Adler, all rights reserved
//% version 2.3, 21 Jan 2013
//% This software is provided 'as-is', without any express or implied
//% warranty.  In no event will the author be held liable for any damages
//% arising from the use of this software.
//% Permission is granted to anyone to use this software for any purpose,
//% including commercial applications, and to alter it and redistribute it
//% freely, subject to the following restrictions:
//% 1. The origin of this software must not be misrepresented; you must not
//%    claim that you wrote the original software. If you use this software
//%    in a product, an acknowledgment in the product documentation would be
//%    appreciated but is not required.
//% 2. Altered source versions must be plainly marked as such, and must not be
//%    misrepresented as being the original software.
//% 3. This notice may not be removed or altered from any source distribution.
//% Mark Adler    madler@xxxxxxxxxxxxxxxxxx

//% BEGIN CODE DERIVED FROM puff.{c,h}

#define MAXBITS 15
#define MAXLCODES 286
#define MAXDCODES 30
#define MAXCODES (MAXLCODES + MAXDCODES)
#define FIXLCODES 288

struct puff_state {
  unsigned char* out;
  unsigned long outlen;
  unsigned long outcnt;
  const unsigned char* in;
  unsigned long inlen;
  unsigned long incnt;
  int bitbuf;
  int bitcnt;
  jmp_buf env;
};
static int puff_bits(struct puff_state* s, int need)
{
  long val = s->bitbuf;
  while (s->bitcnt < need) {
    if (s->incnt == s->inlen)
      longjmp(s->env, 1);
    val |= (long)(s->in[s->incnt++]) << s->bitcnt;
    s->bitcnt += 8;
  }
  s->bitbuf = (int)(val >> need);
  s->bitcnt -= need;
  return (int)(val & ((1L << need) - 1));
}
static int puff_stored(struct puff_state* s)
{
  s->bitbuf = 0;
  s->bitcnt = 0;
  if (s->incnt + 4 > s->inlen)
    return 2;
  unsigned len = s->in[s->incnt++];
  len |= s->in[s->incnt++] << 8;
  if (s->in[s->incnt++] != (~len & 0xff) ||
      s->in[s->incnt++] != ((~len >> 8) & 0xff))
    return -2;
  if (s->incnt + len > s->inlen)
    return 2;
  if (s->outcnt + len > s->outlen)
    return 1;
  for (; len--; s->outcnt++, s->incnt++) {
    if (s->in[s->incnt])
      s->out[s->outcnt] = s->in[s->incnt];
  }
  return 0;
}
struct puff_huffman {
  short* count;
  short* symbol;
};
static int puff_decode(struct puff_state* s, const struct puff_huffman* h)
{
  int first = 0;
  int index = 0;
  int bitbuf = s->bitbuf;
  int left = s->bitcnt;
  int code = first = index = 0;
  int len = 1;
  short* next = h->count + 1;
  while (1) {
    while (left--) {
      code |= bitbuf & 1;
      bitbuf >>= 1;
      int count = *next++;
      if (code - count < first) {
        s->bitbuf = bitbuf;
        s->bitcnt = (s->bitcnt - len) & 7;
        return h->symbol[index + (code - first)];
      }
      index += count;
      first += count;
      first <<= 1;
      code <<= 1;
      len++;
    }
    left = (MAXBITS + 1) - len;
    if (left == 0)
      break;
    if (s->incnt == s->inlen)
      longjmp(s->env, 1);
    bitbuf = s->in[s->incnt++];
    if (left > 8)
      left = 8;
  }
  return -10;
}
static int puff_construct(struct puff_huffman* h, const short* length, int n)
{
  int len;
  for (len = 0; len <= MAXBITS; len++)
    h->count[len] = 0;
  int symbol;
  for (symbol = 0; symbol < n; symbol++)
    (h->count[length[symbol]])++;
  if (h->count[0] == n)
    return 0;
  int left = 1;
  for (len = 1; len <= MAXBITS; len++) {
    left <<= 1;
    left -= h->count[len];
    if (left < 0)
      return left;
  }
  short offs[MAXBITS + 1];
  offs[1] = 0;
  for (len = 1; len < MAXBITS; len++)
    offs[len + 1] = offs[len] + h->count[len];
  for (symbol = 0; symbol < n; symbol++)
    if (length[symbol] != 0)
      h->symbol[offs[length[symbol]]++] = symbol;
  return left;
}
static int puff_codes(struct puff_state* s, const struct puff_huffman* lencode,
                      const struct puff_huffman* distcode)
{
  static const short lens[29] = {3,  4,  5,  6,   7,   8,   9,   10,  11, 13,
                                 15, 17, 19, 23,  27,  31,  35,  43,  51, 59,
                                 67, 83, 99, 115, 131, 163, 195, 227, 258};
  static const short lext[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
                                 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
  static const short dists[30] = {
      1,    2,    3,    4,    5,    7,    9,    13,    17,    25,
      33,   49,   65,   97,   129,  193,  257,  385,   513,   769,
      1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
  static const short dext[30] = {0, 0, 0,  0,  1,  1,  2,  2,  3,  3,
                                 4, 4, 5,  5,  6,  6,  7,  7,  8,  8,
                                 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
  int symbol;
  do {
    symbol = puff_decode(s, lencode);
    if (symbol < 0)
      return symbol;
    if (symbol < 256) {
      if (s->outcnt == s->outlen)
        return 1;
      if (symbol)
        s->out[s->outcnt] = symbol;
      s->outcnt++;
    } else if (symbol > 256) {
      symbol -= 257;
      if (symbol >= 29)
        return -10;
      int len = lens[symbol] + puff_bits(s, lext[symbol]);
      symbol = puff_decode(s, distcode);
      if (symbol < 0)
        return symbol;
      unsigned dist = dists[symbol] + puff_bits(s, dext[symbol]);
      if (dist > s->outcnt)
        return -11;
      if (s->outcnt + len > s->outlen)
        return 1;
      while (len--) {
        if (dist <= s->outcnt && s->out[s->outcnt - dist])
          s->out[s->outcnt] = s->out[s->outcnt - dist];
        s->outcnt++;
      }
    }
  } while (symbol != 256);
  return 0;
}
static int puff_fixed(struct puff_state* s)
{
  static int virgin = 1;
  static short lencnt[MAXBITS + 1], lensym[FIXLCODES];
  static short distcnt[MAXBITS + 1], distsym[MAXDCODES];
  static struct puff_huffman lencode, distcode;
  if (virgin) {
    lencode.count = lencnt;
    lencode.symbol = lensym;
    distcode.count = distcnt;
    distcode.symbol = distsym;
    short lengths[FIXLCODES];
    int symbol;
    for (symbol = 0; symbol < 144; symbol++)
      lengths[symbol] = 8;
    for (; symbol < 256; symbol++)
      lengths[symbol] = 9;
    for (; symbol < 280; symbol++)
      lengths[symbol] = 7;
    for (; symbol < FIXLCODES; symbol++)
      lengths[symbol] = 8;
    puff_construct(&lencode, lengths, FIXLCODES);
    for (symbol = 0; symbol < MAXDCODES; symbol++)
      lengths[symbol] = 5;
    puff_construct(&distcode, lengths, MAXDCODES);
    virgin = 0;
  }
  return puff_codes(s, &lencode, &distcode);
}
static int puff_dynamic(struct puff_state* s)
{
  static const short order[19] = {16, 17, 18, 0, 8,  7, 9,  6, 10, 5,
                                  11, 4,  12, 3, 13, 2, 14, 1, 15};
  int nlen = puff_bits(s, 5) + 257;
  int ndist = puff_bits(s, 5) + 1;
  int ncode = puff_bits(s, 4) + 4;
  if (nlen > MAXLCODES || ndist > MAXDCODES)
    return -3;
  short lengths[MAXCODES];
  int index;
  for (index = 0; index < ncode; index++)
    lengths[order[index]] = puff_bits(s, 3);
  for (; index < 19; index++)
    lengths[order[index]] = 0;
  short lencnt[MAXBITS + 1], lensym[MAXLCODES];
  struct puff_huffman lencode = {lencnt, lensym};
  int err = puff_construct(&lencode, lengths, 19);
  if (err != 0)
    return -4;
  index = 0;
  while (index < nlen + ndist) {
    int symbol;
    int len;
    symbol = puff_decode(s, &lencode);
    if (symbol < 0)
      return symbol;
    if (symbol < 16)
      lengths[index++] = symbol;
    else {
      len = 0;
      if (symbol == 16) {
        if (index == 0)
          return -5;
        len = lengths[index - 1];
        symbol = 3 + puff_bits(s, 2);
      } else if (symbol == 17)
        symbol = 3 + puff_bits(s, 3);
      else
        symbol = 11 + puff_bits(s, 7);
      if (index + symbol > nlen + ndist)
        return -6;
      while (symbol--)
        lengths[index++] = len;
    }
  }
  if (lengths[256] == 0)
    return -9;
  err = puff_construct(&lencode, lengths, nlen);
  if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
    return -7;
  short distcnt[MAXBITS + 1], distsym[MAXDCODES];
  struct puff_huffman distcode = {distcnt, distsym};
  err = puff_construct(&distcode, lengths + nlen, ndist);
  if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
    return -8;
  return puff_codes(s, &lencode, &distcode);
}
static int puff(unsigned char* dest, unsigned long* destlen,
                const unsigned char* source, unsigned long sourcelen)
{
  struct puff_state s = {
      .out = dest,
      .outlen = *destlen,
      .outcnt = 0,
      .in = source,
      .inlen = sourcelen,
      .incnt = 0,
      .bitbuf = 0,
      .bitcnt = 0,
  };
  int err;
  if (setjmp(s.env) != 0)
    err = 2;
  else {
    int last;
    do {
      last = puff_bits(&s, 1);
      int type = puff_bits(&s, 2);
      err = type == 0 ? puff_stored(&s)
                      : (type == 1 ? puff_fixed(&s)
                                   : (type == 2 ? puff_dynamic(&s) : -1));
      if (err != 0)
        break;
    } while (!last);
  }
  *destlen = s.outcnt;
  return err;
}

//% END CODE DERIVED FROM puff.{c,h}

#define ZLIB_HEADER_WIDTH 2

static int puff_zlib_to_file(const unsigned char* source,
                             unsigned long sourcelen, int dest_fd)
{
  if (sourcelen < ZLIB_HEADER_WIDTH)
    return 0;
  source += ZLIB_HEADER_WIDTH;
  sourcelen -= ZLIB_HEADER_WIDTH;
  const unsigned long max_destlen = 132 << 20;
  void* ret = mmap(0, max_destlen, PROT_WRITE | PROT_READ,
                   MAP_PRIVATE | MAP_ANON, -1, 0);
  if (ret == MAP_FAILED)
    return -1;
  unsigned char* dest = (unsigned char*)ret;
  unsigned long destlen = max_destlen;
  int err = puff(dest, &destlen, source, sourcelen);
  if (err) {
    munmap(dest, max_destlen);
    errno = -err;
    return -1;
  }
  if (write(dest_fd, dest, destlen) != (ssize_t)destlen) {
    munmap(dest, max_destlen);
    return -1;
  }
  return munmap(dest, max_destlen);
}

static int setup_loop_device(unsigned char* data, unsigned long size,
                             const char* loopname, int* loopfd_p)
{
  int err = 0, loopfd = -1;
  int memfd = syscall(__NR_memfd_create, "syzkaller", 0);
  if (memfd == -1) {
    err = errno;
    goto error;
  }
  if (puff_zlib_to_file(data, size, memfd)) {
    err = errno;
    goto error_close_memfd;
  }
  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;
    }
  }
  close(memfd);
  *loopfd_p = loopfd;
  return 0;

error_close_loop:
  close(loopfd);
error_close_memfd:
  close(memfd);
error:
  errno = err;
  return -1;
}

static void reset_loop_device(const char* loopname)
{
  int loopfd = open(loopname, O_RDWR);
  if (loopfd == -1) {
    return;
  }
  if (ioctl(loopfd, LOOP_CLR_FD, 0)) {
  }
  close(loopfd);
}

static long syz_mount_image(volatile long fsarg, volatile long dir,
                            volatile long flags, volatile long optsarg,
                            volatile long change_dir,
                            volatile unsigned long size, volatile long image)
{
  unsigned char* data = (unsigned char*)image;
  int res = -1, err = 0, need_loop_device = !!size;
  char* mount_opts = (char*)optsarg;
  char* target = (char*)dir;
  char* fs = (char*)fsarg;
  char* source = NULL;
  char loopname[64];
  if (need_loop_device) {
    int loopfd;
    memset(loopname, 0, sizeof(loopname));
    snprintf(loopname, sizeof(loopname), "/dev/loop%llu", procid);
    if (setup_loop_device(data, size, loopname, &loopfd) == -1)
      return -1;
    close(loopfd);
    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) {
    bool has_remount_ro = false;
    char* remount_ro_start = strstr(opts, "errors=remount-ro");
    if (remount_ro_start != NULL) {
      char after = *(remount_ro_start + strlen("errors=remount-ro"));
      char before = remount_ro_start == opts ? '\0' : *(remount_ro_start - 1);
      has_remount_ro = ((before == '\0' || before == ',') &&
                        (after == '\0' || after == ','));
    }
    if (strstr(opts, "errors=panic") || !has_remount_ro)
      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;
    goto error_clear_loop;
  }
  if (change_dir) {
    res = chdir(target);
    if (res == -1) {
      err = errno;
    }
  }

error_clear_loop:
  if (need_loop_device)
    reset_loop_device(loopname);
  errno = err;
  return res;
}

#define FS_IOC_SETFLAGS _IOW('f', 2, long)
static void remove_dir(const char* dir)
{
  int iter = 0;
  DIR* dp = 0;
retry:
  while (umount2(dir, MNT_DETACH | UMOUNT_NOFOLLOW) == 0) {
  }
  dp = opendir(dir);
  if (dp == NULL) {
    if (errno == EMFILE) {
      exit(1);
    }
    exit(1);
  }
  struct dirent* ep = 0;
  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 | UMOUNT_NOFOLLOW) == 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 | UMOUNT_NOFOLLOW))
        exit(1);
    }
  }
  closedir(dp);
  for (int 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 | UMOUNT_NOFOLLOW))
          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);
  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 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");
  if (symlink("/dev/binderfs", "./binderfs")) {
  }
}

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 < 2; 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 (call == 0)
        break;
      event_timedwait(&th->done,
                      50 + (call == 0 ? 4000 : 0) + (call == 1 ? 4000 : 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++) {
    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 < 5000)
        continue;
      kill_and_wait(pid, &status);
      break;
    }
    remove_dir(cwdbuf);
  }
}

void execute_call(int call)
{
  switch (call) {
  case 0:
    memcpy((void*)0x20000080, "ext4\000", 5);
    memcpy((void*)0x200001c0, "./mnt\000", 6);
    memcpy(
        (void*)0x200005c0,
        "\x78\x9c\xec\xdd\x4d\x68\x14\x67\x18\x07\xf0\x67\xf6\x23\xc9\x26\x4b"
        "\x49\xdb\x4b\xa1\xd0\x16\x4a\x29\x6d\x20\xa4\xb7\x42\x2f\xe9\xa5\x85"
        "\x40\x09\xa1\x94\x42\x2b\x44\x44\x3c\x49\x22\xc4\x04\x6f\x89\x27\x2f"
        "\x1e\xf4\xac\x92\x93\x97\x20\xde\x8c\x1e\xc5\x4b\xf0\xa2\x08\x9e\xa2"
        "\xe6\x10\x2f\x82\x06\x0f\x06\x0f\x7a\x58\xd9\x8f\xc8\x6a\x36\x46\xb3"
        "\x61\x06\x9d\xdf\x0f\x26\x93\xd9\x77\x66\x9e\x77\xd8\xf9\xbf\x33\x97"
        "\x99\x0d\x20\xb7\x06\x23\x62\x34\x22\x8a\x11\x31\x14\x11\x3d\x11\x91"
        "\xb4\xaf\xf0\x5d\x73\x1a\x6c\x2d\x2e\x56\x56\x26\x23\x6a\xb5\xbf\x9f"
        "\x26\x8d\xf5\x9a\xcb\x4d\x5b\xdb\x0d\x44\xc4\x42\x44\xfc\x1a\xd1\xb7"
        "\xd5\x36\xb7\xfc\xff\xfa\xf3\xd5\x3f\x7f\x3c\x3d\x5b\xfe\xe1\xe2\xf2"
        "\x7f\x95\xb4\x8e\xaf\xdd\xc6\xfa\xda\x5f\x9b\x17\xc6\x4f\x5d\x19\xfb"
        "\x65\xee\xf6\xdd\xc7\xe3\x49\x8c\x46\xb5\xd5\xd6\x7e\x1c\x1f\xaa\xf0"
        "\x8e\xb6\xa4\xc3\x67\xa5\x24\xe2\x8b\xbd\x16\xfb\x08\x24\xa5\xac\x7b"
        "\xc0\xfb\x98\x38\x71\xf9\x5e\x3d\xf7\x5f\x46\xc4\xf7\x8d\xfc\x97\xa3"
        "\x10\xcd\x2f\xef\xcc\x4c\xcf\x8d\x72\xfc\x7c\x7e\xa7\x6d\xcf\x3e\xb9"
        "\xf3\x75\x9a\x7d\x05\xf6\x5f\xad\x56\xae\x5f\x03\x17\x6a\x40\xee\xd4"
        "\xef\x5d\xab\x91\x14\x86\x5b\xf7\xb1\xd5\x28\x14\x86\x87\x9b\xf7\xf0"
        "\xf7\x8b\xfd\x85\xa3\xd3\x33\xc7\x87\x8e\x4c\xcf\x4e\x1d\xce\x7a\xa4"
        "\x02\xf6\x4b\x35\x7a\xe3\x8f\x6b\xbd\x57\x07\xde\xca\xff\xa3\x62\x33"
        "\xff\xc0\xa7\xab\x1a\xb1\xf6\xcf\xc4\xd2\x83\xfa\xff\x9b\xc5\xac\x7b"
        "\x03\xa4\xa9\x9e\xff\xa1\x83\xf3\x3f\x85\xfc\x43\xee\xc8\x3f\xe4\x97"
        "\xfc\x43\x7e\xc9\x3f\xe4\x97\xfc\x43\x7e\xc9\x3f\xe4\x4f\x4f\x6b\xbe"
        "\x5b\xfe\xcb\x29\xf7\x0b\x48\x8f\xeb\x3f\xe4\x97\xfc\x43\x7e\xc9\x3f"
        "\xe4\x57\x7b\xfe\x01\x80\x7c\xa9\xf5\x66\xfd\x04\x32\x90\x95\xac\xc7"
        "\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\xbb"
        "\xc5\xca\xca\xe4\xd6\x94\x56\xcd\x9b\xe7\x22\x36\x7e\x8f\x88\x52\xa7"
        "\xfa\xc5\xc6\xef\x11\x47\xf4\x35\xfe\xf6\x3f\x4b\xea\xab\xbd\x96\x34"
        "\x37\xeb\xca\x81\x6f\xbb\xdc\x41\x97\x2e\x65\xfc\xf4\xf5\x67\x0f\xd3"
        "\xa9\xb3\xd3\xeb\xe5\x6e\x7d\x93\x4e\xfd\x9d\xcc\x4f\x45\x2c\x9c\x8c"
        "\x88\x91\x52\x69\xfb\xf9\x97\xb4\xce\xbf\xbd\xfb\x7c\x97\xf6\xf2\xa1"
        "\x2e\x0b\x74\xe9\xb7\x7f\xb3\xad\xff\x72\x29\xed\x8a\x95\x37\x96\xc6"
        "\x56\x23\xae\xd7\xc7\x9f\x91\x4e\xe3\x4f\x21\xbe\x6a\xcc\x3b\x8f\x3f"
        "\xd5\x7d\x78\x47\xfa\xb1\x17\x5d\xee\x00\x00\x00\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\xd4\xbc\x0a\x00\x00\xff\xff\x89\xf6\x6b\x40",
        592);
    syz_mount_image(/*fs=*/0x20000080, /*dir=*/0x200001c0,
                    /*flags=MS_RELATIME|MS_NODEV*/ 0x200004,
                    /*opts=*/0x200002c0, /*chdir=*/0xfd, /*size=*/0x250,
                    /*img=*/0x200005c0);
    break;
  case 1:
    memcpy((void*)0x20000000, "ext4\000", 5);
    memcpy((void*)0x20000580, "./file0\000", 8);
    memcpy((void*)0x20000040, "noauto_da_alloc", 15);
    *(uint8_t*)0x2000004f = 0x2c;
    memcpy((void*)0x20000050, "bsddf", 5);
    *(uint8_t*)0x20000055 = 0x2c;
    memcpy((void*)0x20000056, "nouid32", 7);
    *(uint8_t*)0x2000005d = 0x2c;
    memcpy((void*)0x2000005e, "noinit_itable", 13);
    *(uint8_t*)0x2000006b = 0x2c;
    memcpy((void*)0x2000006c, "noblock_validity", 16);
    *(uint8_t*)0x2000007c = 0x2c;
    memcpy((void*)0x2000007d, "journal_dev", 11);
    *(uint8_t*)0x20000088 = 0x3d;
    sprintf((char*)0x20000089, "0x%016llx", (long long)0x7b000700);
    *(uint8_t*)0x2000009b = 0x2c;
    memcpy((void*)0x2000009c, "max_batch_time", 14);
    *(uint8_t*)0x200000aa = 0x3d;
    sprintf((char*)0x200000ab, "0x%016llx", (long long)0x10001);
    *(uint8_t*)0x200000bd = 0x2c;
    memcpy((void*)0x200000be, "journal_async_commit", 20);
    *(uint8_t*)0x200000d2 = 0x2c;
    *(uint8_t*)0x200000d3 = 0;
    memcpy(
        (void*)0x20000b80,
        "\x78\x9c\xec\xdd\x4d\x6b\x54\x57\x1f\x00\xf0\xff\x1d\x27\x1a\xf5\x79"
        "\x6a\x04\x11\xda\x45\x1b\x10\x5a\xc1\x3a\x31\x49\x5f\x2c\x74\xa1\xcb"
        "\xd2\x4a\x85\x76\xd7\x85\x86\x64\x0c\x92\x89\x23\x99\x89\x98\x28\x54"
        "\x17\x75\x53\x0a\x45\x0a\xa5\x54\x28\x05\xb7\xdd\x77\x29\xed\x07\xe8"
        "\xa2\x1f\xa0\x2b\xa1\x15\xa4\x48\xe8\xa6\x9b\x29\x77\xe6\x4e\x9c\x24"
        "\x33\xc9\x34\x26\xce\x94\xf9\xfd\xe0\x3a\xe7\xcc\xbd\x33\xe7\xfc\xef"
        "\xb9\xe7\xcc\xb9\x2f\x92\x00\x06\xd6\x68\xfa\x4f\x2e\xe2\xc5\x88\xf8"
        "\x32\x89\x38\xd4\xb2\x2e\x1f\xd9\xca\xd1\xc6\x76\x2b\x4f\x6e\x4e\xa7"
        "\x4b\x12\xb5\xda\x47\x7f\x26\xf1\xf3\xfd\xc6\x7b\xcd\xed\x93\xec\xf5"
        "\x60\x96\xa9\xd5\x6a\xb5\x9f\x3e\x8b\x38\x91\xdb\x58\x6e\x65\x69\x79"
        "\x6e\xaa\x54\x2a\x2e\x64\xf9\xb1\xea\xfc\xd5\xb1\xca\xd2\xf2\xc9\xcb"
        "\xf3\x53\xb3\xc5\xd9\xe2\x95\x89\xc9\xc9\xd3\x6f\x4e\x4e\xbc\xf3\xf6"
        "\x5b\x3b\x11\xe6\x8d\x91\xc6\xeb\x37\x1f\x3e\x78\xef\xf4\xe7\xc7\x56"
        "\xbe\xfe\xe1\xd1\xe1\xbb\x49\x9c\x69\xc4\x1f\x6b\xe3\xd8\x29\xa3\x31"
        "\x9a\xed\x93\xa1\x38\xb3\x6e\xdd\xf8\x4e\x17\xd6\x63\x49\xaf\x2b\xc0"
        "\xb6\xe4\xb3\x65\x28\xd2\x31\xe0\x90\x66\x84\x41\x92\x6f\xfc\x4e\x03"
        "\x83\x28\xd1\xff\x61\x40\x35\xa7\x01\xcd\x73\xfb\xdd\x38\x0f\xee\x67"
        "\x8f\xcf\x46\x7c\x92\x6b\x17\x7f\x3e\xbb\x36\x30\x5c\x3f\x37\x3a\xb0"
        "\x92\x64\xd7\x43\x1a\xd2\x13\xa5\x91\x1d\x28\xff\x7f\x11\xf1\xe3\x1f"
        "\xf7\xee\xa6\x4b\xfc\x8b\xeb\x10\xfb\x77\xa0\x6c\x60\xb0\xdd\xba\x1d"
        "\x11\xa7\xf2\xf9\x8d\xe3\x5f\xb2\x7a\x6d\x74\xbb\x4e\x75\xb1\xcd\xfa"
        "\x32\x06\xed\xf7\x07\x7a\xe9\xc1\xd9\x88\x78\xbd\xdd\xfc\x27\xb7\x3a"
        "\xff\x89\x6c\xfe\xd3\x3a\xe7\x38\xd8\xa6\xef\x6e\xc7\xd6\xfd\x3f\xf7"
        "\x68\x07\x8a\xe9\x28\x9d\xff\xbd\xdb\x76\xfe\xbb\x7a\xd3\x6a\x64\x4f"
        "\x96\xfb\x7f\x7d\xce\x37\x94\x5c\xba\x5c\x2a\xa6\x63\xdb\x0b\x11\x71"
        "\x3c\x86\xf6\xa5\xf9\xcd\xee\xe7\x9c\x5e\x79\x58\xeb\xb4\x6e\xb4\x65"
        "\xfe\x97\x2e\x69\xf9\xcd\xb9\x60\x56\x8f\x47\xf9\x7d\x6b\x3f\x33\x33"
        "\x55\x9d\x7a\x96\x98\x5b\x3d\xbe\x1d\xf1\x52\xbe\x5d\xfc\xc9\x6a\xfb"
        "\x27\x6d\xe6\xbf\xe9\xfe\x38\xdf\x65\x19\x47\x8b\xf7\x5e\xee\xb4\xae"
        "\x5e\xc6\xa6\xf1\x6f\xe6\xb7\x2e\x6b\xd0\x59\xed\xfb\x88\xd7\x5a\xdb"
        "\xff\xd7\xe6\x9a\xa7\xb7\x42\x92\xcd\xef\x4f\x8e\xd5\x8f\x87\xb1\xe6"
        "\x51\xb1\xd1\x5f\x77\x8e\xfe\xd2\xa9\xfc\xad\xdb\x7f\x77\xa5\xed\x7f"
        "\xa0\xed\xf1\xbf\x1a\xff\x48\xd2\x7a\xbf\xb6\xb2\xf5\x77\xde\x5f\x97"
        "\xff\x6e\xf8\xef\x62\xa7\x6d\xb7\x7b\xfc\xef\x4d\x3e\xae\xa7\xf7\x66"
        "\xef\x5d\x9f\xaa\x56\x17\xc6\xd3\xdc\x07\x1b\xdf\x9f\x78\xfa\xd9\x66"
        "\x3e\x7d\xfd\x34\x8b\xff\xf8\xb1\x34\xfe\x57\x3a\x8e\x7f\xed\x8e\xff"
        "\x33\x11\x71\x71\xed\x7e\x5a\xef\x8b\xe6\x08\x72\xe7\xc8\x9d\x8b\xdb"
        "\x8f\x7f\x77\xa5\xf1\xcf\x6c\x6c\xff\xd6\x61\x79\x5d\xfb\x77\x9d\x88"
        "\xe1\x2c\xf1\xf0\xfd\x1b\xdf\x76\x2a\xbf\xbb\xf6\x7f\xa3\x9e\x3a\x9e"
        "\xbd\xd3\xcd\xf8\xd7\x6d\x4d\x9f\x65\xdf\x01\x00\x00\x00\x00\x00\x40"
        "\xbf\xc9\xd5\x9f\x41\x4d\x72\x85\xd5\x74\x2e\x57\x28\x34\x9e\xef\x38"
        "\x12\x07\x72\xa5\x72\xa5\x7a\xe2\x52\x79\xf1\xca\x4c\xe3\x59\xd5\x91"
        "\x18\xca\x35\xef\x74\x1f\x6a\x79\x1e\x62\x3c\x7b\x1e\xb6\x99\x9f\x58"
        "\x97\x9f\x8c\x88\xc3\x11\xf1\xd5\x9e\xfd\xf5\x7c\x61\xba\x5c\x9a\xe9"
        "\x75\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\xd0\x27\x0e\x76\xf8\xff\xff\xa9\xdf\xf7\xf4\xba\x76\xc0\xae\xcb\xf7"
        "\xba\x02\x40\xcf\x3c\xed\xff\x43\x3d\xad\x07\xf0\xfc\xf9\xfd\x87\xc1"
        "\xa5\xff\xc3\xe0\xd2\xff\x61\x70\xe9\xff\x30\xb8\xea\xfd\xdf\xa5\x3f"
        "\x18\x48\xdb\xf8\xfd\x7f\x75\x37\xea\x01\x3c\x7f\xe6\xff\x30\xb8\xf2"
        "\x6b\x5e\x62\x78\xd3\x8d\x93\xdd\xaf\x0f\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xc7\x9d"
        "\x3f\x77\x2e\x5d\x6a\x2b\x4f\x6e\x4e\xa7\xf9\x99\x6b\x4b\x8b\x73\xe5"
        "\x6b\x27\x67\x8a\x95\xb9\xc2\xfc\xe2\x74\x61\xba\xbc\x70\xb5\x30\x5b"
        "\x2e\xcf\x96\x8a\x85\xe9\xf2\xfc\x56\xdf\x57\x2a\x97\xaf\x8e\x4f\xc4"
        "\xe2\xf5\xb1\x6a\xb1\x52\x1d\xab\x2c\x2d\x5f\x98\x2f\x2f\x5e\xa9\x5e"
        "\xb8\x3c\x3f\x35\x5b\xbc\x50\xf4\x57\x46\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x60\xa3\xca\xd2\xf2\xdc\x54\xa9\x54"
        "\x5c\x18\xc4\x44\x12\x71\x6b\x93\x6d\xf6\x65\xfb\xa8\x1f\xaa\xba\x59"
        "\x22\x1f\x11\xdb\xf8\x78\x12\x49\x3d\xbc\x3e\x89\x62\xb9\x79\x48\xf6"
        "\x4b\x7d\xba\x49\xa4\x87\x48\x1f\x54\x63\x37\x12\xbd\x1a\x91\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x60\xa3\x7f\x02\x00\x00\xff\xff\x37\x81\x2d\xb2",
        1457);
    syz_mount_image(/*fs=*/0x20000000, /*dir=*/0x20000580, /*flags=*/0,
                    /*opts=*/0x20000040, /*chdir=*/0, /*size=*/0x5b1,
                    /*img=*/0x20000b80);
    break;
  }
}
int main(void)
{
  syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000ul, /*prot=*/0ul,
          /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
          /*offset=*/0ul);
  syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul,
          /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
          /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
          /*offset=*/0ul);
  syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul, /*prot=*/0ul,
          /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1,
          /*offset=*/0ul);
  use_temporary_dir();
  loop();
  return 0;
}






[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux