// https://syzkaller.appspot.com/bug?id=1a237d589845a77a695b488e4f81821420d22bcc // autogenerated by syzkaller (http://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include __attribute__((noreturn)) static void doexit(int status) { volatile unsigned i; syscall(__NR_exit_group, status); for (i = 0;; i++) { } } #include #include #include #include #include const int kFailStatus = 67; const int kRetryStatus = 69; static void exitf(const char* msg, ...) { int e = errno; va_list args; va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); fprintf(stderr, " (errno %d)\n", e); doexit(kRetryStatus); } #define BITMASK_LEN(type, bf_len) (type)((1ull << (bf_len)) - 1) #define BITMASK_LEN_OFF(type, bf_off, bf_len) \ (type)(BITMASK_LEN(type, (bf_len)) << (bf_off)) #define STORE_BY_BITMASK(type, addr, val, bf_off, bf_len) \ if ((bf_off) == 0 && (bf_len) == 0) { \ *(type*)(addr) = (type)(val); \ } else { \ type new_val = *(type*)(addr); \ new_val &= ~BITMASK_LEN_OFF(type, (bf_off), (bf_len)); \ new_val |= ((type)(val)&BITMASK_LEN(type, (bf_len))) << (bf_off); \ *(type*)(addr) = new_val; \ } static bool write_file(const char* file, const char* what, ...) { char buf[1024]; va_list args; va_start(args, what); vsnprintf(buf, sizeof(buf), what, args); va_end(args); buf[sizeof(buf) - 1] = 0; int len = strlen(buf); int fd = open(file, O_WRONLY | O_CLOEXEC); if (fd == -1) return false; if (write(fd, buf, len) != len) { int err = errno; close(fd); errno = err; return false; } close(fd); return true; } static int inject_fault(int nth) { int fd; char buf[16]; fd = open("/proc/thread-self/fail-nth", O_RDWR); if (fd == -1) exitf("failed to open /proc/thread-self/fail-nth"); sprintf(buf, "%d", nth + 1); if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) exitf("failed to write /proc/thread-self/fail-nth"); return fd; } static void execute_one(); extern unsigned long long procid; void loop() { while (1) { execute_one(); } } 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 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); struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 20 * 1000 * 1000; syscall(SYS_futex, &th->running, FUTEX_WAIT, 1, &ts); if (__atomic_load_n(&running, __ATOMIC_RELAXED)) usleep((call == num_calls - 1) ? 10000 : 1000); break; } } } } unsigned long long procid; void execute_call(int call) { switch (call) { case 0: *(uint32_t*)0x20c86f88 = 2; *(uint32_t*)0x20c86f8c = 0x70; *(uint8_t*)0x20c86f90 = 0xf4; *(uint8_t*)0x20c86f91 = 0; *(uint8_t*)0x20c86f92 = 0; *(uint8_t*)0x20c86f93 = 0; *(uint32_t*)0x20c86f94 = 0; *(uint64_t*)0x20c86f98 = 0; *(uint64_t*)0x20c86fa0 = 0; *(uint64_t*)0x20c86fa8 = 0; STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 0, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 1, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 2, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 3, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 4, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, -1, 5, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 6, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 7, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 8, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 9, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 10, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 11, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 12, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 13, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 14, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 15, 2); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 17, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 18, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 19, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 20, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 21, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 22, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 23, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 24, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 25, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 26, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 27, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 28, 1); STORE_BY_BITMASK(uint64_t, 0x20c86fb0, 0, 29, 35); *(uint32_t*)0x20c86fb8 = 0; *(uint32_t*)0x20c86fbc = 0; *(uint64_t*)0x20c86fc0 = 0x20000000; *(uint64_t*)0x20c86fc8 = 0; *(uint64_t*)0x20c86fd0 = 0; *(uint64_t*)0x20c86fd8 = 0; *(uint32_t*)0x20c86fe0 = 0; *(uint32_t*)0x20c86fe4 = 0; *(uint64_t*)0x20c86fe8 = 0; *(uint32_t*)0x20c86ff0 = 0; *(uint16_t*)0x20c86ff4 = 0; *(uint16_t*)0x20c86ff6 = 0; syscall(__NR_perf_event_open, 0x20c86f88, 0, 0, -1, 0); break; case 1: memcpy((void*)0x200000c0, "big_key", 8); *(uint8_t*)0x20000100 = 0x73; *(uint8_t*)0x20000101 = 0x79; *(uint8_t*)0x20000102 = 0x7a; *(uint8_t*)0x20000103 = 0; *(uint8_t*)0x20000104 = 0; memcpy( (void*)0x20000140, "\xf2\xb7\xbd\x3f\x0f\x47\x43\xf0\xe9\xa9\x49\x24\x8a\xba\x0c\x66\xa6" "\x6d\x8b\x0d\x84\x0a\x29\x80\x0b\x73\x1f\x49\x50\xf3\xa0\xf7\xc4\x38" "\x25\x00\x3d\x0e\x82\xee\x05\x2a\x46\x47\xaf\xdc\xc5\xf8\xd5\x6f\x67" "\x56\x02\x8c\x6b\x3d\xc5\xd7\x05\x49\x67\xab\x9a\x9a\x68\x20\xac\x54" "\xc7\xe3\x5d\x53\x94\x51\xd7\xc2\xd0\x73\x0f\x64\x92\xae\xa8\x4c\x94" "\x49\x96\x11\x74\x63\xf0\x7d\xed\x57\xbe\x2c\x70\xcd\xff\x19\x7f\xc3" "\x6c\x38\x14\x07\x4c\xb2\x10\xaf\xde\x00\xcf\xd3\x9b\xfc\x00\x28\xdc" "\x50\x13\xc3\x59\x19\xee\xf4\x59\x05\xa0\xfa\xf3\x2a\xb1\x47\x57\x8a" "\x96\x6a\xe9\x5a\x5f\x4a\x21\x48\x75\x2a\xfe\x93\x3e\xf9\x44\xae\xd8" "\xfe\xfb\x90\xb8\xe6\x9d\xe3\x3e\xe4\xd9\x8c\x3a\xb3\x33\x7f\x1a\x83" "\x53\x48\x32\xbf\xe0\x07\x0a\xa5\x4b\xe3\x7c\xc2\xe3\xbc\x1f\x36\x3d" "\x6f\x3f\x33\x07\xbb\xa7\xd6\xb0\xe0\xef\x13\xe4\xa4\x34\xa2\x9f\x9f" "\x55\x89\xa5\x2f\xf5\x50\x13\xf0\x8d\xa9\xd0\xce\x4d\xfa\x9b\xf1\xf9" "\x71\x83\x12\x87\x3c\x0f\xda\x7b\x6a\x90\xde\x03\x22\xe9\x4a\xa0\x63" "\x10\x0e\xc1\x3b\x51\xd9\x36\xce\x72\xb9\x3f\x12\x30\x9d\x1d\x73\x88" "\x27\x93\x1a\x13\x78\x80\x47\x0d\xbf\x85\xee\x86\xc5\x9c\xbe\xf9\x3a" "\x88\xc2\x23\xd7\xa3\x22\x0a\x8d\xe2\xea\x60\x3d\xc1\xeb\xed\x20\x7d" "\x3f\xa8\xf4\x30\x11\xf9\xac\x62\x34\x83\x1b\x68\x82\xf6\x71\xb9\x6a" "\x07\x52\x26\x47\xea\x82\x33\xc3\xe2\xc3\x43\x47\x52\x1f\x9c\xd6\x06" "\x52\xe7\x34\xcf\xfc\x40\x0d\x63\x5e\x78\x5e\x61\x63\xd7\x55\x6c\x49" "\x83\xba\xbd\x48\x64\x64\x83\x2e\xee\xd3\xa0\x41\x86\x04\x3c\xa2\x5e" "\x77\x86\x37\x14\x41\x66\x08\x8d\x04\xca\xc4\x50\x1f\x10\xaf\xf1\x1a" "\xe2\x9d\xaf\xc3\xfb\xf1\xbd\x4f\xe7\xfe\x82\xe8\xfd\x1f\xc4\x4e\xbb" "\x88\x91\x95\x3e\x26\x22\xb3\xe2\x42\x69\x50\x00\x0c\xbe\x0d\x34\x4e" "\xa3\x35\xb3\x84\x4f\x64\x04\x6d\x94\x79\x86\x30\xe5\x82\x63\x4e\xc9" "\x37\x99\x94\xd2\x87\x9a\xd6\x32\x8c\x69\x41\x0b\xb6\x3d\xb9\x05\x83" "\x48\x99\x34\x9f\xe0\x4a\x2f\x93\x3b\xee\x83\x5c\x5e\x24\xb9\xa6\x2a" "\xca\x48\xb9\x9a\x72\x3d\x94\x74\x3d\x9b\x0a\xc1\x37\xbf\x8d\xdc\x68" "\x28\x61\xb7\x02\xc2\xbf\x74\xa7\xad\xe8\x14\x65\x85\x80\x2c\x8a\x17" "\xf0\xb1\xc3\x3f\xfd\x2a\xfb\xad\x06\x7a\x6a\xa7\xb5\xd9\x21\x2c\x61" "\xe9\x47\x83\xf7\x37\x67\x54\x8c\xd9\x01\xe9\x86\x54\x73\xbd\x55\xf8" "\xeb\x71\x22\x49\x75\x5f\x9a\xd8\x3f\x6d\xa5\x5c\x7b\x8a\x02\xc2\x9d" "\x1a\x3f\x73\xbd\xc0\xbc\xd6\x4a\x25\x68\xf3\x29\x7e\xce\xfe\x9f\x85" "\xe3\x7a\xc2\x2b\x57\xf5\xc8\xb0\x76\x68\xe3\xe7\x59\x6f\x58\x88\x1e" "\xf5\x7e\xb2\x1d\xd3\x09\x7a\x68\xc7\x4f\xa5\xe2\x2b\x34\x24\x19\xa4" "\x27\x41\x1a\x68\xa0\x75\x56\x96\x40\xe5\xde\x4d\x54\x1b\x94\x94\x7c" "\x90\xc6\xab\xa6\xf2\xad\x88\x0d\xe9\xfa\x3a\x47\xae\x12\x11\xc1\xac" "\x87\xf8\x91\xaa\x34\x8b\xb6\xfc\x2d\xfb\x8e\xfd\x75\x1f\x4e\xbd\x73" "\x08\xe7\xc8\xf5\x0a\xaa\xcd\x83\x47\xbd\x6d\xea\x3f\xff\xac\x30\x8c" "\x80\x5f\xa2\xde\xa6\xd2\xbc\x4e\x4b\x63\x16\xa5\xc7\xef\x1c\x60\xc8" "\x9f\x7a\xf8\x83\xf8\x5e\xc9\x96\x1c\x3d\xc6\x1a\x7a\x7c\x93\xd7\xb2" "\xba\xb4\x86\xeb\x91\xb3\x0b\xa4\x31\xa5\xe9\x05\x78\xef\x51\xc0\x52" "\x35\x58\x49\x12\xa0\xb0\x1d\xcb\x8f\x3b\x17\x5f\xad\x72\xe8\x13\xc0" "\x18\xbe\xa2\xbf\x3a\x6d\x30\xbf\x25\x85\xf2\x95\x57\xa2\xa9\xe8\x3c" "\xb2\x49\xaa\x2c\x2c\xc1\x53\xb3\xa0\xf1\x97\xed\x63\x81\x10\xe4\x71" "\xb4\xd4\xef\xa7\x18\x89\x64\xae\xe0\x85\x95\xed\xfb\xfd\x0b\xe1\x0c" "\x69\xf3\xed", 785); write_file("/sys/kernel/debug/failslab/ignore-gfp-wait", "N"); write_file("/sys/kernel/debug/fail_futex/ignore-private", "N"); inject_fault(8); syscall(__NR_add_key, 0x200000c0, 0x20000100, 0x20000140, 0x311, 0xfffffffc); break; } } void execute_one() { execute(2); } 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; }