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 0.731s ? github.com/google/syzkaller/pkg/bisect [no test files] ok github.com/google/syzkaller/pkg/build 4.441s ok github.com/google/syzkaller/pkg/compiler 6.826s ok github.com/google/syzkaller/pkg/config (cached) ? github.com/google/syzkaller/pkg/cover [no test files] --- FAIL: TestGenerate (8.29s) --- FAIL: TestGenerate/test/64 (0.33s) csource_test.go:72: seed=1568782896115811514 --- FAIL: TestGenerate/test/64/0 (0.93s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_one(void) { *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); syscall(SYS_seccomp); *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); syz_compare_int(3, 0xa80, 0, 8, 0); memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); syz_compare_int(2, 0x80, 0x9c4, 0, 0); syz_errno(0); memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); syz_exit(1); syz_mmap(0x20ffb000, 0x3000); } 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-executor450889320 -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.88s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor572047729 -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/16 (1.00s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor089072295 -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.98s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor178715098 -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.96s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor100429340 -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.99s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor167573422 -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 (1.09s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor103054645 -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 (1.00s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor652507339 -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.92s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor556572432 -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.99s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor374598447 -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 (1.04s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor632484153 -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 (1.16s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor321732802 -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.92s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { intptr_t res; switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; res = syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); fprintf(stderr, "### call=0 errno=%u\n", res == -1 ? errno : 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); res = syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); fprintf(stderr, "### call=1 errno=%u\n", res == -1 ? errno : 0); break; case 2: *(uint8_t*)0x20000080 = 1; res = syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); fprintf(stderr, "### call=2 errno=%u\n", res == -1 ? errno : 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; res = syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); fprintf(stderr, "### call=3 errno=%u\n", res == -1 ? errno : 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); res = syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); fprintf(stderr, "### call=4 errno=%u\n", res == -1 ? errno : 0); break; case 5: *(uint8_t*)0x200001c0 = 4; res = syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); fprintf(stderr, "### call=5 errno=%u\n", res == -1 ? errno : 0); break; case 6: res = syscall(SYS_seccomp); fprintf(stderr, "### call=6 errno=%u\n", res == -1 ? errno : 0); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; res = syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); fprintf(stderr, "### call=7 errno=%u\n", res == -1 ? errno : 0); break; case 8: res = syz_compare_int(3, 0xa80, 0, 8, 0); fprintf(stderr, "### call=8 errno=%u\n", res == -1 ? errno : 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); res = syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); fprintf(stderr, "### call=9 errno=%u\n", res == -1 ? errno : 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; res = syz_compare(0x20000000, 1, 0x20000040, 8); fprintf(stderr, "### call=10 errno=%u\n", res == -1 ? errno : 0); break; case 11: res = syz_compare_int(2, 0x80, 0x9c4, 0, 0); fprintf(stderr, "### call=11 errno=%u\n", res == -1 ? errno : 0); break; case 12: res = syz_errno(0); fprintf(stderr, "### call=12 errno=%u\n", res == -1 ? errno : 0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); res = syz_execute_func(0x20000080); fprintf(stderr, "### call=13 errno=%u\n", res == -1 ? errno : 0); break; case 14: res = syz_exit(1); fprintf(stderr, "### call=14 errno=%u\n", res == -1 ? errno : 0); break; case 15: res = syz_mmap(0x20ffb000, 0x3000); 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-executor228648260 -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.81s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor656380883 -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.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:true Trace:false} program: test$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor019650429 -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.81s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor241023254 -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.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:true Repro:false Trace:false} program: test$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: NONFAILING(*(uint8_t*)0x20000000 = 3); NONFAILING(*(uint32_t*)0x20000004 = 8); NONFAILING(*(uint64_t*)0x20000008 = 3); NONFAILING(*(uint32_t*)0x20000010 = 0x10); syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: NONFAILING(*(uint16_t*)0x20000040 = htobe16(0xe)); NONFAILING(*(uint32_t*)0x20000042 = htobe32(0x42)); NONFAILING(*(uint64_t*)0x20000046 = htobe64(0)); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: NONFAILING(*(uint8_t*)0x20000080 = 1); syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: NONFAILING(*(uint8_t*)0x200000c0 = 0xe3); syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: NONFAILING(*(uint16_t*)0x20000100 = 0); NONFAILING(*(uint32_t*)0x20000102 = htobe32(9)); NONFAILING(*(uint32_t*)0x20000106 = htobe32(0x400)); NONFAILING(*(uint16_t*)0x2000010a = 0); NONFAILING(memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145)); struct csum_inet csum_1; csum_inet_init(&csum_1); NONFAILING(csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4)); NONFAILING(csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4)); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); NONFAILING(csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147)); NONFAILING(*(uint16_t*)0x2000010a = csum_inet_digest(&csum_1)); struct csum_inet csum_2; csum_inet_init(&csum_2); NONFAILING(csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10)); NONFAILING(*(uint16_t*)0x20000100 = csum_inet_digest(&csum_2)); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: NONFAILING(*(uint8_t*)0x200001c0 = 4); syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: NONFAILING(*(uint64_t*)0x20000200 = 0x34); NONFAILING(*(uint8_t*)0x20000208 = 6); NONFAILING(*(uint8_t*)0x20000209 = 1); NONFAILING(*(uint16_t*)0x2000020a = 0x10); NONFAILING(*(uint32_t*)0x2000020c = 9); NONFAILING(*(uint32_t*)0x20000210 = 2); NONFAILING(*(uint32_t*)0x20000214 = 0x7ff); NONFAILING(*(uint8_t*)0x20000218 = 7); NONFAILING(*(uint8_t*)0x20000219 = 1); NONFAILING(*(uint16_t*)0x2000021a = 0x10); NONFAILING(*(uint32_t*)0x2000021c = 0x7fff); NONFAILING(*(uint32_t*)0x20000220 = 0x8a); NONFAILING(*(uint32_t*)0x20000224 = 0xffffff01); NONFAILING(*(uint32_t*)0x20000228 = 0x10); NONFAILING(*(uint16_t*)0x2000022c = 1); NONFAILING(*(uint16_t*)0x2000022e = 3); NONFAILING(*(uint16_t*)0x20000230 = 3); NONFAILING(*(uint16_t*)0x20000232 = 4); syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: NONFAILING(memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69)); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: NONFAILING(memcpy((void*)0x20000000, "\000", 1)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10)); NONFAILING(*(uint8_t*)0x20000044 = 0xce); syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: NONFAILING(memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50)); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor456582839 -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.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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor007809720 -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.69s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor935464106 -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.94s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor206018049 -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.74s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor133101420 -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.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: test$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor062032859 -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.69s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor660156613 -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.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: test$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor351972754 -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.69s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor292312928 -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.89s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor949768062 -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.82s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor899322687 -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.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:false Trace:false} program: test$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor771877833 -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.81s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor396551828 -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.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: test$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor605054691 -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.79s) 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$length24(&(0x7f0000000000)={{0x3, {0x8}}, {0x3, {0x10}}}) test$end1(&(0x7f0000000040)={0xe}) test$type_confusion1(&(0x7f0000000080)=@f1=0x1) test$length28(&(0x7f00000000c0)=@f1=0x7e3, 0x2a) test$csum_ipv4_udp(&(0x7f0000000100)={{0x0, 0x9, 0x400}, {0x0, "7df7b5befee2d28ffbde3ce43115d2127910a4127a30c6e7de4f32c13a74f2df30159f22e294b8e14f1b5ab6f596188f10bbf328c575d2caa21a835d6e5e9bcfee70d38741c7caba753aff7275211fa6b3cfc964ddc3785caa56964676edd98d2fb444fce8898ff23c2fe6369f7f81eb9a9e067285af359789ecc345f93eca3235f9f1d3640f5f02ef44af8093657f5cb7"}}) test$type_confusion1(&(0x7f00000001c0)=@f1=0x4) seccomp() test$length8(&(0x7f0000000200)={0x34, {0x6, 0x1, 0x10, [0x9, 0x2, 0x7ff]}, [{0x7, 0x1, 0x10, [0x7fff, 0x8a, 0xffffffffffffff01]}], 0x10, 0x1, [0x3, 0x3, 0x4]}) syz_compare_int$3(0x3, 0xa80, 0x0, 0x8) test$text_x86_32(&(0x7f0000000240)="23503ef20f5fdf0f4dd2c7442400dcc10000c7442402fa000000c7442406000000000f011c24b8010000000f01d9c4c32d4a9966470000050f0d00640f01c49d660f017802", 0x45) syz_compare(&(0x7f0000000000)='\x00', 0x1, &(0x7f0000000040)=@bf1={{0x3, 0x1, 0x9662}, 0xffffffffffffffce}, 0x8) syz_compare_int$2(0x2, 0x80, 0x9c4) syz_errno(0x100000000) syz_execute_func(&(0x7f0000000080)="08fd9f3f0872ce6667d778041d0edde2917b7d6219b01c95a7e952611d5795b71f9f5e7687d7de2d91feb8f51776263b6ac9") syz_exit(0x1) syz_mmap(&(0x7f0000ffb000/0x3000)=nil, 0x3000) 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)))) struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } 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_seccomp #define SYS_seccomp 0 #endif #ifndef SYS_test #define SYS_test 0 #endif void execute_call(int call) { switch (call) { case 0: *(uint8_t*)0x20000000 = 3; *(uint32_t*)0x20000004 = 8; *(uint64_t*)0x20000008 = 3; *(uint32_t*)0x20000010 = 0x10; syscall(SYS_test, 0x20000000, 0, 0, 0, 0, 0); break; case 1: *(uint16_t*)0x20000040 = htobe16(0xe); *(uint32_t*)0x20000042 = htobe32(0x42); *(uint64_t*)0x20000046 = htobe64(0); syscall(SYS_test, 0x20000040, 0, 0, 0, 0, 0); break; case 2: *(uint8_t*)0x20000080 = 1; syscall(SYS_test, 0x20000080, 0, 0, 0, 0, 0); break; case 3: *(uint8_t*)0x200000c0 = 0xe3; syscall(SYS_test, 0x200000c0, 0x2a, 0, 0, 0, 0); break; case 4: *(uint16_t*)0x20000100 = 0; *(uint32_t*)0x20000102 = htobe32(9); *(uint32_t*)0x20000106 = htobe32(0x400); *(uint16_t*)0x2000010a = 0; memcpy((void*)0x2000010c, "\x7d\xf7\xb5\xbe\xfe\xe2\xd2\x8f\xfb\xde\x3c\xe4\x31\x15\xd2\x12\x79\x10\xa4\x12\x7a\x30\xc6\xe7\xde\x4f\x32\xc1\x3a\x74\xf2\xdf\x30\x15\x9f\x22\xe2\x94\xb8\xe1\x4f\x1b\x5a\xb6\xf5\x96\x18\x8f\x10\xbb\xf3\x28\xc5\x75\xd2\xca\xa2\x1a\x83\x5d\x6e\x5e\x9b\xcf\xee\x70\xd3\x87\x41\xc7\xca\xba\x75\x3a\xff\x72\x75\x21\x1f\xa6\xb3\xcf\xc9\x64\xdd\xc3\x78\x5c\xaa\x56\x96\x46\x76\xed\xd9\x8d\x2f\xb4\x44\xfc\xe8\x89\x8f\xf2\x3c\x2f\xe6\x36\x9f\x7f\x81\xeb\x9a\x9e\x06\x72\x85\xaf\x35\x97\x89\xec\xc3\x45\xf9\x3e\xca\x32\x35\xf9\xf1\xd3\x64\x0f\x5f\x02\xef\x44\xaf\x80\x93\x65\x7f\x5c\xb7", 145); struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20000102, 4); csum_inet_update(&csum_1, (const uint8_t*)0x20000106, 4); uint16_t csum_1_chunk_2 = 0x1100; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_2, 2); uint16_t csum_1_chunk_3 = 0x9300; csum_inet_update(&csum_1, (const uint8_t*)&csum_1_chunk_3, 2); csum_inet_update(&csum_1, (const uint8_t*)0x2000010a, 147); *(uint16_t*)0x2000010a = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20000100, 10); *(uint16_t*)0x20000100 = csum_inet_digest(&csum_2); syscall(SYS_test, 0x20000100, 0, 0, 0, 0, 0); break; case 5: *(uint8_t*)0x200001c0 = 4; syscall(SYS_test, 0x200001c0, 0, 0, 0, 0, 0); break; case 6: syscall(SYS_seccomp); break; case 7: *(uint64_t*)0x20000200 = 0x34; *(uint8_t*)0x20000208 = 6; *(uint8_t*)0x20000209 = 1; *(uint16_t*)0x2000020a = 0x10; *(uint32_t*)0x2000020c = 9; *(uint32_t*)0x20000210 = 2; *(uint32_t*)0x20000214 = 0x7ff; *(uint8_t*)0x20000218 = 7; *(uint8_t*)0x20000219 = 1; *(uint16_t*)0x2000021a = 0x10; *(uint32_t*)0x2000021c = 0x7fff; *(uint32_t*)0x20000220 = 0x8a; *(uint32_t*)0x20000224 = 0xffffff01; *(uint32_t*)0x20000228 = 0x10; *(uint16_t*)0x2000022c = 1; *(uint16_t*)0x2000022e = 3; *(uint16_t*)0x20000230 = 3; *(uint16_t*)0x20000232 = 4; syscall(SYS_test, 0x20000200, 0, 0, 0, 0, 0); break; case 8: syz_compare_int(3, 0xa80, 0, 8, 0); break; case 9: memcpy((void*)0x20000240, "\x23\x50\x3e\xf2\x0f\x5f\xdf\x0f\x4d\xd2\xc7\x44\x24\x00\xdc\xc1\x00\x00\xc7\x44\x24\x02\xfa\x00\x00\x00\xc7\x44\x24\x06\x00\x00\x00\x00\x0f\x01\x1c\x24\xb8\x01\x00\x00\x00\x0f\x01\xd9\xc4\xc3\x2d\x4a\x99\x66\x47\x00\x00\x05\x0f\x0d\x00\x64\x0f\x01\xc4\x9d\x66\x0f\x01\x78\x02", 69); syscall(SYS_test, 0x20000240, 0x45, 0, 0, 0, 0); break; case 10: memcpy((void*)0x20000000, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000040, 3, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 1, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0x9662, 20, 10); *(uint8_t*)0x20000044 = 0xce; syz_compare(0x20000000, 1, 0x20000040, 8); break; case 11: syz_compare_int(2, 0x80, 0x9c4, 0, 0); break; case 12: syz_errno(0); break; case 13: memcpy((void*)0x20000080, "\x08\xfd\x9f\x3f\x08\x72\xce\x66\x67\xd7\x78\x04\x1d\x0e\xdd\xe2\x91\x7b\x7d\x62\x19\xb0\x1c\x95\xa7\xe9\x52\x61\x1d\x57\x95\xb7\x1f\x9f\x5e\x76\x87\xd7\xde\x2d\x91\xfe\xb8\xf5\x17\x76\x26\x3b\x6a\xc9", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(1); break; case 15: syz_mmap(0x20ffb000, 0x3000); 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-executor792201958 -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_fork (0.44s) csource_test.go:72: seed=1568782896115839371 --- FAIL: TestGenerate/test/64_fork/0 (0.88s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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); } #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); #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_errno(9); memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); syz_exit(3); memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); syz_errno(0xf12); memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); syz_exit(0); syz_mmap(0x20ff8000, 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-executor170384762 -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.50s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor235808088 -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.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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor078908705 -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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor584388170 -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.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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor846031333 -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.76s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor060053504 -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.50s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor503802719 -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.82s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); fprintf(stderr, "### call=0 errno=%u\n", res == -1 ? errno : 0); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); res = syz_compare(0x20000000, 0, 0x20000040, 0x6a); fprintf(stderr, "### call=1 errno=%u\n", res == -1 ? errno : 0); break; case 2: res = syz_exit(3); fprintf(stderr, "### call=2 errno=%u\n", res == -1 ? errno : 0); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); res = syz_compare(0x200000c0, 1, 0x20000100, 2); fprintf(stderr, "### call=3 errno=%u\n", res == -1 ? errno : 0); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); res = syz_compare(0x20000140, 1, 0x20000180, 8); fprintf(stderr, "### call=4 errno=%u\n", res == -1 ? errno : 0); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; res = syz_compare(0x200001c0, 1, 0x20000200, 8); fprintf(stderr, "### call=5 errno=%u\n", res == -1 ? errno : 0); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; res = syz_compare(0x20000240, 1, 0x20000280, 0x18); fprintf(stderr, "### call=6 errno=%u\n", res == -1 ? errno : 0); break; case 7: res = syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); fprintf(stderr, "### call=7 errno=%u\n", res == -1 ? errno : 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; res = syz_compare(0x200002c0, 1, 0x20000300, 0x20); fprintf(stderr, "### call=8 errno=%u\n", res == -1 ? errno : 0); break; case 9: res = syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); fprintf(stderr, "### call=9 errno=%u\n", res == -1 ? errno : 0); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; res = syz_compare(0x20000000, 2, 0x20000040, 8); fprintf(stderr, "### call=10 errno=%u\n", res == -1 ? errno : 0); break; case 11: res = syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); fprintf(stderr, "### call=11 errno=%u\n", res == -1 ? errno : 0); break; case 12: res = syz_errno(0xf12); fprintf(stderr, "### call=12 errno=%u\n", res == -1 ? errno : 0); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); res = syz_execute_func(0x20000080); fprintf(stderr, "### call=13 errno=%u\n", res == -1 ? errno : 0); break; case 14: res = syz_exit(0); fprintf(stderr, "### call=14 errno=%u\n", res == -1 ? errno : 0); break; case 15: res = syz_mmap(0x20ff8000, 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-executor916929822 -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.92s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor870203698 -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.74s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: NONFAILING(memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106)); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: NONFAILING(memcpy((void*)0x200000c0, "\000", 1)); NONFAILING(*(uint16_t*)0x20000100 = htobe16(8)); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: NONFAILING(memcpy((void*)0x20000140, "\000", 1)); NONFAILING(STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4)); NONFAILING(STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8)); NONFAILING(STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12)); NONFAILING(STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20)); NONFAILING(STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16)); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: NONFAILING(memcpy((void*)0x200001c0, "\000", 1)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10)); NONFAILING(*(uint8_t*)0x20000204 = 2); syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: NONFAILING(memcpy((void*)0x20000240, "\000", 1)); NONFAILING(*(uint16_t*)0x20000280 = 6); NONFAILING(*(uint32_t*)0x20000284 = 4); NONFAILING(*(uint8_t*)0x20000288 = 0xf); NONFAILING(*(uint16_t*)0x2000028a = 3); NONFAILING(*(uint64_t*)0x20000290 = 3); syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: NONFAILING(memcpy((void*)0x200002c0, "\000", 1)); NONFAILING(STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10)); NONFAILING(*(uint64_t*)0x20000308 = 0x3f); NONFAILING(STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5)); NONFAILING(STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15)); NONFAILING(STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11)); NONFAILING(STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11)); NONFAILING(*(uint8_t*)0x2000031c = -1); syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: NONFAILING(memcpy((void*)0x20000000, ".\000", 2)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10)); NONFAILING(STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10)); NONFAILING(*(uint8_t*)0x20000044 = 3); syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: NONFAILING(memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50)); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor627518260 -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.88s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor398708969 -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.85s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor726818438 -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.88s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor979112707 -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.91s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor086478893 -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.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:false Trace:false} program: syz_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor838383528 -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.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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor946956570 -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.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: syz_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor466933991 -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.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: syz_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor584322481 -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.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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor486142300 -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.89s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor712408843 -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.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: syz_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor261276910 -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.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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor703596917 -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.82s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor989900368 -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.72s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor212025346 -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.95s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor579775865 -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.55s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor274574583 -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.42s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); } void execute_call(int call) { switch (call) { case 0: syz_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor585804266 -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.50s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor434556993 -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.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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor665456300 -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.97s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor099525147 -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.78s) 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_errno(0x9) syz_compare(&(0x7f0000000000), 0x0, &(0x7f0000000040)=@blob="529d927649b80ed16dc3b18de3ce6008ec6d92cd02775ec720fc4772b91742ed9d419ababc7e97d4b59c4586b238365f3c73c63ebc4145f8e0ed073e8160ca081b16733f6d7a137a8e8e97ad57a91ac1da5fa15da98acfcbd5b07ae88dee76829c89092c0f550b20a9ae", 0x6a) syz_exit(0x3) syz_compare(&(0x7f00000000c0)='\x00', 0x1, &(0x7f0000000100)=@arr16be=[0x8], 0x2) syz_compare(&(0x7f0000000140)='\x00', 0x1, &(0x7f0000000180)=@bf3={0x2, 0x7, 0x0, 0x7, 0x4}, 0x8) syz_compare(&(0x7f00000001c0)='\x00', 0x1, &(0x7f0000000200)=@bf1={{0x5, 0x2, 0x4}, 0x2}, 0x8) syz_compare(&(0x7f0000000240)='\x00', 0x1, &(0x7f0000000280)=@align0={0x6, 0x4, 0xf, 0x3, 0x3}, 0x18) syz_compare_int$4(0x4, 0x449d, 0x9c5, 0x607, 0x0) syz_compare(&(0x7f00000002c0)='\x00', 0x1, &(0x7f0000000300)=@bf0={0x0, 0x3f, 0x42, 0x40, 0x42, 0x20, 0x20, 0xffffffff}, 0x20) syz_compare_int$4(0x4, 0x8001, 0x20, 0x3ff, 0x1) syz_compare(&(0x7f0000000000)='.\x00', 0x2, &(0x7f0000000040)=@bf1={{0x2, 0xd3, 0xff80000000000000}, 0x3}, 0x8) syz_compare_int$2(0x2, 0xfffffffffffffff5, 0x0) syz_errno(0xf12) syz_execute_func(&(0x7f0000000080)="bd57f0c7498194304739540063ab1e5d2c15c7732c8f0fd3167ba5b7159721fdec0020b68add84e9f90ad03c876c8910dc05") syz_exit(0x0) syz_mmap(&(0x7f0000ff8000/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; } #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); #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_errno(9); break; case 1: memcpy((void*)0x20000040, "\x52\x9d\x92\x76\x49\xb8\x0e\xd1\x6d\xc3\xb1\x8d\xe3\xce\x60\x08\xec\x6d\x92\xcd\x02\x77\x5e\xc7\x20\xfc\x47\x72\xb9\x17\x42\xed\x9d\x41\x9a\xba\xbc\x7e\x97\xd4\xb5\x9c\x45\x86\xb2\x38\x36\x5f\x3c\x73\xc6\x3e\xbc\x41\x45\xf8\xe0\xed\x07\x3e\x81\x60\xca\x08\x1b\x16\x73\x3f\x6d\x7a\x13\x7a\x8e\x8e\x97\xad\x57\xa9\x1a\xc1\xda\x5f\xa1\x5d\xa9\x8a\xcf\xcb\xd5\xb0\x7a\xe8\x8d\xee\x76\x82\x9c\x89\x09\x2c\x0f\x55\x0b\x20\xa9\xae", 106); syz_compare(0x20000000, 0, 0x20000040, 0x6a); break; case 2: syz_exit(3); break; case 3: memcpy((void*)0x200000c0, "\000", 1); *(uint16_t*)0x20000100 = htobe16(8); syz_compare(0x200000c0, 1, 0x20000100, 2); break; case 4: memcpy((void*)0x20000140, "\000", 1); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 2, 0, 4); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 4, 8); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 0, 12, 12); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 7, 24, 20); STORE_BY_BITMASK(uint64_t, htobe64, 0x20000180, 4, 44, 16); syz_compare(0x20000140, 1, 0x20000180, 8); break; case 5: memcpy((void*)0x200001c0, "\000", 1); STORE_BY_BITMASK(uint32_t, , 0x20000200, 5, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 2, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000200, 4, 20, 10); *(uint8_t*)0x20000204 = 2; syz_compare(0x200001c0, 1, 0x20000200, 8); break; case 6: memcpy((void*)0x20000240, "\000", 1); *(uint16_t*)0x20000280 = 6; *(uint32_t*)0x20000284 = 4; *(uint8_t*)0x20000288 = 0xf; *(uint16_t*)0x2000028a = 3; *(uint64_t*)0x20000290 = 3; syz_compare(0x20000240, 1, 0x20000280, 0x18); break; case 7: syz_compare_int(4, 0x449d, 0x9c5, 0x607, 0); break; case 8: memcpy((void*)0x200002c0, "\000", 1); STORE_BY_BITMASK(uint16_t, , 0x20000300, 0, 0, 10); *(uint64_t*)0x20000308 = 0x3f; STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x42, 0, 5); STORE_BY_BITMASK(uint16_t, , 0x20000310, 0x40, 5, 6); STORE_BY_BITMASK(uint32_t, , 0x20000314, 0x42, 0, 15); STORE_BY_BITMASK(uint16_t, , 0x20000318, 0x20, 0, 11); STORE_BY_BITMASK(uint16_t, htobe16, 0x2000031a, 0x20, 0, 11); *(uint8_t*)0x2000031c = -1; syz_compare(0x200002c0, 1, 0x20000300, 0x20); break; case 9: syz_compare_int(4, 0x8001, 0x20, 0x3ff, 1); break; case 10: memcpy((void*)0x20000000, ".\000", 2); STORE_BY_BITMASK(uint32_t, , 0x20000040, 2, 0, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0xd3, 10, 10); STORE_BY_BITMASK(uint32_t, , 0x20000040, 0, 20, 10); *(uint8_t*)0x20000044 = 3; syz_compare(0x20000000, 2, 0x20000040, 8); break; case 11: syz_compare_int(2, 0xfffffffffffffff5, 0, 0, 0); break; case 12: syz_errno(0xf12); break; case 13: memcpy((void*)0x20000080, "\xbd\x57\xf0\xc7\x49\x81\x94\x30\x47\x39\x54\x00\x63\xab\x1e\x5d\x2c\x15\xc7\x73\x2c\x8f\x0f\xd3\x16\x7b\xa5\xb7\x15\x97\x21\xfd\xec\x00\x20\xb6\x8a\xdd\x84\xe9\xf9\x0a\xd0\x3c\x87\x6c\x89\x10\xdc\x05", 50); syz_execute_func(0x20000080); break; case 14: syz_exit(0); break; case 15: syz_mmap(0x20ff8000, 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-executor269568672 -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 FAIL github.com/google/syzkaller/pkg/csource 29.549s 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 0.097s ? 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 3.494s ok github.com/google/syzkaller/pkg/ipc 21.060s ? 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 0.359s ok github.com/google/syzkaller/pkg/osutil (cached) ok github.com/google/syzkaller/pkg/report 11.237s ok github.com/google/syzkaller/pkg/repro 3.772s ? github.com/google/syzkaller/pkg/rpctype [no test files] ok github.com/google/syzkaller/pkg/runtest 0.270s 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 64.372s 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 1.408s ? 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 1.725s ? github.com/google/syzkaller/syz-fuzzer [no test files] ok github.com/google/syzkaller/syz-hub 0.251s 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 0.089s ok github.com/google/syzkaller/tools/syz-trace2syz/proggen 0.938s ? 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 16.018s ? 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]