// https://syzkaller.appspot.com/bug?id=363ff76bf48bd8fe1fc097374b652c507f51d26e // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #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); if (pthread_create(&th, &attr, fn, arg)) exit(1); pthread_attr_destroy(&attr); } 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 loop(void) { int i, call, thread; for (call = 0; call < 2; 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: syscall(SYS_mmap, 0x20000000, 0x4000, 0, 0x8832, -1, 0); break; case 1: *(uint32_t*)0x200005c0 = -1; *(uint32_t*)0x200005c4 = 3; *(uint32_t*)0x200005c8 = 0x40; *(uint32_t*)0x200005cc = 0x2c1d; *(uint64_t*)0x200005d0 = 0x20000100; *(uint64_t*)0x20000100 = 0x20000080; memcpy((void*)0x20000080, "\x3f\x03\x30\x04\x4b\xce\x3a\x23\x84\x74\xfa\xa3\x42\xe0\xdc\xa9" "\xf9\x50\x11\x76\xa5\xd2\x36\xe8\xd9\x4b\xd6\x45\x46\x41\x4a\x57" "\xc7\xca\x55\x94\x9e\xbc\xd7\xb1\x04\x75\xac\x60\x74\x30\x24\x43" "\x0c\x47\x40\x02\x9f\x7f\x0d\x56\x38\x25\xa7\x7a\x09\x22\x51\xf6" "\xdb\xa7\xe8\xec\xa5\x05\x7a\x9d\x37\xaa\xd3\x96\xc2\x3b\xf4\xa0", 80); *(uint32_t*)0x20000108 = 0xdfe; *(uint8_t*)0x2000010c = 1; *(uint32_t*)0x20000110 = 6; *(uint64_t*)0x20000118 = 0x88; *(uint64_t*)0x20000120 = 0x10000; *(uint64_t*)0x200005d8 = 0; *(uint32_t*)0x200005e0 = -1; *(uint32_t*)0x200005e4 = 3; *(uint32_t*)0x200005e8 = 0x410; *(uint32_t*)0x200005ec = 0x1f; *(uint64_t*)0x200005f0 = 0x20000280; *(uint64_t*)0x20000280 = 0x20000200; memcpy((void*)0x20000200, "\xfb\x6d\xac\x98\x3b\xac\x0c\xa1\xf5\xa6\x84\x3b\xd8\x42\x2c\x26" "\x4b\x28\x65\xb7\xd1\xd0\x47\xb6\x6f\x18\xe3\xaf\x61\xe1\xb8\x53" "\xab\x52\xa2\x0a\x97\x06\x90\xf9\xd8\x41\x50\x9b\x4b\xa7\x70\x58" "\x29\xd7\xc0\x1a\xcb\xec\x3d\x16\x04\x7f\x1f\x9d\xbf\xb3\x45\x05" "\xf8\x3b\xdb\x95\x3a\x9c\xb0\xe8\xa2\xc9\xfe\x29\x52\xc8\xcb\xdc", 80); *(uint32_t*)0x20000288 = 1; *(uint8_t*)0x2000028c = 1; *(uint32_t*)0x20000290 = 0x72da; *(uint64_t*)0x20000298 = 9; *(uint64_t*)0x200002a0 = 2; *(uint64_t*)0x200005f8 = 0; *(uint32_t*)0x20000600 = -1; *(uint32_t*)0x20000604 = 1; *(uint32_t*)0x20000608 = 4; *(uint32_t*)0x2000060c = 8; *(uint64_t*)0x20000610 = 0x20000340; *(uint64_t*)0x20000340 = 0x200002c0; memcpy((void*)0x200002c0, "\xef\x19\xc5\x25\xc3\x2b\xcd\x7d\x85\x0f\x60\xa8\xdc\x90\x09\xce" "\x79\x8a\x07\x9b\x51\xb8\x55\xbd\xfc\xd1\x62\xb0\x54\xa2\xb7\xa1" "\xb6\xf2\x42\x6e\xac\x84\x5b\xa6\x32\x77\xa0\xc6\x86\xf3\xb7\xd9" "\x27\xdd\xaf\xfd\x19\x5e\x17\xa3\x33\x7c\x56\x86\xd1\xfa\xc3\x9b" "\x64\xdf\x2a\xb8\x2c\xe5\x80\x1c\x46\x0e\xa3\xe8\xc3\x8c\x02\x18", 80); *(uint32_t*)0x20000348 = 0xd3d; *(uint8_t*)0x2000034c = 1; *(uint32_t*)0x20000350 = 9; *(uint64_t*)0x20000358 = 0; *(uint64_t*)0x20000360 = 0xe91; *(uint64_t*)0x20000618 = 0; *(uint32_t*)0x20000620 = -1; *(uint32_t*)0x20000624 = 3; *(uint32_t*)0x20000628 = 1; *(uint32_t*)0x2000062c = 0x100; *(uint64_t*)0x20000630 = 0x20000400; *(uint64_t*)0x20000400 = 0x20000380; memcpy((void*)0x20000380, "\x51\x6b\x8d\xe6\x21\x06\x30\xea\x8e\x2b\xeb\xf1\xf0\x7e\x77\x2b" "\xb7\xc0\x4c\xf6\xde\x1e\x05\x47\xdf\xb8\x27\x4c\xa0\x34\xe2\x17" "\x37\x33\x80\x2d\x99\x1a\xda\xaf\xa2\x0b\xf2\x13\xa5\xd7\xf9\x1f" "\xb3\x94\xda\xd9\x18\x38\x3d\x35\xfd\x47\x09\x3f\x6d\xf8\x77\x21" "\xd8\x42\x8a\x9f\x25\xca\xbb\x0c\xa1\xd5\x93\xac\xa4\x2c\xe1\x2d", 80); *(uint32_t*)0x20000408 = 1; *(uint8_t*)0x2000040c = 1; *(uint32_t*)0x20000410 = 8; *(uint64_t*)0x20000418 = 0x7db75713; *(uint64_t*)0x20000420 = 9; *(uint64_t*)0x20000638 = 0; *(uint32_t*)0x20000640 = -1; *(uint32_t*)0x20000644 = 2; *(uint32_t*)0x20000648 = 0x41; *(uint32_t*)0x2000064c = 0x7f; *(uint64_t*)0x20000650 = 0x200004c0; *(uint64_t*)0x200004c0 = 0x20000440; memcpy((void*)0x20000440, "\x24\x71\xce\xaf\x50\x2f\x9c\x21\x4b\xa3\xba\x53\xca\xe2\xfa\x40" "\xcf\xcf\x29\x6e\x0f\x0e\xa7\x38\x82\xcb\x90\x50\x18\x56\x94\x74" "\x86\x73\x53\x49\xcc\x87\x57\xd1\xbd\x29\xc1\xc3\x58\x0e\x96\x5a" "\xb1\xa4\x62\x73\x5d\xba\x8a\x3e\xf7\xe9\x27\x8c\x7a\x74\x36\x11" "\x95\x2a\xc5\x6b\x41\xa6\x52\x83\xc1\x2c\xb6\xc7\xa7\x16\x64\x4a", 80); *(uint32_t*)0x200004c8 = 2; *(uint8_t*)0x200004cc = 1; *(uint32_t*)0x200004d0 = 0xfffffffc; *(uint64_t*)0x200004d8 = 7; *(uint64_t*)0x200004e0 = 6; *(uint64_t*)0x20000658 = 0; *(uint32_t*)0x20000660 = -1; *(uint32_t*)0x20000664 = 3; *(uint32_t*)0x20000668 = 8; *(uint32_t*)0x2000066c = 0; *(uint64_t*)0x20000670 = 0x20000580; *(uint64_t*)0x20000580 = 0x20000500; memcpy((void*)0x20000500, "\xd7\xaf\xa8\x68\xfa\xb2\x38\xfb\xdb\x0e\x85\xcd\x25\x3c\x41\xe0" "\xa8\xc3\x22\xcc\x74\xaf\x38\x18\xe2\xd8\xd2\x7a\xd0\xf0\x6b\x8e" "\xb6\x21\xff\x4d\x83\x87\xea\x7e\x37\x08\x90\xf9\x42\xf7\xbc\x19" "\x01\xef\x7b\xa4\xcc\x09\xc8\x78\xa0\x4a\x46\xef\x22\x9b\xfa\x71" "\x3d\xc7\x7e\x56\x3b\xbc\xf4\xba\x08\x15\x72\xd1\x47\xfc\x78\x11", 80); *(uint32_t*)0x20000588 = 0x447; *(uint8_t*)0x2000058c = 0; *(uint32_t*)0x20000590 = 0x101; *(uint64_t*)0x20000598 = 0x7f; *(uint64_t*)0x200005a0 = 0x7f; *(uint64_t*)0x20000678 = 0; syscall(SYS_tap_fds, 0x200005c0, 6); break; } } int main(void) { syscall(SYS_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0); loop(); return 0; }