// https://syzkaller.appspot.com/bug?id=4e122f38708160e5fe03d870d6af29b45493efab // 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 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 { int state; } event_t; static void event_init(event_t* ev) { ev->state = 0; } static void event_reset(event_t* ev) { ev->state = 0; } static void event_set(event_t* ev) { if (ev->state) exit(1); __atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE); syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG); } static void event_wait(event_t* ev) { while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE)) syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0); } static int event_isset(event_t* ev) { return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE); } static int event_timedwait(event_t* ev, uint64_t timeout) { uint64_t start = current_time_ms(); uint64_t now = start; for (;;) { uint64_t remain = timeout - (now - start); struct timespec ts; ts.tv_sec = remain / 1000; ts.tv_nsec = (remain % 1000) * 1000 * 1000; syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts); if (__atomic_load_n(&ev->state, __ATOMIC_RELAXED)) return 1; now = current_time_ms(); if (now - start > timeout) 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; 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, 45); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); if (!collide) { collide = 1; goto again; } } uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; void execute_call(int call) { intptr_t res; switch (call) { case 0: res = syscall(__NR_eventfd2, 0, 0); if (res != -1) r[0] = res; break; case 1: res = syscall(__NR_dup, r[0]); if (res != -1) r[1] = res; break; case 2: memcpy( (void*)0x20000700, "\x20\x00\x70\x70\x70\x30\x3a\xf5\x32\x6d\x65\x5f\x74\x79\x70\x65\x77" "\x6c\x61\x6e\x30\x47\x50\x39\xd6\x72\xce\x69\x2d\x2e\x12\x79\x70\x6f" "\x73\x69\x78\x5f\x61\x63\x6c\x5f\x61\x63\x63\x65\x73\x73\x25\x6d\x64" "\x35\x73\x35\x6d\x70\x72\x6f\x63\x65\x6d\x30\x2d\x7b\x2c\x76\x2a\x70" "\x70\x70\x31\x6e\x65\x74\x31\x2b\x40\x77\x6c\x61\x6e\x31\x65\x74\x68" "\x31\x00\x65\x14\x90\x8f\xf4\xd9\x9d\x1d\xd1\xf1\x3a\x33\x36\xab\x62" "\xd9\x3f\xb6\xf1\x99\x93\xdb\x0d\x95\xb2\x78\x97\x06\x88\xd4\x76\x09" "\x9b\xb0\xc4\x94\x60\x99\x2d\xe3\x55\x9b\x77\x31\x62\x78\xf1\x79\xb3" "\x46\x7f\x4a\x23\xc1\x9e\xb2\x79\x07\x2b\xa4\x08\x00\x3f\xa9\xf3\x9a" "\xab\x46\x99\xd2\x20\x85\xec\x0d\x1a\xd5\xc3\xa7\x30\x5d\xb8\xe9\x87" "\x94\x98\x0c\x3a\x4b\xf2\x6c\x23\x63\xcb\xf4\xe7\xec\x56\xca\x06\xd1" "\x21\x22\x59\xf1\xd5\xa1\x75\xed\xf0\xc9\x1d\x18\x7a\x6f\x24\x7f\xb0" "\x5a\x61\x5e\x64\x79\x67\x75\x01\xf6\x97\x52\x23\x4e\xd7\xdb\xdf\xef" "\x2b\x9a\x0f\x57\x79\x45\xf4\x5c\x34\x73\x64\x54\x5a\x7f\x19\x07\x41" "\x92\xa3\x62\x73\x47\x35\x9a\x21\x87\x5b\x88\x95\x2d\x6f\xeb\xf4\x09" "\xbc\x03\x51\x25\x92\xb2\xc6\x13\x10\x44\x23\xa5\x0e\x90\xf6\xad\x69" "\x36\x88\x73\x69\xb0\x3e\x71\xb1\x45\x89\xd6\xdc\x51\x33\x21\x24\x8c" "\x4b\x72\x82\xc5\xc2\x6c\x9c\xeb\x3b\x3f\x7e\x55\xda\xec\x61\x5f\xca" "\xf4\x20\x8d\x26\x53\xf5\x8d\x30\xf1\x56\x8f\x7b\x57\xf5\xf2\x50\x45" "\xc1\xdd\x4e\x8d\x1f\xd4\xdf\x16\xd4\x13\x99\x91\xfe\xeb\x01\xc2\x4c" "\xa3\x17\xb7\x74\x2a\xdd\xd8\xe0\x8d\xc4\xa6\x52\x84\xdd\x7c\x1b\x71" "\xfc\xc2\xd2\xed\x99\x5a\x00\xd2\xa6\x95\x1d\xe3\x00\xc8\xf0\x36\x89" "\x81\x5c\x60\x34\xc3\xf2\x5c\x4b\x75\xe7\x18\x53\x00\xb4\x10\xae\x36" "\xdf\x53\xea\x08\x70\x4f\x4e\x99\x1e\x2a\x13\x69\x32\xe3\x1d\x82\x86" "\x44\xfc\x6f\xf6\xb8\xc5\xf4\xe7\x33\x50\xff\x6f\xe2\x76\xeb\xd0\xc7" "\x72\xe1\xfd\x50\x33\x1a\x39\x96\xbb\x81\x08\x86\x3d\x17\x9d\xbb\x30" "\x1e\xb9\x3b\x74\xc3\xdb\x4e\x9e\xaf\xd1\xe3\x2e\x33\xe3\xc1\xc4\x10" "\x58\xe9\x9b\x98\x22\x4a\x65\x31\x66\xf3\xdd\x2d\xdc\x31\xf1\xd5\x57" "\x4d\x1d\x8a\xcb\x47\x9d\xe3\x06\x2b\x85\x62\xe5\xcf\x47\xef\xf3\xc9" "\xf4\xe9\xfa\x9a\x28\x00\x25\x17\x2a\xc9\x38\xb2\x01\xf4\x41\x12\x56" "\x08\x9f\x72\xe0\x68\x66\x4b\xba\xc1\x25\x18\xc3\x0a\x19\xc9\x21\xbd" "\xd3\x79\x1e\x98\x61\xdf\x74\x90\xb2\x9b\xa7\x33\x68\x7f\x32\x1f\x5d" "\xb3\x64\xe2\x7e\x55\x1a\x14\xac\x80\x79\xe4\x2e\x9e\x14\x91\x9c\x20" "\xb1\x47\xe0\xc5\xf1\x50\x41\x79\x29\x1b\x19\xe1\xef\xe9\x28\x62\x12" "\x5b\x2b\x09\x7c\xe9\x46\x44\x3e\x21\xe7\x82\xbb\x24\xde\xfe\x01\x9d" "\x7f\x55\x19\x67\x46\x7d\x14\xb4\xde\x12\x40\xc4\x34\xe4\x82\xb6\xeb" "\xb5\x29\xed\x10\x5a\x69\x0a\x94\xb6\x36\x05\xae\x93\x81\x3c\xf8\x33" "\x3b\x2e\xec\xcd\xcc\x68\xa9\x26\x4f\xd7\x63\x26\xb8\x42\x3d\xf7\x2a" "\x71\xbd\x24\x53\xb9\x42\xae\xb7\xc1\xdc\x53\x65\xb5\x80\x82\x2e\x11" "\xd0\xf3\x87\xe0\xa1\x3c\x1d\xae\x95\xe5\x48\x9f\xa4\x7c\x47\x3f\x42" "\xfc\x17\x75\x6b\x89\xa0\xa2\xe1\xc3\xe7\x41\x99\xdc\x03\x5a\x39\xb5" "\x81\xf0\xf0\xb7\x2e\x06\x5f\xe4\x0a\xde\xcd\x54\xcb\xe5\xc0\xa7\x44" "\x58\x34\x9b\x0b\x87\xa0\x40\x7a\x89\xe0\x4d\x59\xbb\x5f\x8f\x0b\x1c" "\x21\x47\xd8\x4a\xde\x0b\xca\xec\xcb\x69\x7c\x69\x92\xc0\x12\x31\xfb" "\x35\x1c\xac\x21\x83\xa7\xb0\x75\x8c\x48\xb9\x66\x46\xae\x38\xb3\x9a" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\xe0" "\x1b\x4e\x05\xda\x65\xf3\x0f\xf4\x0c\x4d\xb0\x4c\xec\x86\x2a\x54\xb4" "\xce\x27\x0e\x70\xd9\x37\x5b\x73\xb6\x93\x0a\x9d\x32\xa1\xef\x7c\x46" "\x77\x52\x80\x21\x26\xbd\x90\xed\x92\x22\x63\xda\x4c\x48\x19\xa5\xd5" "\x47\x14\xe1\xe8\x75\xd5\x8b\xb0\x04\xbf\x1f\x27\x1d\xc9\x23\xb7\x4a" "\x39\xb2\xde\x17\x0b\xf2\xd6\x8d\x30\x70\xcc\x11\x98\xf1\x44\x20\x81" "\x2d\x38\xea\x05\xa3\x28\xc8\x0c\xd0\x27\x3a\x1f\x60\x15\xfb\x9a\x27" "\x9d\x85\x52\xb7\x88\x60\x67\xdc\x19\x70\x97\xb7\x5b\x83\x00\x71\x1b" "\x40\x5e\x20\xf9\x1d\x73\x85\x08\x9d\x71\x30\x65\x5d\x31\x41\xf1\xa4" "\xc2\x7e\xd3\x63\x47\x6c\xa7\xbc\x65\x16\x85\x3d\x42\x58\xb1\x3f\x5d" "\x4c\xf6\xc8\x48\xfc\xa7\x3e\xfa\x4c\x29\xaa\xfd\xfe\xfe\x3e\x85\x78" "\x57\x02\x7f\xbc\x26\x54\x53\xec\x57\x82\xc3\x1c\xd6\x3c\xd5\xe1\x94" "\xc5\x1a\x09\xe1\x10\x17\xe8\x69\x3e\x04\xe2\x26\x7e\xe2\x52\x27\x71" "\xb2\xa1\x2e\xb8\xac\xa2\x5e\x02\x0c\x4a\x57\x8e\x8b\x44\x44\xbd\xa4" "\xba\x96\xfa\x02\x30\xf5\xa7\x92\xca\x05", 1013); syscall(__NR_write, r[1], 0x20000700, 0xe4); break; case 3: memcpy((void*)0x20000000, "./file1\000", 8); memcpy((void*)0x20000040, "9p\000", 3); memcpy((void*)0x20000140, "trans=fd,", 9); memcpy((void*)0x20000149, "rfdno", 5); *(uint8_t*)0x2000014e = 0x3d; sprintf((char*)0x2000014f, "0x%016llx", (long long)r[1]); *(uint8_t*)0x20000161 = 0x2c; memcpy((void*)0x20000162, "wfdno", 5); *(uint8_t*)0x20000167 = 0x3d; sprintf((char*)0x20000168, "0x%016llx", (long long)r[1]); *(uint8_t*)0x2000017a = 0x2c; memcpy((void*)0x2000017b, "aname", 5); *(uint8_t*)0x20000180 = 0x3d; memcpy((void*)0x20000181, "vmnet0self", 10); *(uint8_t*)0x2000018b = 0x2c; memcpy((void*)0x2000018c, "loose", 5); *(uint8_t*)0x20000191 = 0x2c; memcpy((void*)0x20000192, "fowner<", 7); sprintf((char*)0x20000199, "%020llu", (long long)0); *(uint8_t*)0x200001ad = 0x2c; memcpy((void*)0x200001ae, "permit_directio", 15); *(uint8_t*)0x200001bd = 0x2c; memcpy((void*)0x200001be, "fsname", 6); *(uint8_t*)0x200001c4 = 0x3d; memcpy((void*)0x200001c5, "(.\\nodev", 8); *(uint8_t*)0x200001cd = 0x2c; memcpy((void*)0x200001ce, "uid<", 4); sprintf((char*)0x200001d2, "%020llu", (long long)0); *(uint8_t*)0x200001e6 = 0x2c; *(uint8_t*)0x200001e7 = 0; syscall(__NR_mount, 0, 0x20000000, 0x20000040, 1, 0x20000140); break; case 4: memcpy((void*)0x200000c0, "./file1\000", 8); syscall(__NR_open, 0x200000c0, 0x220141042, 0); break; } } int main(void) { syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0); loop(); return 0; }