// https://syzkaller.appspot.com/bug?id=aaef532c9f73f2ae51e1ecf92c03374e7a2829f5 // 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 unsigned long long procid; 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; int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0; int valid = addr < prog_start || addr > prog_end; if (sig == SIGBUS) { valid = 1; } if (skip && valid) { _longjmp(segv_env, 1); } exit(sig); } static void install_segv_handler(void) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = segv_handler; sa.sa_flags = SA_NODEFER | SA_SIGINFO; sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); } #define NONFAILING(...) \ ({ \ int ok = 1; \ __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \ if (_setjmp(segv_env) == 0) { \ __VA_ARGS__; \ } else \ ok = 0; \ __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \ ok; \ }) static void kill_and_wait(int pid, int* status) { kill(pid, SIGKILL); while (waitpid(-1, status, 0) != pid) { } } static void sleep_ms(uint64_t ms) { usleep(ms * 1000); } static uint64_t current_time_ms(void) { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts)) exit(1); return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; } static void thread_start(void* (*fn)(void*), void* arg) { pthread_t th; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 128 << 10); int i = 0; for (; i < 100; i++) { if (pthread_create(&th, &attr, fn, arg) == 0) { pthread_attr_destroy(&attr); return; } if (errno == EAGAIN) { usleep(50); continue; } break; } exit(1); } typedef struct { pthread_mutex_t mu; pthread_cond_t cv; int state; } event_t; static void event_init(event_t* ev) { if (pthread_mutex_init(&ev->mu, 0)) exit(1); if (pthread_cond_init(&ev->cv, 0)) exit(1); ev->state = 0; } static void event_reset(event_t* ev) { ev->state = 0; } static void event_set(event_t* ev) { pthread_mutex_lock(&ev->mu); if (ev->state) exit(1); ev->state = 1; pthread_mutex_unlock(&ev->mu); pthread_cond_broadcast(&ev->cv); } static void event_wait(event_t* ev) { pthread_mutex_lock(&ev->mu); while (!ev->state) pthread_cond_wait(&ev->cv, &ev->mu); pthread_mutex_unlock(&ev->mu); } static int event_isset(event_t* ev) { pthread_mutex_lock(&ev->mu); int res = ev->state; pthread_mutex_unlock(&ev->mu); return res; } static int event_timedwait(event_t* ev, uint64_t timeout) { uint64_t start = current_time_ms(); uint64_t now = start; pthread_mutex_lock(&ev->mu); for (;;) { if (ev->state) break; uint64_t remain = timeout - (now - start); struct timespec ts; ts.tv_sec = remain / 1000; ts.tv_nsec = (remain % 1000) * 1000 * 1000; pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); now = current_time_ms(); if (now - start > timeout) break; } int res = ev->state; pthread_mutex_unlock(&ev->mu); return res; } struct thread_t { int created, call; event_t ready, done; }; static struct thread_t threads[16]; static void execute_call(int call); static int running; static void* thr(void* arg) { struct thread_t* th = (struct thread_t*)arg; for (;;) { event_wait(&th->ready); event_reset(&th->ready); execute_call(th->call); __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); event_set(&th->done); } return 0; } static void execute_one(void) { int i, call, thread; int collide = 0; again: for (call = 0; call < 5; 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, 50); 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 = 0; for (;; 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 < 5000) { continue; } kill_and_wait(pid, &status); break; } } } uint64_t r[1] = {0xffffffffffffffff}; void execute_call(int call) { intptr_t res = 0; switch (call) { case 0: syscall(SYS_ioctl, 0xffffff9c, 0xc450443cul, 0ul); break; case 1: NONFAILING(memcpy((void*)0x20000000, "/dev/pf\000", 8)); res = syscall(SYS_openat, 0xffffffffffffff9cul, 0x20000000ul, 0ul, 0ul); if (res != -1) r[0] = res; break; case 2: NONFAILING(memcpy( (void*)0x20000040, "\xdf\x1a\x0b\x98\x7c\x6c\xdb\x8f\x79\xd5\x39\x07\xdc\xad\xfb\xc3\xb5" "\x26\x2d\x98\x74\xfb\x15\xf9\xf9\x0f\xe8\x20\x1a\x4b\xeb\xbd\xbd\x6f" "\x33\xbd\x2b\x77\x79\x28\xdd\x7c\x68\xab\x9b\x47\x52\xe9\xd7\x7a\x94" "\x12\x52\xe1\xe9\x73\x89\x4e\x2c\x03\x29\x6a\x8e\x06\x4e\xc0\xa1\xa2" "\x54\x58\xe5\x51\x5f\xb8\x0e\x75\xa0\x70\xff\xdc\x02\x56\x8a\x53\x4c" "\x5c\xe6\x38\xcd\xe6\x24\xe3\xa0\xc5\x26\x6b\x97\x31\xd6\x52\x37\xde" "\xea\x54\xdf\x91\x91\xca\x7a\xa7\x97\xf0\xb5\x6e\xb7\x07\x74\x13\x02" "\xd8\x44\x31\x48\x77\x26\x48\xfe\x93\xe6\xed\xe8\x74\x84\xc8\x74\x60" "\xc3\xfa\xa7\xab\xf7\x32\xb4\xf7\x6d\xfa\xc3\x12\x7d\xb6\x26\x6b\x43" "\x51\xc5\x4b\xcf\x2d\xf9\x72\x8e\x0c\xd5\x6b\xef\x14\x96\x94\x54\x0e" "\x3d\x15\x1d\x71\x1d\xfa\x14\x0b\x54\x40\x71\x33\xbe\x11\x57\xc2\xd1" "\xa7\xaa\x5f\x25\x5c\x9d\x89\xb1\xa2\xc3\x87\xef\x0d\xf7\x65\x80\x54" "\x62\x74\xb0\xcd\xc8\x40\x56\x9e\xf6\x41\xfe\x5c\x80\x5a\x92\x03\xaa" "\x6a\x35\x4e\xcd\x06\x47\xc2\x01\x2d\xd4\xd3\x28\xf3\x32\x9e\x6b\xf4" "\x69\xc7\xe8\xfc\x06\x02\xb9\x6e\xe0\x50\x0f\x4d\x3b\x01\x27\xe0\xf8" "\x38\x1a\x94\xc0\x47\x21\x32\x2d\x66\xb9\x46\x59\x54\x60\x43\x04\x4d" "\x2c\x2f\xfb\x3c\x4e\x89\xd0\x1d\xe4\xbf\x18\xbc\x8e\x67\xfe\xca\xba" "\x1a\xa0\x07\x78\x09\x7d\xc3\xbe\x3f\x20\xe0\x0a\x4d\x55\xcf\x3b\xeb" "\x74\xe0\xc0\xe1\x73\x83\x7f\x51\x11\xe6\x11\xcf\x98\x54\x89\x12\x33" "\x56\x51\xe8\x37\xd3\x3e\x4f\x5c\xff\x5a\x11\x1e\xa5\x99\xcf\x2f\xd8" "\xe7\x3d\xd8\x96\xa6\xd3\x90\x02\x1d\x68\xf5\x2a\x26\x22\x0f\xd5\xf4" "\x80\x19\xfc\x33\xa4\xf0\x80\x5f\xf7\x51\xd6\xf7\x79\x39\xc5\x4e\xd1" "\xbf\x3c\x13\x21\x33\xf3\x01\xf8\x35\xa5\x53\x11\x66\xcb\x85\x69\x38" "\x68\x03\x3f\x51\xf7\xb4\x36\x87\xac\x34\xf0\x67\x0e\x5b\xbe\x7a\x47" "\x9f\xbd\x72\xc2\xa7\x5f\xf9\x35\xc7\x72\xbe\xc2\x54\x3e\xb3\x0e\x1e" "\x26\xaa\xa8\xc2\x76\xcb\x60\xcb\xdd\x77\xe7\xeb\x97\xf1\x34\x0c\x49" "\xe7\x9c\xa2\xa7\xd2\xa5\x42\x92\xcb\xae\xe0\x03\xd3\x35\xbe\x50\x4d" "\xb4\xea\x04\x7c\x36\xd7\xd8\x9e\xb8\x43\x46\x8a\x50\x5b\x14\x10\x3b" "\xc2\xf3\x21\x2c\xc0\x1d\x6d\x3a\x64\x5a\xf1\xd3\x42\xc9\xa9\xd1\x44" "\x02\x02\x5e\x77\x66\xdb\x44\x97\xab\x75\xaf\x0a\x41\x16\x9e\xd5\xdc" "\xba\xa9\x9e\x8c\x6e\x33\x82\x41\x21\x6a\xb9\xab\x55\xcb\x7b\x94\x31" "\x3b\x57\x5a\x9b\xaf\x3b\x12\xef\xf5\x9b\x38\x12\x4b\x9f\x20\x53\x77" "\xee\x41\x99\x10\xb8\xda\x94\x23\x17\xe3\x67\xc7\x69\x7b\x0c\xcc\x80" "\xba\x2f\xa3\x74\x7e\xbc\x4b\x1c\x9c\x71\x73\x58\xe5\xbc\x81\x97\xd1" "\x71\x6c\x4f\x73\xde\xc3\x86\x73\x2f\x4b\xbb\x16\xc3\xb6\x80\x43\x20" "\x34\x94\xd4\x8b\xee\x19\x6a\x8d\x6c\x3a\x40\x05\xfd\xbf\xa4\x68\xac" "\x44\xc2\xcc\x52\x6c\xe0\xdb\x6c\xaf\x18\x2b\xaa\x51\x54\xba\x84\xd1" "\x09\x79\x12\x0b\x1c\xc5\x0a\xcb\x4b\xb4\x0f\x45\x2a\x36\x64\x3d\xc8" "\xfa\x9d\xb8\x7c\xcc\xce\x3a\x53\xe1\x0c\x1f\xe8\x24\xb8\xad\x6f\xdc" "\xc1\xb7\x2f\x42\x7b\x61\x43\x3c\xd6\x6c\xd6\x92\xbc\x67\x41\x0f\xda" "\x00\xae\x33\x13\x32\xa7\x3c\xfb\x8b\x51\xc5\x0a\x1f\x3a\x77\x80\xf4" "\x43\x0a\x4a\x6d\xe9\xe2\x62\x91\xa2\x2f\xae\xc5\xd6\xec\xd0\xc6\x9e" "\x13\x62\x44\x39\x98\x87\x13\xfa\x99\x40\xc1\xe3\xdb\x39\x67\x07\xc8" "\x74\xfc\xe9\x97\x62\x23\xbf\x4d\x23\x80\xb8\xa7\x4e\x4a\x02\xbf\x07" "\x6d\x76\xea\x8f\x26\x83\x30\xea\xf1\x8a\xc6\x35\x24\x07\x15\x79\xff" "\x3e\x74\x91\x6a\x4c\xd1\xca\x59\x2e\x40\xc9\xbe\x48\x57\x33\x10\xf3" "\xd7\xce\xb5\xf3\xcc\xe0\x66\x41\x52\x78\x2d\x8a\x52\x00\x2b\xa1\xf1" "\xcf\xc5\x09\xfc\x5e\x37\x2b\x1f\xe7\x5a\x1c\x8c\x74\x80\x50\xee\x1b" "\xb7\x45\xe0\x90\x52\xb7\x37\x15\x7d\xaa\xe6\x12\x31\x9f\xca\xd9\xd3" "\xc7\x7c\x31\xd1\x48\x52\xe5\x3f\x4f\x3b\xdd\x67\xc1\xad\xa4\x7d\x9e" "\xd4\x2a\xdb\x2f\xc3\xee\x10\xc2\x75\x57\x2c\xb4\x4f\xdd\x4b\x40\x8a" "\x41\x66\xc2\x3b\x45\x34\x72\xbe\xee\xaf\x3e\x8d\x32\x2d\xbb\xe1\xb6" "\x35\x14\xe0\xb1\x12\x84\x9c\x69\xd3\xad\xe3\xe6\xc4\xf2\x5c\x33\x8d" "\x4e\xcd\x38\x52\x2c\xfc\xd0\x58\x20\x1a\xf0\xfb\xb9\x0a\xf7\x46\xb1" "\x4c\x79\xef\xc9\x62\xde\x9e\xd3\xa8\x6a\x1e\x53\x3e\x75\xa0\xe4\x43" "\x1a\x10\x13\x2e\x9d\x8c\x80\xe8\xd6\xa6\x9c\xaf\x7a\xfa\x40\xd7\xb5" "\xad\x91\xb0\x51\x7b\x27\xd2\x63\x1d\x9b\x27\xba\x8b\x38\x37\xaa\x25" "\xe5\xc3\x6a\x42\xbf\xbf\xda\xdb\xcb\x67\x7e\x80\x85\x12\xff\xf1\xf9" "\x91\x15\x5a\x7a\xdf\xec\x98\x7a\xc5\x1f\xa9\xfa\x4c\xdf\x78\xb9\xfe" "\x7d\xaa\x84\x95\xcc\x53\x8b\xce\xa8\xe1\xfb\x00\x47\x0c\xbd\xc4\x67" "\x67\x66\xac\xb2", 1024)); NONFAILING(memcpy( (void*)0x20000440, "\x84\x28\xa4\x99\xe4\x5c\xcf\xaf\xd8\xf0\xca\x9e\x40\x6e\xe2\x33\xbc" "\x62\x03\x00\x00\x00\x48\x1a\xfa\xdb\xe2\x99\x19\x61\x80\xa1", 32)); NONFAILING(*(uint32_t*)0x20000460 = 0xfffffffd); NONFAILING(*(uint8_t*)0x20000464 = 0); NONFAILING(*(uint64_t*)0x20000468 = 0); NONFAILING(*(uint64_t*)0x20000470 = 0); NONFAILING(*(uint64_t*)0x20000478 = 0); NONFAILING(*(uint64_t*)0x20000480 = 0); NONFAILING(*(uint64_t*)0x20000488 = 0); NONFAILING(*(uint64_t*)0x20000490 = 0); NONFAILING(*(uint64_t*)0x20000498 = 0x80000000000000); NONFAILING(*(uint64_t*)0x200004a0 = 0xfff); NONFAILING(*(uint32_t*)0x200004a8 = 0); syscall(SYS_ioctl, r[0], 0xc4504441ul, 0x20000040ul); break; case 3: NONFAILING(memcpy( (void*)0x200019c0, "\xc5\x7c\x6a\x7f\x69\x92\x73\x9c\xdd\x48\xe6\x0b\x45\xee\x25\x7c\x97" "\x04\xa8\x12\x17\x53\x2e\x80\x1e\x67\x4a\x48\xe5\x53\x0f\xef\x75\xb1" "\x7e\xa3\x82\x36\x23\xc1\xdb\xaf\x06\x63\xf5\x48\x61\x01\x99\x0b\xf4" "\xf9\x5d\xbc\x52\x03\xb7\xa2\x0f\xae\xf5\xf0\x45\x45\x6b\xed\xc2\xc2" "\x71\x5c\xd5\xe0\x21\x7a\x93\xc5\x31\x65\x78\xd7\xf1\x98\x4e\x66\x68" "\xd5\xde\x41\x5e\x76\x97\xc4\x33\xba\x51\x54\x9d\x71\x87\xd2\x66\x15" "\x77\x5a\xa5\x26\xfc\x8d\x16\xb9\x32\x43\x1a\xd6\xdc\xef\xcd\x94\x19" "\x1a\xf1\xbf\x00\x48\x9e\x0b\x8f\x3e\xce\xe1\x23\x75\x26\x4c\xa0\xf5" "\x8c\xf4\x38\x48\x99\x29\x69\x24\x46\xa4\x62\x1e\x50\xa0\x27\xe7\xa1" "\xbe\x2e\x8d\x18\x80\xef\xd6\x48\xba\x36", 163)); syscall(SYS_ioctl, r[0], 0xc0104419ul, 0x200019c0ul); break; case 4: syscall(SYS_ioctl, -1, 0xc450444aul, 0ul); break; } } int main(void) { syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); install_segv_handler(); for (procid = 0; procid < 4; procid++) { if (fork() == 0) { loop(); } } sleep(1000000); return 0; }