ok github.com/google/syzkaller/dashboard/app (cached) ? github.com/google/syzkaller/dashboard/dashapi [no test files] ? github.com/google/syzkaller/executor [no test files] ok github.com/google/syzkaller/pkg/ast (cached) ? github.com/google/syzkaller/pkg/bisect [no test files] ok github.com/google/syzkaller/pkg/build (cached) ok github.com/google/syzkaller/pkg/compiler (cached) ok github.com/google/syzkaller/pkg/config (cached) ? github.com/google/syzkaller/pkg/cover [no test files] --- FAIL: TestGenerate (2.64s) --- FAIL: TestGenerate/test/64_fork (0.14s) csource_test.go:72: seed=1568807105649054040 --- FAIL: TestGenerate/test/64_fork/0 (0.57s) csource_test.go:110: opts: {Threaded:false Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) exit(1); } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } static void execute_one(void); #define WAIT_FLAGS 0 static void loop(void) { int iter; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_one(void) { syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); syz_exit(4); syz_errno(0x800); syz_errno(0x7fff); memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); syz_compare_int(2, 0xd4, 0x3ff, 0, 0); memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); syz_compare_int(4, 1, 0x80000000, 0x8da, 9); syz_mmap(0x20ff8000, 0x6000); memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); syz_compare_int(2, 7, 0x4000000, 0, 0); syz_errno(4); memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); syz_exit(9); syz_mmap(0x20ffa000, 0x2000); } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor407202027 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/16 (0.60s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor963013966 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/30 (0.52s) csource_test.go:110: opts: {Threaded:true Collide:true Repeat:true RepeatTimes:0 Procs:2 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:true Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 unsigned long long procid; 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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; int collide = 0; again: for (call = 0; call < 16; 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 (collide && (call % 2) == 0) break; event_timedwait(&th->done, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); if (!collide) { collide = 1; goto again; } } static void execute_one(void); #define WAIT_FLAGS 0 static void loop(void) { int iter; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); for (procid = 0; procid < 2; procid++) { if (fork() == 0) { use_temporary_dir(); do_sandbox_none(); } } sleep(1000000); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor731381845 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/29 (0.54s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:true} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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) { fprintf(stderr, "### start\n"); int i, call, thread; for (call = 0; call < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { intptr_t res; switch (call) { case 0: res = syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); fprintf(stderr, "### call=0 errno=%u\n", res == -1 ? errno : 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); res = syz_execute_func(0x20000000); fprintf(stderr, "### call=1 errno=%u\n", res == -1 ? errno : 0); break; case 2: res = syz_exit(4); fprintf(stderr, "### call=2 errno=%u\n", res == -1 ? errno : 0); break; case 3: res = syz_errno(0x800); fprintf(stderr, "### call=3 errno=%u\n", res == -1 ? errno : 0); break; case 4: res = syz_errno(0x7fff); fprintf(stderr, "### call=4 errno=%u\n", res == -1 ? errno : 0); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); res = syz_execute_func(0x20000040); fprintf(stderr, "### call=5 errno=%u\n", res == -1 ? errno : 0); break; case 6: res = syz_compare_int(2, 0xd4, 0x3ff, 0, 0); fprintf(stderr, "### call=6 errno=%u\n", res == -1 ? errno : 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); res = syz_execute_func(0x20000080); fprintf(stderr, "### call=7 errno=%u\n", res == -1 ? errno : 0); break; case 8: res = syz_compare_int(4, 1, 0x80000000, 0x8da, 9); fprintf(stderr, "### call=8 errno=%u\n", res == -1 ? errno : 0); break; case 9: res = syz_mmap(0x20ff8000, 0x6000); fprintf(stderr, "### call=9 errno=%u\n", res == -1 ? errno : 0); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; res = syz_compare(0x20000000, 2, 0x20000040, 0x18); fprintf(stderr, "### call=10 errno=%u\n", res == -1 ? errno : 0); break; case 11: res = syz_compare_int(2, 7, 0x4000000, 0, 0); fprintf(stderr, "### call=11 errno=%u\n", res == -1 ? errno : 0); break; case 12: res = syz_errno(4); fprintf(stderr, "### call=12 errno=%u\n", res == -1 ? errno : 0); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); res = syz_execute_func(0x20000080); fprintf(stderr, "### call=13 errno=%u\n", res == -1 ? errno : 0); break; case 14: res = syz_exit(9); fprintf(stderr, "### call=14 errno=%u\n", res == -1 ? errno : 0); break; case 15: res = syz_mmap(0x20ffa000, 0x2000); fprintf(stderr, "### call=15 errno=%u\n", res == -1 ? errno : 0); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor863370160 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/28 (0.52s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor085803855 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/27 (0.54s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:true Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor041721442 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/26 (0.63s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor070940249 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/25 (0.63s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:true Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 static __thread int skip_segv; static __thread jmp_buf segv_env; static void segv_handler(int sig, siginfo_t* info, void* ctx) { uintptr_t addr = (uintptr_t)info->si_addr; const uintptr_t prog_start = 1 << 20; const uintptr_t prog_end = 100 << 20; if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) && (addr < prog_start || addr > prog_end)) { _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(...) { __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); if (_setjmp(segv_env) == 0) { __VA_ARGS__; } __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); } 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; NONFAILING(((void (*)(void))(text))()); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: NONFAILING(memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50)); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: NONFAILING(memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50)); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: NONFAILING(memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50)); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: NONFAILING(memcpy((void*)0x20000000, "&\000", 2)); NONFAILING(*(uint16_t*)0x20000040 = 2); NONFAILING(*(uint32_t*)0x20000044 = 0x200); NONFAILING(*(uint8_t*)0x20000048 = 0); NONFAILING(*(uint16_t*)0x2000004a = 8); NONFAILING(*(uint64_t*)0x20000050 = 6); syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: NONFAILING(memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50)); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); install_segv_handler(); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor670035940 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/24 (0.62s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor249311219 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/23 (0.67s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor570103990 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/22 (0.75s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:false HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; iter++) { int pid = fork(); if (pid < 0) exit(1); if (pid == 0) { 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 < 5 * 1000) continue; kill_and_wait(pid, &status); break; } } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor017178781 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/21 (0.67s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor840626008 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/8 (0.66s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:1 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor804375767 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/20 (0.77s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor281083978 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/19 (0.65s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor894495521 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/18 (0.61s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor462796812 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/15 (0.71s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor507156475 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/14 (0.67s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor118392094 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/17 (0.64s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor377795045 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/13 (0.68s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor674539008 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/11 (0.59s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor632138034 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/12 (0.73s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor374676319 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/9 (0.66s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:4 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 unsigned long long procid; 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); for (procid = 0; procid < 4; procid++) { if (fork() == 0) { use_temporary_dir(); do_sandbox_none(); } } sleep(1000000); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor981085492 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/10 (0.66s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox: Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); loop(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor256503529 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/4 (0.60s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:false RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 loop(void) { int i, call, thread; for (call = 0; call < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor287255811 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/7 (0.64s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:10 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0; iter < 10; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor503047814 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/2 (0.65s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor276909613 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/3 (0.70s) csource_test.go:110: opts: {Threaded:true Collide:true Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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; int collide = 0; again: for (call = 0; call < 16; 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 (collide && (call % 2) == 0) break; event_timedwait(&th->done, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); if (!collide) { collide = 1; goto again; } } static void execute_one(void); #define WAIT_FLAGS 0 static void loop(void) { int iter; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor982178216 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/1 (0.62s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor382505703 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/6 (0.59s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor280798490 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64_fork/5 (0.64s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: syz_compare_int$3(0x3, 0x2, 0x400, 0xfffffffffffffffd) syz_execute_func(&(0x7f0000000000)="3815a7419ce993cdd9a613441d62c53aaa9f71a67a62a7a676cbfbc97a9051adff8c02d1fe757b4b3b12991dfec4dba1277a") syz_exit(0x4) syz_errno(0x800) syz_errno(0x7fff) syz_execute_func(&(0x7f0000000040)="ddbc33a157cfc292c682d8d9a129d51de17b77775221e40bff84d693807b18a49d931dd200dcec176cf816893263323837c2") syz_compare_int$2(0x2, 0xd4, 0x3ff) syz_execute_func(&(0x7f0000000080)="9c5f89ee9d98b8d986b5407bc4141744694a9b190fd2e5ac8675d8e2f185a558f1814b376be5e6ee5ee48b880a29bba22ad0") syz_compare_int$4(0x4, 0x1, 0x80000000, 0x8da, 0x9) syz_mmap(&(0x7f0000ff8000/0x6000)=nil, 0x6000) syz_compare(&(0x7f0000000000)='&\x00', 0x2, &(0x7f0000000040)=@align0={0x2, 0x200, 0x0, 0x8, 0x6}, 0x18) syz_compare_int$2(0x2, 0x7, 0x4000000) syz_errno(0x4) syz_execute_func(&(0x7f0000000080)="83448d6f48ddfe3a7bb9d2f6f431d31fc36fca7d9d0c0012d5c41c1cba5954bd8b9e624d24017fb37d4e289c2caeca59731b") syz_exit(0x9) syz_mmap(&(0x7f0000ffa000/0x2000)=nil, 0x2000) csource_test.go:111: failed to build program: // 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 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 remove_dir(const char* dir) { DIR* dp; struct dirent* ep; dp = opendir(dir); if (dp == NULL) exit(1); 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)) exit(1); } closedir(dp); if (rmdir(dir)) 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; for (i = 0; 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; } static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); 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; for (iter = 0;; 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 (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5 * 1000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } void execute_call(int call) { switch (call) { case 0: syz_compare_int(3, 2, 0x400, 0xfffffffffffffffd, 0); break; case 1: memcpy((void*)0x20000000, "\x38\x15\xa7\x41\x9c\xe9\x93\xcd\xd9\xa6\x13\x44\x1d\x62\xc5\x3a\xaa\x9f\x71\xa6\x7a\x62\xa7\xa6\x76\xcb\xfb\xc9\x7a\x90\x51\xad\xff\x8c\x02\xd1\xfe\x75\x7b\x4b\x3b\x12\x99\x1d\xfe\xc4\xdb\xa1\x27\x7a", 50); syz_execute_func(0x20000000); break; case 2: syz_exit(4); break; case 3: syz_errno(0x800); break; case 4: syz_errno(0x7fff); break; case 5: memcpy((void*)0x20000040, "\xdd\xbc\x33\xa1\x57\xcf\xc2\x92\xc6\x82\xd8\xd9\xa1\x29\xd5\x1d\xe1\x7b\x77\x77\x52\x21\xe4\x0b\xff\x84\xd6\x93\x80\x7b\x18\xa4\x9d\x93\x1d\xd2\x00\xdc\xec\x17\x6c\xf8\x16\x89\x32\x63\x32\x38\x37\xc2", 50); syz_execute_func(0x20000040); break; case 6: syz_compare_int(2, 0xd4, 0x3ff, 0, 0); break; case 7: memcpy((void*)0x20000080, "\x9c\x5f\x89\xee\x9d\x98\xb8\xd9\x86\xb5\x40\x7b\xc4\x14\x17\x44\x69\x4a\x9b\x19\x0f\xd2\xe5\xac\x86\x75\xd8\xe2\xf1\x85\xa5\x58\xf1\x81\x4b\x37\x6b\xe5\xe6\xee\x5e\xe4\x8b\x88\x0a\x29\xbb\xa2\x2a\xd0", 50); syz_execute_func(0x20000080); break; case 8: syz_compare_int(4, 1, 0x80000000, 0x8da, 9); break; case 9: syz_mmap(0x20ff8000, 0x6000); break; case 10: memcpy((void*)0x20000000, "&\000", 2); *(uint16_t*)0x20000040 = 2; *(uint32_t*)0x20000044 = 0x200; *(uint8_t*)0x20000048 = 0; *(uint16_t*)0x2000004a = 8; *(uint64_t*)0x20000050 = 6; syz_compare(0x20000000, 2, 0x20000040, 0x18); break; case 11: syz_compare_int(2, 7, 0x4000000, 0, 0); break; case 12: syz_errno(4); break; case 13: memcpy((void*)0x20000080, "\x83\x44\x8d\x6f\x48\xdd\xfe\x3a\x7b\xb9\xd2\xf6\xf4\x31\xd3\x1f\xc3\x6f\xca\x7d\x9d\x0c\x00\x12\xd5\xc4\x1c\x1c\xba\x59\x54\xbd\x8b\x9e\x62\x4d\x24\x01\x7f\xb3\x7d\x4e\x28\x9c\x2c\xae\xca\x59\x73\x1b", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(9); break; case 15: syz_mmap(0x20ffa000, 0x2000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor973485489 -DGOOS_test=1 -DGOARCH_64_fork=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64 (0.15s) csource_test.go:72: seed=1568807105649148370 --- FAIL: TestGenerate/test/64/16 (0.60s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor865916252 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/0 (0.72s) csource_test.go:110: opts: {Threaded:false Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include 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); } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_one(void) { memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); syz_errno(0x400); memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); syz_exit(4); syz_mmap(0x20ffe000, 0x1000); } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor986869003 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/30 (0.62s) csource_test.go:110: opts: {Threaded:true Collide:true Repeat:true RepeatTimes:0 Procs:2 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:true Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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; int collide = 0; again: for (call = 0; call < 16; 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 (collide && (call % 2) == 0) break; event_timedwait(&th->done, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); if (!collide) { collide = 1; goto again; } } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); for (procid = 0; procid < 2; procid++) { if (fork() == 0) { use_temporary_dir(); do_sandbox_none(); } } sleep(1000000); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor603726062 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/29 (0.72s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:true} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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) { fprintf(stderr, "### start\n"); int i, call, thread; for (call = 0; call < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { intptr_t res; switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); res = syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); fprintf(stderr, "### call=0 errno=%u\n", res == -1 ? errno : 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; res = syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); fprintf(stderr, "### call=1 errno=%u\n", res == -1 ? errno : 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); res = syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); fprintf(stderr, "### call=2 errno=%u\n", res == -1 ? errno : 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; res = syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); fprintf(stderr, "### call=3 errno=%u\n", res == -1 ? errno : 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; res = syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); fprintf(stderr, "### call=4 errno=%u\n", res == -1 ? errno : 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; res = syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); fprintf(stderr, "### call=5 errno=%u\n", res == -1 ? errno : 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); res = syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); fprintf(stderr, "### call=6 errno=%u\n", res == -1 ? errno : 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; res = syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); fprintf(stderr, "### call=7 errno=%u\n", res == -1 ? errno : 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; res = syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); fprintf(stderr, "### call=8 errno=%u\n", res == -1 ? errno : 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); res = syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); fprintf(stderr, "### call=9 errno=%u\n", res == -1 ? errno : 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; res = syz_compare(0x20000000, 4, 0x20000040, 8); fprintf(stderr, "### call=10 errno=%u\n", res == -1 ? errno : 0); break; case 11: res = syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); fprintf(stderr, "### call=11 errno=%u\n", res == -1 ? errno : 0); break; case 12: res = syz_errno(0x400); fprintf(stderr, "### call=12 errno=%u\n", res == -1 ? errno : 0); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); res = syz_execute_func(0x20000080); fprintf(stderr, "### call=13 errno=%u\n", res == -1 ? errno : 0); break; case 14: res = syz_exit(4); fprintf(stderr, "### call=14 errno=%u\n", res == -1 ? errno : 0); break; case 15: res = syz_mmap(0x20ffe000, 0x1000); fprintf(stderr, "### call=15 errno=%u\n", res == -1 ? errno : 0); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor164173173 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/28 (0.66s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor998103407 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/26 (0.64s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor096937986 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/27 (0.70s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:true Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor984051280 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/24 (0.67s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor962109572 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/25 (0.75s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:true Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // 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 static __thread int skip_segv; static __thread jmp_buf segv_env; static void segv_handler(int sig, siginfo_t* info, void* ctx) { uintptr_t addr = (uintptr_t)info->si_addr; const uintptr_t prog_start = 1 << 20; const uintptr_t prog_end = 100 << 20; if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) && (addr < prog_start || addr > prog_end)) { _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(...) { __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); if (_setjmp(segv_env) == 0) { __VA_ARGS__; } __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); } 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; NONFAILING(((void (*)(void))(text))()); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: NONFAILING(memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74)); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: NONFAILING(*(uint64_t*)0x20000080 = 0x20ffa000); NONFAILING(*(uint64_t*)0x20000088 = 0x3000); syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: NONFAILING(memcpy((void*)0x200000c0, "./file0\000", 8)); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: NONFAILING(*(uint32_t*)0x20000100 = 1); NONFAILING(*(uint32_t*)0x20000104 = 1); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: NONFAILING(*(uint64_t*)0x20000140 = 1); NONFAILING(*(uint64_t*)0x20000148 = 8); syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: NONFAILING(*(uint32_t*)0x20000180 = 3); NONFAILING(*(uint8_t*)0x20000184 = 0); syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: NONFAILING(memcpy((void*)0x200001c0, "./file0\000", 8)); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: NONFAILING(*(uint64_t*)0x20000200 = 0x36); NONFAILING(*(uint8_t*)0x20000208 = 9); NONFAILING(*(uint8_t*)0x20000209 = 1); NONFAILING(*(uint16_t*)0x2000020a = 0x10); NONFAILING(*(uint32_t*)0x2000020c = 0x9ff3); NONFAILING(*(uint32_t*)0x20000210 = 1); NONFAILING(*(uint32_t*)0x20000214 = 3); NONFAILING(*(uint8_t*)0x20000218 = 0); NONFAILING(*(uint8_t*)0x20000219 = 1); NONFAILING(*(uint16_t*)0x2000021a = 0x10); NONFAILING(*(uint32_t*)0x2000021c = 5); NONFAILING(*(uint32_t*)0x20000220 = 8); NONFAILING(*(uint32_t*)0x20000224 = 0xfffffffe); NONFAILING(*(uint32_t*)0x20000228 = 0x10); NONFAILING(*(uint16_t*)0x2000022c = 1); NONFAILING(*(uint16_t*)0x2000022e = 7); NONFAILING(*(uint16_t*)0x20000230 = 6); NONFAILING(*(uint16_t*)0x20000232 = 0x6d9b); NONFAILING(*(uint16_t*)0x20000234 = 0x45); syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: NONFAILING(*(uint8_t*)0x20000240 = 2); NONFAILING(*(uint8_t*)0x20000241 = 7); NONFAILING(*(uint8_t*)0x20000244 = 9); syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: NONFAILING(*(uint16_t*)0x20000280 = htobe16(0xe)); NONFAILING(*(uint32_t*)0x20000282 = htobe32(0x42)); NONFAILING(*(uint64_t*)0x20000286 = htobe64(0)); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: NONFAILING(memcpy((void*)0x20000000, "&l!\000", 4)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10)); NONFAILING(*(uint8_t*)0x20000044 = -1); syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: NONFAILING(memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50)); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); install_segv_handler(); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor757708665 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/22 (0.62s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:false HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include 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 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor792047123 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/23 (0.75s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor924636246 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/21 (0.63s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor940092861 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/20 (0.62s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor547606008 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/18 (0.65s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor830446570 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/19 (0.71s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor009510135 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/15 (0.61s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor056297132 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/17 (0.67s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor521321537 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/8 (0.68s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:1 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor149150235 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/14 (0.60s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor314206910 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/13 (0.65s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor721737989 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/12 (0.58s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor342712992 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/11 (0.68s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor469659519 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/10 (0.70s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox: Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); loop(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor501984978 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/4 (0.66s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:false RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 loop(void) { int i, call, thread; for (call = 0; call < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor686342665 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/9 (0.69s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:4 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); for (procid = 0; procid < 4; procid++) { if (fork() == 0) { use_temporary_dir(); do_sandbox_none(); } } sleep(1000000); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor879444006 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/6 (0.67s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor799767843 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/7 (0.69s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:10 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor007431124 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/5 (0.52s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor844495693 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/2 (0.46s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor749390920 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/3 (0.29s) csource_test.go:110: opts: {Threaded:true Collide:true Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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; int collide = 0; again: for (call = 0; call < 16; 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 (collide && (call % 2) == 0) break; event_timedwait(&th->done, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); if (!collide) { collide = 1; goto again; } } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor381709063 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] --- FAIL: TestGenerate/test/64/1 (0.27s) csource_test.go:110: opts: {Threaded:true Collide:false Repeat:true RepeatTimes:0 Procs:0 Sandbox:none Fault:false FaultCall:0 FaultNth:0 Leak:false EnableTun:false EnableNetDev:false EnableNetReset:false EnableCgroups:false EnableBinfmtMisc:false EnableCloseFds:false UseTmpDir:true HandleSegv:false Repro:false Trace:false} program: test$text_x86_16(&(0x7f0000000000)="b83f000f00d066b80500000066b9040000000f01c1263910f30f0966b9800000c00f326635002000000f3066b80500000066b90f0000000f01d965db1e0000660f72e4000f35360f01c8", 0x4a) test$length9(&(0x7f0000000080)={&(0x7f0000ffa000/0x3000)=nil, 0x3000}) mutate$flags(&(0x7f00000000c0)='./file0\x00', 0x3, 0x0, 0x10) test$missing_struct(&(0x7f0000000100)) test$length2(&(0x7f0000000140)={0x1, 0x8}) test$length26(&(0x7f0000000180)={0x3, 0x400}, 0x8) mutate$flags(&(0x7f00000001c0)='./file0\x00', 0x8, 0x0, 0x10) test$length8(&(0x7f0000000200)={0x36, {0x9, 0x1, 0x10, [0x9ff3, 0x1, 0x3]}, [{0x0, 0x1, 0x10, [0x5, 0x8, 0xfffffffffffffffe]}], 0x10, 0x1, [0x7, 0x6, 0x6d9b, 0x45]}) test$align3(&(0x7f0000000240)={0x2, {0x7}, {0x9}}) test$end1(&(0x7f0000000280)={0xe}) syz_compare(&(0x7f0000000000)='&l!\x00', 0x4, &(0x7f0000000040)=@bf1={{0x6, 0x9, 0x9}, 0x3ff}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffffc, 0x2) syz_errno(0x400) syz_execute_func(&(0x7f0000000080)="ac89ca0ef8bbc673ad7531cb7acad0e42ce7beabceb5fc886cb0f29703cbe224b88b47ed7fa4344435e7e9a2d499d4588001") syz_exit(0x4) syz_mmap(&(0x7f0000ffe000/0x1000)=nil, 0x1000) csource_test.go:111: failed to build program: // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include 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; for (i = 0; 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; } #define BITMASK(bf_off,bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type,htobe,addr,val,bf_off,bf_len) *(type*)(addr) = htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) static long syz_mmap(volatile long a0, volatile long a1) { return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); } static long syz_errno(volatile long v) { errno = v; return v == 0 ? 0 : -1; } static long syz_exit(volatile long status) { _exit(status); return 0; } static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) { if (want_len != got_len) { errno = EBADF; return -1; } if (memcmp((void*)want, (void*)got, want_len)) { errno = EINVAL; return -1; } return 0; } static long syz_compare_int(volatile long n, ...) { va_list args; va_start(args, n); long v0 = va_arg(args, long); long v1 = va_arg(args, long); long v2 = va_arg(args, long); long v3 = va_arg(args, long); va_end(args); if (n < 2 || n > 4) return errno = E2BIG, -1; if (n <= 2 && v2 != 0) return errno = EFAULT, -1; if (n <= 3 && v3 != 0) return errno = EFAULT, -1; if (v0 != v1) return errno = EINVAL, -1; if (n > 2 && v0 != v2) return errno = EINVAL, -1; if (n > 3 && v0 != v3) return errno = EINVAL, -1; return 0; } static void loop(); static int do_sandbox_none(void) { loop(); return 0; } static long syz_execute_func(volatile long text) { volatile long p[8] = {0}; (void)p; ((void (*)(void))(text))(); return 0; } 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 < 16; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); static void loop(void) { execute_one(); } #ifndef SYS_mutate #define SYS_mutate 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: memcpy((void*)0x20000000, "\xb8\x3f\x00\x0f\x00\xd0\x66\xb8\x05\x00\x00\x00\x66\xb9\x04\x00\x00\x00\x0f\x01\xc1\x26\x39\x10\xf3\x0f\x09\x66\xb9\x80\x00\x00\xc0\x0f\x32\x66\x35\x00\x20\x00\x00\x0f\x30\x66\xb8\x05\x00\x00\x00\x66\xb9\x0f\x00\x00\x00\x0f\x01\xd9\x65\xdb\x1e\x00\x00\x66\x0f\x72\xe4\x00\x0f\x35\x36\x0f\x01\xc8", 74); syscall(SYS_test, 0x20000000, 0x4a, 0, 0, 0, 0); break; case 1: *(uint64_t*)0x20000080 = 0x20ffa000; *(uint64_t*)0x20000088 = 0x3000; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 2: memcpy((void*)0x200000c0, "./file0\000", 8); syscall(SYS_mutate, 0x200000c0, 3, 0, 0x10, 0, 0, 0, 0, 0); break; case 3: *(uint32_t*)0x20000100 = 1; *(uint32_t*)0x20000104 = 1; syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 4: *(uint64_t*)0x20000140 = 1; *(uint64_t*)0x20000148 = 8; syscall(SYS_test, 0x20000140, 0, 0, 0, 0, 0); break; case 5: *(uint32_t*)0x20000180 = 3; *(uint8_t*)0x20000184 = 0; syscall(SYS_test, 0x20000180, 8, 0, 0, 0, 0); break; case 6: memcpy((void*)0x200001c0, "./file0\000", 8); syscall(SYS_mutate, 0x200001c0, 8, 0, 0x10, 0, 0, 0, 0, 0); break; case 7: *(uint64_t*)0x20000200 = 0x36; *(uint8_t*)0x20000208 = 9; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 0x9ff3; *(uint32_t*)0x20000210 = 1; *(uint32_t*)0x20000214 = 3; *(uint8_t*)0x20000218 = 0; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 5; *(uint32_t*)0x20000220 = 8; *(uint32_t*)0x20000224 = 0xfffffffe; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 7; *(uint16_t*)0x20000230 = 6; *(uint16_t*)0x20000232 = 0x6d9b; *(uint16_t*)0x20000234 = 0x45; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: *(uint8_t*)0x20000240 = 2; *(uint8_t*)0x20000241 = 7; *(uint8_t*)0x20000244 = 9; syscall(SYS_test, 0x20000240, 0, 0, 0, 0, 0); break; case 9: *(uint16_t*)0x20000280 = htobe16(0xe); *(uint32_t*)0x20000282 = htobe32(0x42); *(uint64_t*)0x20000286 = htobe64(0); syscall(SYS_test, 0x20000280, 0, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "&l!\000", 4); STORE_BY_BITMASK(uint32_t, , 0x20000040, 6, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 9, 20, 10); *(uint8_t*)0x20000044 = -1; syz_compare(0x20000000, 4, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffffc, 2, 0, 0); break; case 12: syz_errno(0x400); break; case 13: memcpy((void*)0x20000080, "\xac\x89\xca\x0e\xf8\xbb\xc6\x73\xad\x75\x31\xcb\x7a\xca\xd0\xe4\x2c\xe7\xbe\xab\xce\xb5\xfc\x88\x6c\xb0\xf2\x97\x03\xcb\xe2\x24\xb8\x8b\x47\xed\x7f\xa4\x34\x44\x35\xe7\xe9\xa2\xd4\x99\xd4\x58\x80\x01", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(4); break; case 15: syz_mmap(0x20ffe000, 0x1000); break; } } int main(void) { syz_mmap(0x20000000, 0x1000000); use_temporary_dir(); do_sandbox_none(); return 0; } c++: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.6' compiler invocation: c++ [-o /tmp/syz-executor398496954 -DGOOS_test=1 -DGOARCH_64=1 -DHOSTGOOS_openbsd=1 -x c - -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=8192 -m64 -fsanitize=address] FAIL FAIL github.com/google/syzkaller/pkg/csource 16.298s ok github.com/google/syzkaller/pkg/db (cached) ok github.com/google/syzkaller/pkg/email (cached) ? github.com/google/syzkaller/pkg/gce [no test files] ? github.com/google/syzkaller/pkg/gcs [no test files] ? github.com/google/syzkaller/pkg/hash [no test files] ok github.com/google/syzkaller/pkg/host (cached) ? github.com/google/syzkaller/pkg/html [no test files] ok github.com/google/syzkaller/pkg/ifuzz (cached) ? github.com/google/syzkaller/pkg/ifuzz/gen [no test files] ? github.com/google/syzkaller/pkg/ifuzz/generated [no test files] ok github.com/google/syzkaller/pkg/instance (cached) ok github.com/google/syzkaller/pkg/ipc (cached) ? github.com/google/syzkaller/pkg/ipc/ipcconfig [no test files] ok github.com/google/syzkaller/pkg/kd (cached) ok github.com/google/syzkaller/pkg/log (cached) ok github.com/google/syzkaller/pkg/mgrconfig (cached) ok github.com/google/syzkaller/pkg/osutil (cached) ok github.com/google/syzkaller/pkg/report (cached) ok github.com/google/syzkaller/pkg/repro (cached) ? github.com/google/syzkaller/pkg/rpctype [no test files] ok github.com/google/syzkaller/pkg/runtest (cached) ok github.com/google/syzkaller/pkg/serializer (cached) ? github.com/google/syzkaller/pkg/signal [no test files] ok github.com/google/syzkaller/pkg/symbolizer (cached) ok github.com/google/syzkaller/pkg/vcs (cached) ok github.com/google/syzkaller/prog (cached) ok github.com/google/syzkaller/prog/test (cached) ? github.com/google/syzkaller/sys [no test files] ? github.com/google/syzkaller/sys/akaros [no test files] ? github.com/google/syzkaller/sys/akaros/gen [no test files] ? github.com/google/syzkaller/sys/freebsd [no test files] ? github.com/google/syzkaller/sys/freebsd/gen [no test files] ? github.com/google/syzkaller/sys/fuchsia [no test files] ? github.com/google/syzkaller/sys/fuchsia/fidlgen [no test files] ? github.com/google/syzkaller/sys/fuchsia/gen [no test files] ? github.com/google/syzkaller/sys/fuchsia/layout [no test files] ok github.com/google/syzkaller/sys/linux (cached) ? github.com/google/syzkaller/sys/linux/gen [no test files] ? github.com/google/syzkaller/sys/netbsd [no test files] ? github.com/google/syzkaller/sys/netbsd/gen [no test files] ok github.com/google/syzkaller/sys/openbsd (cached) ? github.com/google/syzkaller/sys/openbsd/gen [no test files] ? github.com/google/syzkaller/sys/syz-extract [no test files] ? github.com/google/syzkaller/sys/syz-sysgen [no test files] ? github.com/google/syzkaller/sys/targets [no test files] ? github.com/google/syzkaller/sys/test [no test files] ? github.com/google/syzkaller/sys/test/gen [no test files] ? github.com/google/syzkaller/sys/trusty [no test files] ? github.com/google/syzkaller/sys/trusty/gen [no test files] ? github.com/google/syzkaller/sys/windows [no test files] ? github.com/google/syzkaller/sys/windows/gen [no test files] ok github.com/google/syzkaller/syz-ci (cached) ? github.com/google/syzkaller/syz-fuzzer [no test files] ok github.com/google/syzkaller/syz-hub (cached) ok github.com/google/syzkaller/syz-hub/state (cached) ? github.com/google/syzkaller/syz-manager [no test files] ? github.com/google/syzkaller/tools/syz-benchcmp [no test files] ? github.com/google/syzkaller/tools/syz-bisect [no test files] ? github.com/google/syzkaller/tools/syz-cover [no test files] ? github.com/google/syzkaller/tools/syz-crush [no test files] ? github.com/google/syzkaller/tools/syz-db [no test files] ? github.com/google/syzkaller/tools/syz-env [no test files] ? github.com/google/syzkaller/tools/syz-execprog [no test files] ? github.com/google/syzkaller/tools/syz-fmt [no test files] ? github.com/google/syzkaller/tools/syz-imagegen [no test files] ? github.com/google/syzkaller/tools/syz-mutate [no test files] ? github.com/google/syzkaller/tools/syz-prog2c [no test files] ? github.com/google/syzkaller/tools/syz-repro [no test files] ? github.com/google/syzkaller/tools/syz-runtest [no test files] ? github.com/google/syzkaller/tools/syz-stress [no test files] ? github.com/google/syzkaller/tools/syz-symbolize [no test files] ? github.com/google/syzkaller/tools/syz-testbuild [no test files] ? github.com/google/syzkaller/tools/syz-trace2syz [no test files] ok github.com/google/syzkaller/tools/syz-trace2syz/parser (cached) ok github.com/google/syzkaller/tools/syz-trace2syz/proggen (cached) ? github.com/google/syzkaller/tools/syz-tty [no test files] ? github.com/google/syzkaller/tools/syz-upgrade [no test files] ? github.com/google/syzkaller/tools/syz-usbgen [no test files] ok github.com/google/syzkaller/vm (cached) ? github.com/google/syzkaller/vm/adb [no test files] ? github.com/google/syzkaller/vm/bhyve [no test files] ? github.com/google/syzkaller/vm/gce [no test files] ? github.com/google/syzkaller/vm/gvisor [no test files] ? github.com/google/syzkaller/vm/isolated [no test files] ? github.com/google/syzkaller/vm/kvm [no test files] ? github.com/google/syzkaller/vm/odroid [no test files] ? github.com/google/syzkaller/vm/qemu [no test files] ok github.com/google/syzkaller/vm/vmimpl (cached) ? github.com/google/syzkaller/vm/vmm [no test files]