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