1cbc3ecb7SPeter Holm#!/bin/sh 2cbc3ecb7SPeter Holm 3cbc3ecb7SPeter Holm# panic: ASan: Invalid access, 32-byte read at 0xfffffe01f76145a0, UseAfterScope(f8) 4cbc3ecb7SPeter Holm# cpuid = 3 5cbc3ecb7SPeter Holm# time = 1635158022 6cbc3ecb7SPeter Holm# KDB: stack backtrace: 7cbc3ecb7SPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0xa5/frame 0xfffffe01f7614170 8cbc3ecb7SPeter Holm# kdb_backtrace() at kdb_backtrace+0xc9/frame 0xfffffe01f76142d0 9cbc3ecb7SPeter Holm# vpanic() at vpanic+0x248/frame 0xfffffe01f76143b0 10cbc3ecb7SPeter Holm# panic() at panic+0xb5/frame 0xfffffe01f7614480 11cbc3ecb7SPeter Holm# __asan_storeN() at __asan_storeN/frame 0xfffffe01f7614550 12cbc3ecb7SPeter Holm# smp_masked_invlpg_range() at smp_masked_invlpg_range+0xb2/frame 0xfffffe01f7614630 13cbc3ecb7SPeter Holm# pmap_invalidate_range() at pmap_invalidate_range+0x22b/frame 0xfffffe01f7614730 14cbc3ecb7SPeter Holm# vm_thread_stack_create() at vm_thread_stack_create+0xf5/frame 0xfffffe01f7614910 15cbc3ecb7SPeter Holm# kstack_import() at kstack_import+0xcache_alloc() at cache_alloc+0x556/frame 0xfffffe01f7614a10 16cbc3ecb7SPeter Holm# cache_alloc_retry() at cache_alloc_retry+0x30/frame 0xfffffe01f7614a80 17cbc3ecb7SPeter Holm# vm_thread_new() at vm_thread_new+0x61/frame 0xfffffe01f7614ab0 18cbc3ecb7SPeter Holm# thread_alloc() at thread_alloc+0x5f/frame 0xfffffe01f7614af0 19cbc3ecb7SPeter Holm# thread_create() at thread_create+0x1b3/frame 0xfffffe01f7614bf0 20cbc3ecb7SPeter Holm# sys_thr_new() at sys_thr_new+0x15a/framd30 21cbc3ecb7SPeter Holm# amd64_syscall() at amd64_syscall+0x31e/frame 0xfffffe01f7614f30 22cbc3ecb7SPeter Holm# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01f7614f30 23cbc3ecb7SPeter Holm# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x8003afafa, rsp = 0x7fffdfffdf58, rbp = 0x7fffdfffdf70 --- 24cbc3ecb7SPeter Holm# KDB: enter: panic 25cbc3ecb7SPeter Holm# [ thread pid 69407 tid 100937 ] 26cbc3ecb7SPeter Holm# Stopped at kdb_enter+0x37: movq $0,0x2638c4e(%rip) 27cbc3ecb7SPeter Holm# db> x/s version 28cbc3ecb7SPeter Holm# version: FreeBSD 14.0-CURRENT #0 main-n250242-eab5358b9080-dirty: Mon Oct 25 11:32:45 CEST 2021 29cbc3ecb7SPeter Holm# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO-KASAN 30cbc3ecb7SPeter Holm# db> 31cbc3ecb7SPeter Holm 32cbc3ecb7SPeter Holm[ `uname -p` != "amd64" ] && exit 0 33cbc3ecb7SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 34cbc3ecb7SPeter Holm[ "`sysctl -in kern.features.kasan`" != "1" ] && exit 0 35cbc3ecb7SPeter Holm 36cbc3ecb7SPeter Holm. ../default.cfg 37cbc3ecb7SPeter Holmcat > /tmp/syzkaller47.c <<EOF 38cbc3ecb7SPeter Holm// https://syzkaller.appspot.com/bug?id=5676c1c4b457596c1a8782e4a8533f4e9ff2aa0e 39cbc3ecb7SPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller) 40cbc3ecb7SPeter Holm// Reported-by: syzbot+a5898c11651b423b501f@syzkaller.appspotmail.com 41cbc3ecb7SPeter Holm 42cbc3ecb7SPeter Holm#define _GNU_SOURCE 43cbc3ecb7SPeter Holm 44cbc3ecb7SPeter Holm#include <sys/types.h> 45cbc3ecb7SPeter Holm 46cbc3ecb7SPeter Holm#include <dirent.h> 47cbc3ecb7SPeter Holm#include <errno.h> 48cbc3ecb7SPeter Holm#include <pthread.h> 49cbc3ecb7SPeter Holm#include <pwd.h> 50cbc3ecb7SPeter Holm#include <setjmp.h> 51cbc3ecb7SPeter Holm#include <signal.h> 52cbc3ecb7SPeter Holm#include <stdarg.h> 53cbc3ecb7SPeter Holm#include <stdbool.h> 54cbc3ecb7SPeter Holm#include <stdint.h> 55cbc3ecb7SPeter Holm#include <stdio.h> 56cbc3ecb7SPeter Holm#include <stdlib.h> 57cbc3ecb7SPeter Holm#include <string.h> 58cbc3ecb7SPeter Holm#include <sys/endian.h> 59cbc3ecb7SPeter Holm#include <sys/resource.h> 60cbc3ecb7SPeter Holm#include <sys/stat.h> 61cbc3ecb7SPeter Holm#include <sys/syscall.h> 62cbc3ecb7SPeter Holm#include <sys/wait.h> 63cbc3ecb7SPeter Holm#include <time.h> 64cbc3ecb7SPeter Holm#include <unistd.h> 65cbc3ecb7SPeter Holm 66cbc3ecb7SPeter Holmstatic __thread int skip_segv; 67cbc3ecb7SPeter Holmstatic __thread jmp_buf segv_env; 68cbc3ecb7SPeter Holm 69cbc3ecb7SPeter Holmstatic void segv_handler(int sig, siginfo_t* info, void* ctx __unused) 70cbc3ecb7SPeter Holm{ 71cbc3ecb7SPeter Holm uintptr_t addr = (uintptr_t)info->si_addr; 72cbc3ecb7SPeter Holm const uintptr_t prog_start = 1 << 20; 73cbc3ecb7SPeter Holm const uintptr_t prog_end = 100 << 20; 74cbc3ecb7SPeter Holm int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0; 75cbc3ecb7SPeter Holm int valid = addr < prog_start || addr > prog_end; 76cbc3ecb7SPeter Holm if (sig == SIGBUS) 77cbc3ecb7SPeter Holm valid = 1; 78cbc3ecb7SPeter Holm if (skip && valid) { 79cbc3ecb7SPeter Holm _longjmp(segv_env, 1); 80cbc3ecb7SPeter Holm } 81cbc3ecb7SPeter Holm exit(sig); 82cbc3ecb7SPeter Holm} 83cbc3ecb7SPeter Holm 84cbc3ecb7SPeter Holmstatic void install_segv_handler(void) 85cbc3ecb7SPeter Holm{ 86cbc3ecb7SPeter Holm struct sigaction sa; 87cbc3ecb7SPeter Holm memset(&sa, 0, sizeof(sa)); 88cbc3ecb7SPeter Holm sa.sa_sigaction = segv_handler; 89cbc3ecb7SPeter Holm sa.sa_flags = SA_NODEFER | SA_SIGINFO; 90cbc3ecb7SPeter Holm sigaction(SIGSEGV, &sa, NULL); 91cbc3ecb7SPeter Holm sigaction(SIGBUS, &sa, NULL); 92cbc3ecb7SPeter Holm} 93cbc3ecb7SPeter Holm 94cbc3ecb7SPeter Holm#define NONFAILING(...) \ 95cbc3ecb7SPeter Holm ({ \ 96cbc3ecb7SPeter Holm int ok = 1; \ 97cbc3ecb7SPeter Holm __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \ 98cbc3ecb7SPeter Holm if (_setjmp(segv_env) == 0) { \ 99cbc3ecb7SPeter Holm __VA_ARGS__; \ 100cbc3ecb7SPeter Holm } else \ 101cbc3ecb7SPeter Holm ok = 0; \ 102cbc3ecb7SPeter Holm __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \ 103cbc3ecb7SPeter Holm ok; \ 104cbc3ecb7SPeter Holm }) 105cbc3ecb7SPeter Holm 106cbc3ecb7SPeter Holmstatic void kill_and_wait(int pid, int* status) 107cbc3ecb7SPeter Holm{ 108cbc3ecb7SPeter Holm kill(pid, SIGKILL); 109cbc3ecb7SPeter Holm while (waitpid(-1, status, 0) != pid) { 110cbc3ecb7SPeter Holm } 111cbc3ecb7SPeter Holm} 112cbc3ecb7SPeter Holm 113cbc3ecb7SPeter Holmstatic void sleep_ms(uint64_t ms) 114cbc3ecb7SPeter Holm{ 115cbc3ecb7SPeter Holm usleep(ms * 1000); 116cbc3ecb7SPeter Holm} 117cbc3ecb7SPeter Holm 118cbc3ecb7SPeter Holmstatic uint64_t current_time_ms(void) 119cbc3ecb7SPeter Holm{ 120cbc3ecb7SPeter Holm struct timespec ts; 121cbc3ecb7SPeter Holm if (clock_gettime(CLOCK_MONOTONIC, &ts)) 122cbc3ecb7SPeter Holm exit(1); 123cbc3ecb7SPeter Holm return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 124cbc3ecb7SPeter Holm} 125cbc3ecb7SPeter Holm 126cbc3ecb7SPeter Holmstatic void use_temporary_dir(void) 127cbc3ecb7SPeter Holm{ 128cbc3ecb7SPeter Holm char tmpdir_template[] = "./syzkaller.XXXXXX"; 129cbc3ecb7SPeter Holm char* tmpdir = mkdtemp(tmpdir_template); 130cbc3ecb7SPeter Holm if (!tmpdir) 131cbc3ecb7SPeter Holm exit(1); 132cbc3ecb7SPeter Holm if (chmod(tmpdir, 0777)) 133cbc3ecb7SPeter Holm exit(1); 134cbc3ecb7SPeter Holm if (chdir(tmpdir)) 135cbc3ecb7SPeter Holm exit(1); 136cbc3ecb7SPeter Holm} 137cbc3ecb7SPeter Holm 138cbc3ecb7SPeter Holmstatic void __attribute__((noinline)) remove_dir(const char* dir) 139cbc3ecb7SPeter Holm{ 140cbc3ecb7SPeter Holm DIR* dp = opendir(dir); 141cbc3ecb7SPeter Holm if (dp == NULL) { 142cbc3ecb7SPeter Holm if (errno == EACCES) { 143cbc3ecb7SPeter Holm if (rmdir(dir)) 144cbc3ecb7SPeter Holm exit(1); 145cbc3ecb7SPeter Holm return; 146cbc3ecb7SPeter Holm } 147cbc3ecb7SPeter Holm exit(1); 148cbc3ecb7SPeter Holm } 149cbc3ecb7SPeter Holm struct dirent* ep = 0; 150cbc3ecb7SPeter Holm while ((ep = readdir(dp))) { 151cbc3ecb7SPeter Holm if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) 152cbc3ecb7SPeter Holm continue; 153cbc3ecb7SPeter Holm char filename[FILENAME_MAX]; 154cbc3ecb7SPeter Holm snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name); 155cbc3ecb7SPeter Holm struct stat st; 156cbc3ecb7SPeter Holm if (lstat(filename, &st)) 157cbc3ecb7SPeter Holm exit(1); 158cbc3ecb7SPeter Holm if (S_ISDIR(st.st_mode)) { 159cbc3ecb7SPeter Holm remove_dir(filename); 160cbc3ecb7SPeter Holm continue; 161cbc3ecb7SPeter Holm } 162cbc3ecb7SPeter Holm if (unlink(filename)) 163cbc3ecb7SPeter Holm exit(1); 164cbc3ecb7SPeter Holm } 165cbc3ecb7SPeter Holm closedir(dp); 166cbc3ecb7SPeter Holm if (rmdir(dir)) 167cbc3ecb7SPeter Holm exit(1); 168cbc3ecb7SPeter Holm} 169cbc3ecb7SPeter Holm 170cbc3ecb7SPeter Holmstatic void thread_start(void* (*fn)(void*), void* arg) 171cbc3ecb7SPeter Holm{ 172cbc3ecb7SPeter Holm pthread_t th; 173cbc3ecb7SPeter Holm pthread_attr_t attr; 174cbc3ecb7SPeter Holm pthread_attr_init(&attr); 175cbc3ecb7SPeter Holm pthread_attr_setstacksize(&attr, 128 << 10); 176cbc3ecb7SPeter Holm int i = 0; 177cbc3ecb7SPeter Holm for (; i < 100; i++) { 178cbc3ecb7SPeter Holm if (pthread_create(&th, &attr, fn, arg) == 0) { 179cbc3ecb7SPeter Holm pthread_attr_destroy(&attr); 180cbc3ecb7SPeter Holm return; 181cbc3ecb7SPeter Holm } 182cbc3ecb7SPeter Holm if (errno == EAGAIN) { 183cbc3ecb7SPeter Holm usleep(50); 184cbc3ecb7SPeter Holm continue; 185cbc3ecb7SPeter Holm } 186cbc3ecb7SPeter Holm break; 187cbc3ecb7SPeter Holm } 188cbc3ecb7SPeter Holm exit(1); 189cbc3ecb7SPeter Holm} 190cbc3ecb7SPeter Holm 191cbc3ecb7SPeter Holmtypedef struct { 192cbc3ecb7SPeter Holm pthread_mutex_t mu; 193cbc3ecb7SPeter Holm pthread_cond_t cv; 194cbc3ecb7SPeter Holm int state; 195cbc3ecb7SPeter Holm} event_t; 196cbc3ecb7SPeter Holm 197cbc3ecb7SPeter Holmstatic void event_init(event_t* ev) 198cbc3ecb7SPeter Holm{ 199cbc3ecb7SPeter Holm if (pthread_mutex_init(&ev->mu, 0)) 200cbc3ecb7SPeter Holm exit(1); 201cbc3ecb7SPeter Holm if (pthread_cond_init(&ev->cv, 0)) 202cbc3ecb7SPeter Holm exit(1); 203cbc3ecb7SPeter Holm ev->state = 0; 204cbc3ecb7SPeter Holm} 205cbc3ecb7SPeter Holm 206cbc3ecb7SPeter Holmstatic void event_reset(event_t* ev) 207cbc3ecb7SPeter Holm{ 208cbc3ecb7SPeter Holm ev->state = 0; 209cbc3ecb7SPeter Holm} 210cbc3ecb7SPeter Holm 211cbc3ecb7SPeter Holmstatic void event_set(event_t* ev) 212cbc3ecb7SPeter Holm{ 213cbc3ecb7SPeter Holm pthread_mutex_lock(&ev->mu); 214cbc3ecb7SPeter Holm if (ev->state) 215cbc3ecb7SPeter Holm exit(1); 216cbc3ecb7SPeter Holm ev->state = 1; 217cbc3ecb7SPeter Holm pthread_mutex_unlock(&ev->mu); 218cbc3ecb7SPeter Holm pthread_cond_broadcast(&ev->cv); 219cbc3ecb7SPeter Holm} 220cbc3ecb7SPeter Holm 221cbc3ecb7SPeter Holmstatic void event_wait(event_t* ev) 222cbc3ecb7SPeter Holm{ 223cbc3ecb7SPeter Holm pthread_mutex_lock(&ev->mu); 224cbc3ecb7SPeter Holm while (!ev->state) 225cbc3ecb7SPeter Holm pthread_cond_wait(&ev->cv, &ev->mu); 226cbc3ecb7SPeter Holm pthread_mutex_unlock(&ev->mu); 227cbc3ecb7SPeter Holm} 228cbc3ecb7SPeter Holm 229cbc3ecb7SPeter Holmstatic int event_isset(event_t* ev) 230cbc3ecb7SPeter Holm{ 231cbc3ecb7SPeter Holm pthread_mutex_lock(&ev->mu); 232cbc3ecb7SPeter Holm int res = ev->state; 233cbc3ecb7SPeter Holm pthread_mutex_unlock(&ev->mu); 234cbc3ecb7SPeter Holm return res; 235cbc3ecb7SPeter Holm} 236cbc3ecb7SPeter Holm 237cbc3ecb7SPeter Holmstatic int event_timedwait(event_t* ev, uint64_t timeout) 238cbc3ecb7SPeter Holm{ 239cbc3ecb7SPeter Holm uint64_t start = current_time_ms(); 240cbc3ecb7SPeter Holm uint64_t now = start; 241cbc3ecb7SPeter Holm pthread_mutex_lock(&ev->mu); 242cbc3ecb7SPeter Holm for (;;) { 243cbc3ecb7SPeter Holm if (ev->state) 244cbc3ecb7SPeter Holm break; 245cbc3ecb7SPeter Holm uint64_t remain = timeout - (now - start); 246cbc3ecb7SPeter Holm struct timespec ts; 247cbc3ecb7SPeter Holm ts.tv_sec = remain / 1000; 248cbc3ecb7SPeter Holm ts.tv_nsec = (remain % 1000) * 1000 * 1000; 249cbc3ecb7SPeter Holm pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 250cbc3ecb7SPeter Holm now = current_time_ms(); 251cbc3ecb7SPeter Holm if (now - start > timeout) 252cbc3ecb7SPeter Holm break; 253cbc3ecb7SPeter Holm } 254cbc3ecb7SPeter Holm int res = ev->state; 255cbc3ecb7SPeter Holm pthread_mutex_unlock(&ev->mu); 256cbc3ecb7SPeter Holm return res; 257cbc3ecb7SPeter Holm} 258cbc3ecb7SPeter Holm 259cbc3ecb7SPeter Holmstatic void sandbox_common() 260cbc3ecb7SPeter Holm{ 261cbc3ecb7SPeter Holm struct rlimit rlim; 262cbc3ecb7SPeter Holm rlim.rlim_cur = rlim.rlim_max = 128 << 20; 263cbc3ecb7SPeter Holm setrlimit(RLIMIT_AS, &rlim); 264cbc3ecb7SPeter Holm rlim.rlim_cur = rlim.rlim_max = 8 << 20; 265cbc3ecb7SPeter Holm setrlimit(RLIMIT_MEMLOCK, &rlim); 266cbc3ecb7SPeter Holm rlim.rlim_cur = rlim.rlim_max = 1 << 20; 267cbc3ecb7SPeter Holm setrlimit(RLIMIT_FSIZE, &rlim); 268cbc3ecb7SPeter Holm rlim.rlim_cur = rlim.rlim_max = 1 << 20; 269cbc3ecb7SPeter Holm setrlimit(RLIMIT_STACK, &rlim); 270cbc3ecb7SPeter Holm rlim.rlim_cur = rlim.rlim_max = 0; 271cbc3ecb7SPeter Holm setrlimit(RLIMIT_CORE, &rlim); 272cbc3ecb7SPeter Holm rlim.rlim_cur = rlim.rlim_max = 256; 273cbc3ecb7SPeter Holm setrlimit(RLIMIT_NOFILE, &rlim); 274cbc3ecb7SPeter Holm} 275cbc3ecb7SPeter Holm 276cbc3ecb7SPeter Holmstatic void loop(); 277cbc3ecb7SPeter Holm 278cbc3ecb7SPeter Holmstatic int do_sandbox_none(void) 279cbc3ecb7SPeter Holm{ 280cbc3ecb7SPeter Holm sandbox_common(); 281cbc3ecb7SPeter Holm loop(); 282cbc3ecb7SPeter Holm return 0; 283cbc3ecb7SPeter Holm} 284cbc3ecb7SPeter Holm 285cbc3ecb7SPeter Holmstruct thread_t { 286cbc3ecb7SPeter Holm int created, call; 287cbc3ecb7SPeter Holm event_t ready, done; 288cbc3ecb7SPeter Holm}; 289cbc3ecb7SPeter Holm 290cbc3ecb7SPeter Holmstatic struct thread_t threads[16]; 291cbc3ecb7SPeter Holmstatic void execute_call(int call); 292cbc3ecb7SPeter Holmstatic int running; 293cbc3ecb7SPeter Holm 294cbc3ecb7SPeter Holmstatic void* thr(void* arg) 295cbc3ecb7SPeter Holm{ 296cbc3ecb7SPeter Holm struct thread_t* th = (struct thread_t*)arg; 297cbc3ecb7SPeter Holm for (;;) { 298cbc3ecb7SPeter Holm event_wait(&th->ready); 299cbc3ecb7SPeter Holm event_reset(&th->ready); 300cbc3ecb7SPeter Holm execute_call(th->call); 301cbc3ecb7SPeter Holm __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 302cbc3ecb7SPeter Holm event_set(&th->done); 303cbc3ecb7SPeter Holm } 304cbc3ecb7SPeter Holm return 0; 305cbc3ecb7SPeter Holm} 306cbc3ecb7SPeter Holm 307cbc3ecb7SPeter Holmstatic void execute_one(void) 308cbc3ecb7SPeter Holm{ 309cbc3ecb7SPeter Holm int i, call, thread; 310cbc3ecb7SPeter Holm int collide = 0; 311cbc3ecb7SPeter Holmagain: 312cbc3ecb7SPeter Holm for (call = 0; call < 2; call++) { 313cbc3ecb7SPeter Holm for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 314cbc3ecb7SPeter Holm thread++) { 315cbc3ecb7SPeter Holm struct thread_t* th = &threads[thread]; 316cbc3ecb7SPeter Holm if (!th->created) { 317cbc3ecb7SPeter Holm th->created = 1; 318cbc3ecb7SPeter Holm event_init(&th->ready); 319cbc3ecb7SPeter Holm event_init(&th->done); 320cbc3ecb7SPeter Holm event_set(&th->done); 321cbc3ecb7SPeter Holm thread_start(thr, th); 322cbc3ecb7SPeter Holm } 323cbc3ecb7SPeter Holm if (!event_isset(&th->done)) 324cbc3ecb7SPeter Holm continue; 325cbc3ecb7SPeter Holm event_reset(&th->done); 326cbc3ecb7SPeter Holm th->call = call; 327cbc3ecb7SPeter Holm __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 328cbc3ecb7SPeter Holm event_set(&th->ready); 329cbc3ecb7SPeter Holm if (collide && (call % 2) == 0) 330cbc3ecb7SPeter Holm break; 331cbc3ecb7SPeter Holm event_timedwait(&th->done, 50); 332cbc3ecb7SPeter Holm break; 333cbc3ecb7SPeter Holm } 334cbc3ecb7SPeter Holm } 335cbc3ecb7SPeter Holm for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 336cbc3ecb7SPeter Holm sleep_ms(1); 337cbc3ecb7SPeter Holm if (!collide) { 338cbc3ecb7SPeter Holm collide = 1; 339cbc3ecb7SPeter Holm goto again; 340cbc3ecb7SPeter Holm } 341cbc3ecb7SPeter Holm} 342cbc3ecb7SPeter Holm 343cbc3ecb7SPeter Holmstatic void execute_one(void); 344cbc3ecb7SPeter Holm 345cbc3ecb7SPeter Holm#define WAIT_FLAGS 0 346cbc3ecb7SPeter Holm 347cbc3ecb7SPeter Holmstatic void loop(void) 348cbc3ecb7SPeter Holm{ 349cbc3ecb7SPeter Holm int iter = 0; 350cbc3ecb7SPeter Holm for (;; iter++) { 351cbc3ecb7SPeter Holm char cwdbuf[32]; 352cbc3ecb7SPeter Holm sprintf(cwdbuf, "./%d", iter); 353cbc3ecb7SPeter Holm if (mkdir(cwdbuf, 0777)) 354cbc3ecb7SPeter Holm exit(1); 355cbc3ecb7SPeter Holm int pid = fork(); 356cbc3ecb7SPeter Holm if (pid < 0) 357cbc3ecb7SPeter Holm exit(1); 358cbc3ecb7SPeter Holm if (pid == 0) { 359cbc3ecb7SPeter Holm if (chdir(cwdbuf)) 360cbc3ecb7SPeter Holm exit(1); 361cbc3ecb7SPeter Holm execute_one(); 362cbc3ecb7SPeter Holm exit(0); 363cbc3ecb7SPeter Holm } 364cbc3ecb7SPeter Holm int status = 0; 365cbc3ecb7SPeter Holm uint64_t start = current_time_ms(); 366cbc3ecb7SPeter Holm for (;;) { 367cbc3ecb7SPeter Holm if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 368cbc3ecb7SPeter Holm break; 369cbc3ecb7SPeter Holm sleep_ms(1); 370cbc3ecb7SPeter Holm if (current_time_ms() - start < 5000) 371cbc3ecb7SPeter Holm continue; 372cbc3ecb7SPeter Holm kill_and_wait(pid, &status); 373cbc3ecb7SPeter Holm break; 374cbc3ecb7SPeter Holm } 375cbc3ecb7SPeter Holm remove_dir(cwdbuf); 376cbc3ecb7SPeter Holm } 377cbc3ecb7SPeter Holm} 378cbc3ecb7SPeter Holm 379cbc3ecb7SPeter Holmvoid execute_call(int call) 380cbc3ecb7SPeter Holm{ 381cbc3ecb7SPeter Holm switch (call) { 382cbc3ecb7SPeter Holm case 0: 383cbc3ecb7SPeter Holm syscall(SYS_rfork, 0x4030ul); 384cbc3ecb7SPeter Holm break; 385cbc3ecb7SPeter Holm case 1: 386cbc3ecb7SPeter Holm syscall(SYS_thr_new, 0ul, 0ul); 387cbc3ecb7SPeter Holm break; 388cbc3ecb7SPeter Holm } 389cbc3ecb7SPeter Holm} 390cbc3ecb7SPeter Holmint main(void) 391cbc3ecb7SPeter Holm{ 392cbc3ecb7SPeter Holm syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); 393cbc3ecb7SPeter Holm install_segv_handler(); 394cbc3ecb7SPeter Holm use_temporary_dir(); 395cbc3ecb7SPeter Holm do_sandbox_none(); 396cbc3ecb7SPeter Holm return 0; 397cbc3ecb7SPeter Holm} 398cbc3ecb7SPeter HolmEOF 399cbc3ecb7SPeter Holmmycc -o /tmp/syzkaller47 -Wall -Wextra -O0 /tmp/syzkaller47.c -lpthread || exit 1 400cbc3ecb7SPeter Holm 401cbc3ecb7SPeter Holm(cd /tmp; timeout 2m ./syzkaller47) 402cbc3ecb7SPeter Holm 403cbc3ecb7SPeter Holmrm -rf /tmp/syzkaller47 /tmp/syzkaller47.c /tmp/syzkaller.* 404cbc3ecb7SPeter Holmexit 0 405