// https://syzkaller.appspot.com/bug?id=5ac24a3c5711973c287882c9539f095ac817a309 // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static unsigned long long procid; static __thread int clone_ongoing; static __thread int skip_segv; static __thread jmp_buf segv_env; static void segv_handler(int sig, siginfo_t* info, void* ctx) { if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) { exit(sig); } uintptr_t addr = (uintptr_t)info->si_addr; const uintptr_t prog_start = 1 << 20; const uintptr_t prog_end = 100 << 20; int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0; int valid = addr < prog_start || addr > prog_end; if (sig == SIGBUS) valid = 1; if (skip && valid) { _longjmp(segv_env, 1); } exit(sig); } static void install_segv_handler(void) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = segv_handler; sa.sa_flags = SA_NODEFER | SA_SIGINFO; sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); } #define NONFAILING(...) \ ({ \ int ok = 1; \ __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \ if (_setjmp(segv_env) == 0) { \ __VA_ARGS__; \ } else \ ok = 0; \ __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \ ok; \ }) static void kill_and_wait(int pid, int* status) { kill(pid, SIGKILL); while (waitpid(-1, status, 0) != pid) { } } 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 reset_flags(const char* filename) { struct stat st; if (lstat(filename, &st)) exit(1); st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE | SF_APPEND | UF_APPEND); if (lchflags(filename, st.st_flags)) exit(1); } static void __attribute__((noinline)) remove_dir(const char* dir) { DIR* dp = opendir(dir); if (dp == NULL) { if (errno == EACCES) { if (rmdir(dir)) exit(1); return; } 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); struct stat st; if (lstat(filename, &st)) exit(1); if (S_ISDIR(st.st_mode)) { remove_dir(filename); continue; } if (unlink(filename)) { if (errno == EPERM) { reset_flags(filename); reset_flags(dir); if (unlink(filename) == 0) continue; } exit(1); } } closedir(dp); while (rmdir(dir)) { if (errno == EPERM) { reset_flags(dir); if (rmdir(dir) == 0) break; } 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 { pthread_mutex_t mu; pthread_cond_t cv; int state; } event_t; static void event_init(event_t* ev) { if (pthread_mutex_init(&ev->mu, 0)) exit(1); if (pthread_cond_init(&ev->cv, 0)) exit(1); ev->state = 0; } static void event_reset(event_t* ev) { ev->state = 0; } static void event_set(event_t* ev) { pthread_mutex_lock(&ev->mu); if (ev->state) exit(1); ev->state = 1; pthread_mutex_unlock(&ev->mu); pthread_cond_broadcast(&ev->cv); } static void event_wait(event_t* ev) { pthread_mutex_lock(&ev->mu); while (!ev->state) pthread_cond_wait(&ev->cv, &ev->mu); pthread_mutex_unlock(&ev->mu); } static int event_isset(event_t* ev) { pthread_mutex_lock(&ev->mu); int res = ev->state; pthread_mutex_unlock(&ev->mu); return res; } static int event_timedwait(event_t* ev, uint64_t timeout) { uint64_t start = current_time_ms(); uint64_t now = start; pthread_mutex_lock(&ev->mu); for (;;) { if (ev->state) break; uint64_t remain = timeout - (now - start); struct timespec ts; ts.tv_sec = remain / 1000; ts.tv_nsec = (remain % 1000) * 1000 * 1000; pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); now = current_time_ms(); if (now - start > timeout) break; } int res = ev->state; pthread_mutex_unlock(&ev->mu); return res; } 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) { if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { } int i, call, thread; for (call = 0; call < 23; 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); event_timedwait(&th->done, 50); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); #define WAIT_FLAGS 0 static void loop(void) { int iter = 0; for (;; iter++) { char cwdbuf[32]; sprintf(cwdbuf, "./%d", iter); if (mkdir(cwdbuf, 0777)) exit(1); int pid = fork(); if (pid < 0) exit(1); if (pid == 0) { if (chdir(cwdbuf)) exit(1); execute_one(); exit(0); } int status = 0; uint64_t start = current_time_ms(); for (;;) { sleep_ms(10); if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; if (current_time_ms() - start < 5000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } uint64_t r[6] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}; void execute_call(int call) { intptr_t res = 0; switch (call) { case 0: // socket arguments: [ // domain: socket_domain = 0x11 (8 bytes) // type: socket_type = 0x3 (8 bytes) // proto: int8 = 0x0 (1 bytes) // ] // returns sock syscall(SYS_socket, /*domain=AF_APPLETALK|AF_UNIX*/ 0x11ul, /*type=SOCK_RAW*/ 3ul, /*proto=*/0); break; case 1: // sendmsg arguments: [ // fd: sock (resource) // msg: ptr[in, send_msghdr] { // send_msghdr { // msg_name: nil // msg_namelen: len = 0x0 (4 bytes) // pad = 0x0 (4 bytes) // msg_iov: ptr[in, array[iovec_in]] { // array[iovec_in] { // iovec_in { // addr: ptr[in, buffer] { // buffer: {} (length 0x0) // } // len: len = 0x0 (8 bytes) // } // } // } // msg_iovlen: len = 0x1 (8 bytes) // msg_control: nil // msg_controllen: bytesize = 0x0 (8 bytes) // msg_flags: const = 0x0 (4 bytes) // pad = 0x0 (4 bytes) // } // } // f: send_flags = 0x0 (8 bytes) // ] NONFAILING(*(uint64_t*)0x2000000005c0 = 0); NONFAILING(*(uint32_t*)0x2000000005c8 = 0); NONFAILING(*(uint64_t*)0x2000000005d0 = 0x200000000380); NONFAILING(*(uint64_t*)0x200000000380 = 0x200000000040); NONFAILING(*(uint64_t*)0x200000000388 = 0); NONFAILING(*(uint64_t*)0x2000000005d8 = 1); NONFAILING(*(uint64_t*)0x2000000005e0 = 0); NONFAILING(*(uint64_t*)0x2000000005e8 = 0); NONFAILING(*(uint32_t*)0x2000000005f0 = 0); syscall(SYS_sendmsg, /*fd=*/(intptr_t)-1, /*msg=*/0x2000000005c0ul, /*f=*/0ul); break; case 2: // open$dir arguments: [ // file: ptr[in, buffer] { // buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8) // } // flags: open_flags = 0x40000400000002c2 (8 bytes) // mode: open_mode = 0x0 (8 bytes) // ] // returns fd_dir NONFAILING(memcpy((void*)0x200000000840, "./file1\000", 8)); syscall(SYS_open, /*file=*/0x200000000840ul, /*flags=O_SYNC|O_CREAT|FASYNC|O_RDWR|0x4000040000000000*/ 0x40000400000002c2ul, /*mode=*/0ul); break; case 3: // freebsd11_mknod arguments: [ // file: ptr[in, buffer] { // buffer: {2e 2f 66 69 6c 65 30 00} (length 0x8) // } // mod: mknod_mode = 0x1000 (8 bytes) // dev: int32 = 0x0 (4 bytes) // ] NONFAILING(memcpy((void*)0x200000000040, "./file0\000", 8)); syscall(SYS_freebsd11_mknod, /*file=*/0x200000000040ul, /*mod=S_IFIFO*/ 0x1000ul, /*dev=*/0); break; case 4: // socket$inet6_sctp arguments: [ // domain: const = 0x1c (8 bytes) // type: sctp_socket_type = 0x5 (8 bytes) // proto: const = 0x84 (1 bytes) // ] // returns sock_sctp6 syscall(SYS_socket, /*domain=*/0x1cul, /*type=SOCK_SEQPACKET*/ 5ul, /*proto=*/0x84); break; case 5: // open$dir arguments: [ // file: ptr[in, buffer] { // buffer: {2e 2f 66 69 6c 65 30 00} (length 0x8) // } // flags: open_flags = 0x1 (8 bytes) // mode: open_mode = 0x0 (8 bytes) // ] // returns fd_dir NONFAILING(memcpy((void*)0x200000000000, "./file0\000", 8)); res = syscall(SYS_open, /*file=*/0x200000000000ul, /*flags=O_WRONLY*/ 1ul, /*mode=*/0ul); if (res != -1) r[0] = res; break; case 6: // close arguments: [ // fd: fd (resource) // ] syscall(SYS_close, /*fd=*/(intptr_t)-1); break; case 7: // writev arguments: [ // fd: fd (resource) // vec: nil // vlen: len = 0x0 (8 bytes) // ] syscall(SYS_writev, /*fd=*/r[0], /*vec=*/0ul, /*vlen=*/0ul); break; case 8: // open arguments: [ // file: ptr[in, buffer] { // buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8) // } // flags: open_flags = 0x4 (8 bytes) // mode: open_mode = 0x102 (8 bytes) // ] // returns fd NONFAILING(memcpy((void*)0x200000000480, "./file1\000", 8)); syscall(SYS_open, /*file=*/0x200000000480ul, /*flags=O_NONBLOCK*/ 4ul, /*mode=S_IWOTH|S_IRUSR*/ 0x102ul); break; case 9: // mprotect arguments: [ // addr: VMA[0x800000] // len: len = 0x800000 (8 bytes) // prot: mmap_prot = 0x5 (8 bytes) // ] syscall(SYS_mprotect, /*addr=*/0x200000000000ul, /*len=*/0x800000ul, /*prot=PROT_READ|PROT_EXEC*/ 5ul); break; case 10: // truncate arguments: [ // file: ptr[in, buffer] { // buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8) // } // len: intptr = 0x1 (8 bytes) // ] NONFAILING(memcpy((void*)0x200000000440, "./file1\000", 8)); syscall(SYS_truncate, /*file=*/0x200000000440ul, /*len=*/1ul); break; case 11: // mount arguments: [ // type: nil // path: nil // flags: mount_flags = 0x0 (8 bytes) // data: nil // ] syscall(SYS_mount, /*type=*/0ul, /*path=*/0ul, /*flags=*/0ul, /*data=*/0ul); break; case 12: // freebsd10_pipe arguments: [ // pipefd: ptr[out, pipefd] { // pipefd { // rfd: fd (resource) // wfd: fd (resource) // } // } // ] res = syscall(SYS_freebsd10_pipe, /*pipefd=*/0x200000000040ul); if (res != -1) NONFAILING(r[1] = *(uint32_t*)0x200000000044); break; case 13: // mprotect arguments: [ // addr: VMA[0x800000] // len: len = 0x800000 (8 bytes) // prot: mmap_prot = 0x1 (8 bytes) // ] syscall(SYS_mprotect, /*addr=*/0x200000000000ul, /*len=*/0x800000ul, /*prot=PROT_READ*/ 1ul); break; case 14: // socket$inet6_udp arguments: [ // domain: const = 0x1c (8 bytes) // type: const = 0x2 (8 bytes) // proto: const = 0x0 (1 bytes) // ] // returns sock_udp6 res = syscall(SYS_socket, /*domain=*/0x1cul, /*type=*/2ul, /*proto=*/0); if (res != -1) r[2] = res; break; case 15: // setsockopt$inet6_IPV6_DSTOPTS arguments: [ // fd: sock_in6 (resource) // level: const = 0x29 (4 bytes) // optname: const = 0x32 (4 bytes) // optval: ptr[inout, array[ANYUNION]] { // array[ANYUNION] { // } // } // optlen: len = 0x8 (8 bytes) // ] syscall(SYS_setsockopt, /*fd=*/r[2], /*level=*/0x29, /*optname=*/0x32, /*optval=*/0x200000000300ul, /*optlen=*/8ul); break; case 16: // getsockopt$inet6_buf arguments: [ // fd: sock_in6 (resource) // level: const = 0x29 (4 bytes) // optname: inet6_option_types_buf = 0x32 (4 bytes) // optval: ptr[out, buffer] { // buffer: (DirOut) // } // optlen: ptr[inout, len] { // len = 0x1000 (4 bytes) // } // ] NONFAILING(*(uint32_t*)0x200000000000 = 0x1000); syscall(SYS_getsockopt, /*fd=*/r[2], /*level=*/0x29, /*optname=IPV6_DSTOPTS*/ 0x32, /*optval=*/0x200000001040ul, /*optlen=*/0x200000000000ul); break; case 17: // aio_waitcomplete arguments: [ // iocbp: ptr[out, ptr[in, aiocb]] { // ptr[in, aiocb] { // aiocb { // aio_fildes: fd (resource) // pad = 0x0 (4 bytes) // aio_offset: int64 = 0xffffffffffffffff (8 bytes) // aio_buf: nil // aio_nbytes: len = 0x0 (8 bytes) // spare: array[int32] { // int32 = 0x1 (4 bytes) // int32 = 0xe7 (4 bytes) // } // spare2: intptr = 0x3 (8 bytes) // aio_lio_opcode: lio_opcodes = 0xf470d7943015b589 (4 bytes) // aio_reqprio: int32 = 0x0 (4 bytes) // aiocb_private: aiocb_private { // status: intptr = 0x2 (8 bytes) // error: intptr = 0x7 (8 bytes) // kernelinfo: ptr[in, buffer] { // buffer: {6d 84 e3 85 20 18 fe 29 3d 32 f2 24 bc 15 0d ae 4e // 5f fb 70 6b c2 5e f2 ae 80 8b 6d 11 73 93 e2 d6 91 64 6b 89 // 56 e9 1f e6 18 18 eb e0 6a 39 5d da 2f 2e c0 b9 79 bf a3 54 // 59 e5 f6 27 a7 08 e8 2c a0 a7 c8 ae 18 ac ab 2e 1f 3f 57 fe // d1 ee 7d 37 ac 03 cc b6 26 0b 99 a1 97 1e 7d 3e fb 76 af 1c // 15 b5 1d 03 a8 f2 ed 85 94 09 fd bc 92 c1 e5 4b 58 4a 5e c5 // 62 ae b1 79 a1 4f 17 34 4f 77 e1 6b c9 68 55 08 6b c6 15 30 // 26 eb 34 62 ed e9 a6 ae ef 78 bd 5f c6 16 d1 29 e1 7a 81 37 // 26 f4 11 f2 d3} (length 0xa2) // } // } // aio_sigevent: sigevent { // notify: sigev_notify = 0x0 (4 bytes) // signo: int32 = 0x1a (4 bytes) // val: union sigval { // sigval_int: int32 = 0xa0a0 (4 bytes) // } // u: union sigevent_u { // spare: array[intptr] { // intptr = 0x31 (8 bytes) // intptr = 0x2 (8 bytes) // intptr = 0x80000001 (8 bytes) // intptr = 0x7 (8 bytes) // intptr = 0x5 (8 bytes) // intptr = 0x0 (8 bytes) // intptr = 0x1 (8 bytes) // intptr = 0x3 (8 bytes) // } // } // } // } // } // } // timeout: nil // ] NONFAILING(*(uint64_t*)0x200000000340 = 0x200000000280); NONFAILING(*(uint32_t*)0x200000000280 = r[1]); NONFAILING(*(uint64_t*)0x200000000288 = -1); NONFAILING(*(uint64_t*)0x200000000290 = 0); NONFAILING(*(uint64_t*)0x200000000298 = 0); NONFAILING(*(uint32_t*)0x2000000002a0 = 1); NONFAILING(*(uint32_t*)0x2000000002a4 = 0xe7); NONFAILING(*(uint64_t*)0x2000000002a8 = 3); NONFAILING(*(uint32_t*)0x2000000002b0 = 0x3015b589); NONFAILING(*(uint32_t*)0x2000000002b4 = 0); NONFAILING(*(uint64_t*)0x2000000002b8 = 2); NONFAILING(*(uint64_t*)0x2000000002c0 = 7); NONFAILING(*(uint64_t*)0x2000000002c8 = 0x2000000001c0); NONFAILING(memcpy( (void*)0x2000000001c0, "\x6d\x84\xe3\x85\x20\x18\xfe\x29\x3d\x32\xf2\x24\xbc\x15\x0d\xae\x4e" "\x5f\xfb\x70\x6b\xc2\x5e\xf2\xae\x80\x8b\x6d\x11\x73\x93\xe2\xd6\x91" "\x64\x6b\x89\x56\xe9\x1f\xe6\x18\x18\xeb\xe0\x6a\x39\x5d\xda\x2f\x2e" "\xc0\xb9\x79\xbf\xa3\x54\x59\xe5\xf6\x27\xa7\x08\xe8\x2c\xa0\xa7\xc8" "\xae\x18\xac\xab\x2e\x1f\x3f\x57\xfe\xd1\xee\x7d\x37\xac\x03\xcc\xb6" "\x26\x0b\x99\xa1\x97\x1e\x7d\x3e\xfb\x76\xaf\x1c\x15\xb5\x1d\x03\xa8" "\xf2\xed\x85\x94\x09\xfd\xbc\x92\xc1\xe5\x4b\x58\x4a\x5e\xc5\x62\xae" "\xb1\x79\xa1\x4f\x17\x34\x4f\x77\xe1\x6b\xc9\x68\x55\x08\x6b\xc6\x15" "\x30\x26\xeb\x34\x62\xed\xe9\xa6\xae\xef\x78\xbd\x5f\xc6\x16\xd1\x29" "\xe1\x7a\x81\x37\x26\xf4\x11\xf2\xd3", 162)); NONFAILING(*(uint32_t*)0x2000000002d0 = 0); NONFAILING(*(uint32_t*)0x2000000002d4 = 0x1a); NONFAILING(*(uint32_t*)0x2000000002d8 = 0xa0a0); NONFAILING(*(uint64_t*)0x2000000002e0 = 0x31); NONFAILING(*(uint64_t*)0x2000000002e8 = 2); NONFAILING(*(uint64_t*)0x2000000002f0 = 0x80000001); NONFAILING(*(uint64_t*)0x2000000002f8 = 7); NONFAILING(*(uint64_t*)0x200000000300 = 5); NONFAILING(*(uint64_t*)0x200000000308 = 0); NONFAILING(*(uint64_t*)0x200000000310 = 1); NONFAILING(*(uint64_t*)0x200000000318 = 3); syscall(SYS_aio_waitcomplete, /*iocbp=*/0x200000000340ul, /*timeout=*/0ul); break; case 18: // openat$crypto arguments: [ // fd: const = 0xffffffffffffff9c (8 bytes) // file: nil // flags: open_flags = 0x0 (8 bytes) // mode: const = 0x0 (8 bytes) // ] // returns fd_crypto res = syscall(SYS_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0ul, /*flags=*/0ul, /*mode=*/0ul); if (res != -1) r[3] = res; break; case 19: // openat$crypto arguments: [ // fd: const = 0xffffffffffffff9c (8 bytes) // file: ptr[in, buffer] { // buffer: {2f 64 65 76 2f 63 72 79 70 74 6f 00} (length 0xc) // } // flags: open_flags = 0x8 (8 bytes) // mode: const = 0x0 (8 bytes) // ] // returns fd_crypto NONFAILING(memcpy((void*)0x200000000240, "/dev/crypto\000", 12)); res = syscall(SYS_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0x200000000240ul, /*flags=O_APPEND*/ 8ul, /*mode=*/0ul); if (res != -1) r[4] = res; break; case 20: // ioctl$CIOCGSESSION2 arguments: [ // fd: fd_crypto (resource) // cmd: const = 0xc040636a (8 bytes) // arg: ptr[inout, session2_op] { // session2_op { // cipher: cipher_flags = 0x19 (4 bytes) // mac: mac_flags = 0x0 (4 bytes) // keylen: bytesize = 0x10 (4 bytes) // pad = 0x0 (4 bytes) // key: ptr[in, buffer] { // buffer: {3c 9e 89 52 6b 1f 00 b0 7f 8a ee 18 e5 aa 35 05} // (length 0x10) // } // mackeylen: bytesize = 0x0 (4 bytes) // pad = 0x0 (4 bytes) // mackey: nil // ses: int32 = 0x0 (4 bytes) // crid: int32 = 0xfdffffff (4 bytes) // pad: array[int32] { // int32 = 0x0 (4 bytes) // int32 = 0x0 (4 bytes) // int32 = 0x3 (4 bytes) // int32 = 0x80000001 (4 bytes) // } // } // } // ] NONFAILING(*(uint32_t*)0x200000000440 = 0x19); NONFAILING(*(uint32_t*)0x200000000444 = 0); NONFAILING(*(uint32_t*)0x200000000448 = 0x10); NONFAILING(*(uint64_t*)0x200000000450 = 0x200000000200); NONFAILING(memcpy( (void*)0x200000000200, "\x3c\x9e\x89\x52\x6b\x1f\x00\xb0\x7f\x8a\xee\x18\xe5\xaa\x35\x05", 16)); NONFAILING(*(uint32_t*)0x200000000458 = 0); NONFAILING(*(uint64_t*)0x200000000460 = 0); NONFAILING(*(uint32_t*)0x200000000468 = 0); NONFAILING(*(uint32_t*)0x20000000046c = 0xfdffffff); NONFAILING(*(uint32_t*)0x200000000470 = 0); NONFAILING(*(uint32_t*)0x200000000474 = 0); NONFAILING(*(uint32_t*)0x200000000478 = 3); NONFAILING(*(uint32_t*)0x20000000047c = 0x80000001); syscall(SYS_ioctl, /*fd=*/r[4], /*cmd=*/0xc040636aul, /*arg=*/0x200000000440ul); break; case 21: // fcntl$dupfd arguments: [ // fd: fd (resource) // cmd: fcntl_dupfd = 0x11 (8 bytes) // arg: fd (resource) // ] // returns fd res = syscall(SYS_fcntl, /*fd=*/r[4], /*cmd=F_DUPFD_CLOEXEC*/ 0x11ul, /*arg=*/r[3]); if (res != -1) r[5] = res; break; case 22: // ioctl$CIOCCRYPT arguments: [ // fd: fd_crypto (resource) // cmd: const = 0xc0306367 (8 bytes) // arg: ptr[inout, crypt_op] { // crypt_op { // ses: int32 = 0x0 (4 bytes) // op: op_flags = 0x2 (2 bytes) // flags: int16 = 0x100 (2 bytes) // len: int32 = 0x12 (4 bytes) // pad = 0x0 (4 bytes) // src: nil // dst: nil // mac: nil // iv: ptr[in, buffer] { // buffer: {} (length 0x0) // } // } // } // ] NONFAILING(*(uint32_t*)0x200000000080 = 0); NONFAILING(*(uint16_t*)0x200000000084 = 2); NONFAILING(*(uint16_t*)0x200000000086 = 0x100); NONFAILING(*(uint32_t*)0x200000000088 = 0x12); NONFAILING(*(uint64_t*)0x200000000090 = 0); NONFAILING(*(uint64_t*)0x200000000098 = 0); NONFAILING(*(uint64_t*)0x2000000000a0 = 0); NONFAILING(*(uint64_t*)0x2000000000a8 = 0x200000000000); syscall(SYS_ioctl, /*fd=*/r[5], /*cmd=*/0xc0306367ul, /*arg=*/0x200000000080ul); break; } } int main(void) { syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul); const char* reason; (void)reason; install_segv_handler(); for (procid = 0; procid < 4; procid++) { if (fork() == 0) { use_temporary_dir(); loop(); } } sleep(1000000); return 0; }