// https://syzkaller.appspot.com/bug?id=0881c535c265ca965edc49c0ac3d0a9850d26eb1 // 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 __attribute__((noreturn)) static void doexit(int status) { volatile unsigned i; syscall(__NR_exit_group, status); for (i = 0;; i++) { } } #include #include const int kFailStatus = 67; const int kRetryStatus = 69; static void fail(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((e == ENOMEM || e == EAGAIN) ? kRetryStatus : kFailStatus); } #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; \ } struct csum_inet { uint32_t acc; }; static void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } static void csum_inet_update(struct csum_inet* csum, const uint8_t* data, size_t length) { if (length == 0) return; size_t i; for (i = 0; i < length - 1; i += 2) csum->acc += *(uint16_t*)&data[i]; if (length & 1) csum->acc += (uint16_t)data[length - 1]; while (csum->acc > 0xffff) csum->acc = (csum->acc & 0xffff) + (csum->acc >> 16); } static uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } static uint64_t current_time_ms() { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts)) fail("clock_gettime failed"); return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; } static void test(); void loop() { int iter; for (iter = 0;; iter++) { int pid = fork(); if (pid < 0) fail("loop fork failed"); if (pid == 0) { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setpgrp(); test(); doexit(0); } int status = 0; uint64_t start = current_time_ms(); for (;;) { int res = waitpid(-1, &status, __WALL | WNOHANG); if (res == pid) break; usleep(1000); if (current_time_ms() - start > 5 * 1000) { kill(-pid, SIGKILL); kill(pid, SIGKILL); while (waitpid(-1, &status, __WALL) != pid) { } break; } } } } 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; } } } } long r[3]; void execute_call(int call) { switch (call) { case 0: syscall(__NR_mmap, 0x20000000, 0xfff000, 3, 0x32, -1, 0); break; case 1: r[0] = syscall(__NR_socket, 0xa, 6, 0); break; case 2: *(uint16_t*)0x20000000 = 0xa; *(uint16_t*)0x20000002 = htobe16(0x4e20); *(uint32_t*)0x20000004 = 0; *(uint8_t*)0x20000008 = 0; *(uint8_t*)0x20000009 = 0; *(uint8_t*)0x2000000a = 0; *(uint8_t*)0x2000000b = 0; *(uint8_t*)0x2000000c = 0; *(uint8_t*)0x2000000d = 0; *(uint8_t*)0x2000000e = 0; *(uint8_t*)0x2000000f = 0; *(uint8_t*)0x20000010 = 0; *(uint8_t*)0x20000011 = 0; *(uint8_t*)0x20000012 = 0; *(uint8_t*)0x20000013 = 0; *(uint8_t*)0x20000014 = 0; *(uint8_t*)0x20000015 = 0; *(uint8_t*)0x20000016 = 0; *(uint8_t*)0x20000017 = 0; *(uint32_t*)0x20000018 = 0; syscall(__NR_bind, r[0], 0x20000000, 0x1c); break; case 3: r[1] = syscall(__NR_socket, 2, 6, 0); break; case 4: syscall(__NR_listen, r[0], 6); break; case 5: memcpy((void*)0x201c9fff, "\x03", 1); syscall(__NR_setsockopt, r[1], 0x10d, 0xd, 0x201c9fff, 1); break; case 6: *(uint16_t*)0x20e5c000 = 2; *(uint16_t*)0x20e5c002 = htobe16(0x4e20); *(uint32_t*)0x20e5c004 = htobe32(0x7f000001); *(uint8_t*)0x20e5c008 = 0; *(uint8_t*)0x20e5c009 = 0; *(uint8_t*)0x20e5c00a = 0; *(uint8_t*)0x20e5c00b = 0; *(uint8_t*)0x20e5c00c = 0; *(uint8_t*)0x20e5c00d = 0; *(uint8_t*)0x20e5c00e = 0; *(uint8_t*)0x20e5c00f = 0; syscall(__NR_connect, r[1], 0x20e5c000, 0x10); break; case 7: *(uint32_t*)0x2033f000 = 0xc; r[2] = syscall(__NR_accept, r[0], 0x204c9000, 0x2033f000); break; case 8: *(uint64_t*)0x206c8000 = 0; *(uint32_t*)0x206c8008 = 0; *(uint64_t*)0x206c8010 = 0x206b3ff0; *(uint64_t*)0x206c8018 = 1; *(uint64_t*)0x206c8020 = 0; *(uint64_t*)0x206c8028 = 0; *(uint32_t*)0x206c8030 = 0; *(uint64_t*)0x206b3ff0 = 0x20167000; *(uint64_t*)0x206b3ff8 = 0x68; *(uint8_t*)0x20167000 = 2; *(uint8_t*)0x20167001 = 0xc; *(uint8_t*)0x20167002 = 0x86; *(uint8_t*)0x20167003 = 8; *(uint16_t*)0x20167004 = 0xd; *(uint16_t*)0x20167006 = 0; *(uint32_t*)0x20167008 = 0x70bd2b; *(uint32_t*)0x2016700c = 0x25dfdbfd; *(uint16_t*)0x20167010 = 2; *(uint16_t*)0x20167012 = 0x13; *(uint8_t*)0x20167014 = 4; *(uint8_t*)0x20167015 = 0; *(uint16_t*)0x20167016 = 0; *(uint32_t*)0x20167018 = 0x70bd27; *(uint32_t*)0x2016701c = 0x3500; *(uint16_t*)0x20167020 = 1; *(uint16_t*)0x20167022 = 0x14; *(uint8_t*)0x20167024 = 1; *(uint8_t*)0x20167025 = 0; *(uint8_t*)0x20167026 = 0; *(uint8_t*)0x20167027 = 0; *(uint16_t*)0x20167028 = 8; *(uint16_t*)0x2016702a = 0x12; *(uint16_t*)0x2016702c = 3; *(uint8_t*)0x2016702e = 2; *(uint8_t*)0x2016702f = 0; *(uint32_t*)0x20167030 = 0x6e6bb4; *(uint32_t*)0x20167034 = 0x7dd7; *(uint16_t*)0x20167038 = 6; *(uint16_t*)0x2016703a = 0xff; *(uint8_t*)0x2016703c = 0xcc; *(uint8_t*)0x2016703d = 2; *(uint16_t*)0x2016703e = 0; *(uint32_t*)0x20167040 = 0xffff; *(uint32_t*)0x20167044 = 0; *(uint8_t*)0x20167048 = 0xac; *(uint8_t*)0x20167049 = 0x14; *(uint8_t*)0x2016704a = 0; *(uint8_t*)0x2016704b = 0x16; *(uint8_t*)0x20167058 = 0; *(uint8_t*)0x20167059 = 0; *(uint8_t*)0x2016705a = 0; *(uint8_t*)0x2016705b = 0; *(uint8_t*)0x2016705c = 0; *(uint8_t*)0x2016705d = 0; *(uint8_t*)0x2016705e = 0; *(uint8_t*)0x2016705f = 0; *(uint8_t*)0x20167060 = 0; *(uint8_t*)0x20167061 = 0; *(uint8_t*)0x20167062 = -1; *(uint8_t*)0x20167063 = -1; *(uint32_t*)0x20167064 = htobe32(0xe0000001); syscall(__NR_sendmsg, r[2], 0x206c8000, 0x80); break; case 9: memcpy((void*)0x206c2f47, "\x1a\x36\xe3\xa1\x3a\xb3\xf4\xaf\x2b\xb7\xfb\x0b\x3f\xd2\xad\xe8" "\xf0\x54\xb7\xef\xee\x2a\xb3\xa1\x23\xa3\x79\x60\x3e\x0f\xe6\xa1" "\x10\xe0\x8e\x6d\xd6\x9a\x75\x5c\x96\x95\x62\x61\x69\xa8\x1f\xe3" "\x4f\xd8\x0f\xc9\xc3\x70\x79\xd4\x5e\x7b\xf3\x44\xf1\xb3\xbd\x93" "\xb1\xb2\x5b\xe9\xb0\x67\xb1\xf4\xe2\x16\xdf\x61\x49\x44\xa0\xc7" "\x01\x0b\x7e\x0a\x60\xac\xb9\xf5\xf2\xe7\xda\x57\xb7\x72\x4b\x5f" "\x07\x56\x76\x53\xeb\x52\xcf\xf6\x0d\x05\xd2\x32\x33\xd2\x64\x8f" "\xe2\x88\xa4\x3a\xe6\x3b\xf7\x88\x31\x69\x01\x42\x3e\x08\x88\xa3" "\x92\xe5\xff\x4b\x46\x37\x43\xc5\x6a\x32\x96\x50\x14\xa4\x76\xcc" "\xbe\xbb\x81\xa3\xdd\x34\xa0\x8b\x1d\xf2\x6d\xfb\x00\xe0\xc8\xde" "\x4e\xcd\xad\xe1\x1e\x76\x11\xb9\xca\x10\x32\xc6\xe6\xee\x2e\x87" "\x19\x47\x7d\xbd\xe8\xe7\x52\x52\x05", 185); *(uint16_t*)0x20c69ff0 = 4; *(uint16_t*)0x20c69ff2 = htobe16(1); *(uint32_t*)0x20c69ff4 = htobe32(9); memcpy((void*)0x20c69ff8, "\x95\xa7\x0b\x27\x86\x63", 6); *(uint8_t*)0x20c69ffe = -1; *(uint8_t*)0x20c69fff = 0; syscall(__NR_sendto, r[2], 0x206c2f47, 0xb9, 0x20000000, 0x20c69ff0, 0x10); break; case 10: *(uint64_t*)0x20ddd000 = 0x204d2000; *(uint64_t*)0x20ddd008 = 0; *(uint64_t*)0x20ddd010 = 0x20b33fc5; *(uint64_t*)0x20ddd018 = 0; *(uint64_t*)0x20ddd020 = 0x20b75ff0; *(uint64_t*)0x20ddd028 = 0; *(uint64_t*)0x20ddd030 = 0x20f99000; *(uint64_t*)0x20ddd038 = 0x18; memcpy((void*)0x20f99000, "\x29\x8c\xb1\xbe\x4d\xa2\xea\xa6\xdf\xa1\xab\x98" "\x5d\xb8\xc1\x54\x45\x2d\x57\x9e\xe4\xcb\xe4" "\xf8", 24); syscall(__NR_writev, r[1], 0x20ddd000, 4); break; case 11: *(uint8_t*)0x20c12000 = 1; *(uint8_t*)0x20c12001 = 0x80; *(uint8_t*)0x20c12002 = 0xc2; *(uint8_t*)0x20c12003 = 0; *(uint8_t*)0x20c12004 = 0; *(uint8_t*)0x20c12005 = 0; *(uint8_t*)0x20c12006 = 0xaa; *(uint8_t*)0x20c12007 = 0xaa; *(uint8_t*)0x20c12008 = 0xaa; *(uint8_t*)0x20c12009 = 0xaa; *(uint8_t*)0x20c1200a = 0; *(uint8_t*)0x20c1200b = 0xaa; *(uint16_t*)0x20c1200c = htobe16(0x800); STORE_BY_BITMASK(uint8_t, 0x20c1200e, 5, 0, 4); STORE_BY_BITMASK(uint8_t, 0x20c1200e, 4, 4, 4); STORE_BY_BITMASK(uint8_t, 0x20c1200f, 0, 0, 2); STORE_BY_BITMASK(uint8_t, 0x20c1200f, 0, 2, 6); *(uint16_t*)0x20c12010 = htobe16(0x70); *(uint16_t*)0x20c12012 = 0; *(uint16_t*)0x20c12014 = htobe16(0); *(uint8_t*)0x20c12016 = 0; *(uint8_t*)0x20c12017 = 1; *(uint16_t*)0x20c12018 = 0; *(uint32_t*)0x20c1201a = htobe32(0xfffffe01); *(uint8_t*)0x20c1201e = 0xac; *(uint8_t*)0x20c1201f = 0x14; *(uint8_t*)0x20c12020 = 0; *(uint8_t*)0x20c12021 = 0xa; *(uint8_t*)0x20c12022 = 0xb; *(uint8_t*)0x20c12023 = 0; *(uint16_t*)0x20c12024 = 0; *(uint8_t*)0x20c12026 = 0; *(uint8_t*)0x20c12027 = 0; *(uint16_t*)0x20c12028 = 0; STORE_BY_BITMASK(uint8_t, 0x20c1202a, 0x15, 0, 4); STORE_BY_BITMASK(uint8_t, 0x20c1202a, 4, 4, 4); STORE_BY_BITMASK(uint8_t, 0x20c1202b, 0, 0, 2); STORE_BY_BITMASK(uint8_t, 0x20c1202b, 0, 2, 6); *(uint16_t*)0x20c1202c = htobe16(0); *(uint16_t*)0x20c1202e = 0; *(uint16_t*)0x20c12030 = htobe16(0); *(uint8_t*)0x20c12032 = 0; *(uint8_t*)0x20c12033 = 4; *(uint16_t*)0x20c12034 = htobe16(0); *(uint32_t*)0x20c12036 = htobe32(0x7f000001); *(uint32_t*)0x20c1203a = htobe32(0xe0000002); *(uint8_t*)0x20c1203e = 0x44; *(uint8_t*)0x20c1203f = 0x24; *(uint8_t*)0x20c12040 = 0; STORE_BY_BITMASK(uint8_t, 0x20c12041, 0, 0, 4); STORE_BY_BITMASK(uint8_t, 0x20c12041, 0, 4, 4); *(uint32_t*)0x20c12042 = htobe32(0); *(uint8_t*)0x20c12046 = 0xac; *(uint8_t*)0x20c12047 = 0x14; *(uint8_t*)0x20c12048 = 0; *(uint8_t*)0x20c12049 = 0; *(uint32_t*)0x20c1204a = htobe32(0); *(uint32_t*)0x20c1204e = htobe32(0); *(uint32_t*)0x20c12052 = htobe32(0); *(uint32_t*)0x20c12056 = htobe32(0); *(uint32_t*)0x20c1205a = htobe32(0); *(uint32_t*)0x20c1205e = htobe32(0); *(uint8_t*)0x20c12062 = 0x44; *(uint8_t*)0x20c12063 = 0xc; *(uint8_t*)0x20c12064 = 0; STORE_BY_BITMASK(uint8_t, 0x20c12065, 0, 0, 4); STORE_BY_BITMASK(uint8_t, 0x20c12065, 0, 4, 4); *(uint32_t*)0x20c12066 = htobe32(0xe0000001); *(uint32_t*)0x20c1206a = htobe32(0); *(uint8_t*)0x20c1206e = 0x94; *(uint8_t*)0x20c1206f = 6; *(uint32_t*)0x20c12070 = htobe32(0); *(uint8_t*)0x20c12074 = 0x94; *(uint8_t*)0x20c12075 = 6; *(uint32_t*)0x20c12076 = htobe32(0); *(uint8_t*)0x20c1207a = 0; *(uint32_t*)0x20ea3000 = 0; *(uint32_t*)0x20ea3004 = 0; struct csum_inet csum_1; csum_inet_init(&csum_1); csum_inet_update(&csum_1, (const uint8_t*)0x20c12022, 92); *(uint16_t*)0x20c12024 = csum_inet_digest(&csum_1); struct csum_inet csum_2; csum_inet_init(&csum_2); csum_inet_update(&csum_2, (const uint8_t*)0x20c1200e, 20); *(uint16_t*)0x20c12018 = csum_inet_digest(&csum_2); break; } } void test() { memset(r, -1, sizeof(r)); execute(12); collide = 1; execute(12); } int main() { for (;;) { loop(); } }