// https://syzkaller.appspot.com/bug?id=ae8f5829dcc7cff6145c012b746bafa494b144ee // autogenerated by syzkaller (http://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include static void test(); void loop() { while (1) { test(); } } struct thread_t { int created, running, call; pthread_t th; }; static struct thread_t threads[16]; static void execute_call(int call); static int running; static int collide; static void* thr(void* arg) { struct thread_t* th = (struct thread_t*)arg; for (;;) { while (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) syscall(SYS_futex, &th->running, FUTEX_WAIT, 0, 0); execute_call(th->call); __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); __atomic_store_n(&th->running, 0, __ATOMIC_RELEASE); syscall(SYS_futex, &th->running, FUTEX_WAKE); } return 0; } static void execute(int num_calls) { int call, thread; running = 0; for (call = 0; call < num_calls; call++) { for (thread = 0; thread < sizeof(threads) / sizeof(threads[0]); thread++) { struct thread_t* th = &threads[thread]; if (!th->created) { th->created = 1; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 128 << 10); pthread_create(&th->th, &attr, thr, th); } if (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) { th->call = call; __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); __atomic_store_n(&th->running, 1, __ATOMIC_RELEASE); syscall(SYS_futex, &th->running, FUTEX_WAKE); if (collide && call % 2) break; struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 20 * 1000 * 1000; syscall(SYS_futex, &th->running, FUTEX_WAIT, 1, &ts); if (running) usleep((call == num_calls - 1) ? 10000 : 1000); break; } } } } uint64_t r[2] = {0xffffffffffffffff, 0xffffffff}; uint64_t procid; void execute_call(int call) { long res; switch (call) { case 0: memcpy((void*)0x20000180, "/dev/infiniband/rdma_cm", 24); res = syscall(__NR_openat, 0xffffffffffffff9c, 0x20000180, 2, 0); if (res != -1) r[0] = res; break; case 1: *(uint32_t*)0x200000c0 = 0; *(uint16_t*)0x200000c4 = 0x18; *(uint16_t*)0x200000c6 = 0xfa00; *(uint64_t*)0x200000c8 = 3; *(uint64_t*)0x200000d0 = 0x20000080; *(uint16_t*)0x200000d8 = 2; *(uint8_t*)0x200000da = 0; *(uint8_t*)0x200000db = 0; *(uint8_t*)0x200000dc = 0; *(uint8_t*)0x200000dd = 0; *(uint8_t*)0x200000de = 0; *(uint8_t*)0x200000df = 0; res = syscall(__NR_write, r[0], 0x200000c0, 0x20); if (res != -1) r[1] = *(uint32_t*)0x20000080; break; case 2: *(uint32_t*)0x200001c0 = 6; *(uint16_t*)0x200001c4 = 0x118; *(uint16_t*)0x200001c6 = 0xfa00; *(uint32_t*)0x200001c8 = 0xfffffffc; *(uint32_t*)0x200001cc = 0x1000; memcpy((void*)0x200001d0, "\xdf\x6e\xf6\xac\xa9\x7d\x15\xb2\x9b\x79\x36\xf9\x49\x20\xf4\xa6" "\x86\xc5\xf9\xa9\x58\xbe\xfe\xd4\x22\x2d\xd0\xa3\xd3\xff\x43\xef" "\x67\x29\xf4\x43\x76\xa7\xd1\x46\x80\x94\xfd\xdf\x19\x51\x0b\x6f" "\x08\x60\xb6\x39\x9a\xc3\xb7\x8f\x2c\xcd\xcf\xe9\x7a\x2c\xcb\x7a" "\xf6\x34\xe6\x64\x3d\x0a\xad\x7f\xde\x2d\x97\x9f\x9f\x5b\x84\x50" "\xa8\x99\xa8\x34\xc8\xfa\x84\xb2\x6c\xb2\x32\x1f\xbf\x6f\x2d\x33" "\xdf\xa1\xde\x37\x7f\x22\xcb\xa2\xd9\xc4\x41\x57\xaa\xdf\x41\xb6" "\x38\xae\xdd\xa7\x49\x0b\x12\x7f\x37\x14\xd7\x33\x3b\x53\xba\x0b" "\x7e\x77\x45\xfa\x18\x3e\xa3\x2f\xbd\x7a\xd5\x89\xd6\xb9\xcb\x77" "\x36\x72\x68\x1d\xe7\xf7\xa8\xe3\xac\xc2\x80\xb6\x06\x0c\xc5\xe6" "\x19\xc1\x77\x7f\xed\xf1\x76\x00\x94\x55\x68\xb9\xdf\xe7\x0c\xb8" "\x61\x9f\xc1\xeb\x1e\xf9\x0b\x7d\x52\x5b\x88\x19\xe7\x01\x44\x99" "\x73\xd8\xcf\xea\x6d\xf4\xf7\x81\x7c\xa8\xbd\xe9\x5f\x4a\xfb\x24" "\x7a\xd2\x75\x95\x61\xad\xe2\xcf\x27\xe4\x2a\x50\x78\x78\x0c\x31" "\x20\x2e\xb6\x30\x82\x08\x85\x15\x3d\x14\xb4\x1c\x10\xce\x81\x29" "\xdf\x9c\xcd\x84\xa1\x2c\x94\x92\x5b\xb0\x65\xfe\xa2\xee\x22\x53", 256); *(uint8_t*)0x200002d0 = 0xe; *(uint8_t*)0x200002d1 = -1; *(uint8_t*)0x200002d2 = 9; *(uint8_t*)0x200002d3 = 6; *(uint8_t*)0x200002d4 = 0; *(uint8_t*)0x200002d5 = 2; *(uint8_t*)0x200002d6 = 1; *(uint8_t*)0x200002d7 = 1; *(uint32_t*)0x200002d8 = r[1]; *(uint32_t*)0x200002dc = 0; syscall(__NR_write, r[0], 0x200001c0, 0x120); break; case 3: syscall(__NR_close, r[0]); break; } } void test() { execute(4); collide = 1; execute(4); } int main() { syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0); for (procid = 0; procid < 8; procid++) { if (fork() == 0) { for (;;) { loop(); } } } sleep(1000000); return 0; }