// https://syzkaller.appspot.com/bug?id=32e375588044d1883ad3bccae52a3034609c759d // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef __NR_bpf #define __NR_bpf 321 #endif 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 = 0; for (; 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, 1000000); } 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_ACQUIRE)) return 1; now = current_time_ms(); if (now - start > timeout) return 0; } } 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 void kill_and_wait(int pid, int* status) { kill(-pid, SIGKILL); kill(pid, SIGKILL); for (int i = 0; i < 100; i++) { if (waitpid(-1, status, WNOHANG | __WALL) == pid) return; usleep(1000); } DIR* dir = opendir("/sys/fs/fuse/connections"); if (dir) { for (;;) { struct dirent* ent = readdir(dir); if (!ent) break; if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue; char abort[300]; snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort", ent->d_name); int fd = open(abort, O_WRONLY); if (fd == -1) { continue; } if (write(fd, abort, 1) < 0) { } close(fd); } closedir(dir); } else { } while (waitpid(-1, status, __WALL) != pid) { } } static void setup_test() { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setpgrp(); write_file("/proc/self/oom_score_adj", "1000"); } #define USLEEP_FORKED_CHILD (3 * 50 * 1000) static long handle_clone_ret(long ret) { if (ret != 0) { return ret; } usleep(USLEEP_FORKED_CHILD); syscall(__NR_exit, 0); while (1) { } } static long syz_clone(volatile long flags, volatile long stack, volatile long stack_len, volatile long ptid, volatile long ctid, volatile long tls) { long sp = (stack + stack_len) & ~15; long ret = (long)syscall(__NR_clone, flags & ~CLONE_VM, sp, ptid, ctid, tls); return handle_clone_ret(ret); } 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 execute_one(void) { if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { } int i, call, thread; for (call = 0; call < 12; 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, 50 + (call == 6 ? 500 : 0)); break; } } for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) sleep_ms(1); } static void execute_one(void); #define WAIT_FLAGS __WALL static void loop(void) { int iter = 0; for (;; iter++) { int pid = fork(); if (pid < 0) exit(1); if (pid == 0) { setup_test(); execute_one(); exit(0); } int status = 0; uint64_t start = current_time_ms(); for (;;) { sleep_ms(10); if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; if (current_time_ms() - start < 5000) continue; kill_and_wait(pid, &status); break; } } } uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; void execute_call(int call) { intptr_t res = 0; switch (call) { case 0: // ioctl$PERF_EVENT_IOC_SET_FILTER arguments: [ // fd: fd_perf (resource) // cmd: const = 0x8970 (4 bytes) // filter: ptr[in, buffer] { // buffer: {6c 6f 3a 96 6f 38 14 64 a1 ba da d1 a0 4a 12 74 51 b1 36 e3 // d7 5c 62 8b 1f a1 59 ad 34 90 9d 60 d2 98 00 00 6c 20 27 59 17 5d 15 // 63 ca 52 dd 98 4f 43 89 ff e6 84 e2 05 80 77 d2 7c 44 8d 4b 14 42 78 // cb 75 48 c2 ee 63 bf 3c 3e 59 1a fc 1f 39 4f 42 81 89 b7 6c ed 7d e5 // 18 36 c5 71 40 6e b4 b6 73 b0 00 00 00 00 02 08 00 00 da ef ec 45 ec // d5 49 b2 9b fe 8d 90 3f 00 e9 e4 7e 67 3a c1 b2 61 6b 96 bb a7 e2 c0 // dc f9 51 08 eb 01 00 00 00 d3 0d 37 8e ab 64 0f 74 70 82 ae d2 15 8e // 2b 63 f6 bf e1 34 3e a6 2d a5 63 de d7 ab ea 1f d5 73 32 9c 56 46 d5 // 18 fe 0f 8f 20 01 00 00 b1 88 eb 57 5f a5 e1 f6 8a 6a ca f8 6d ab e8 // 99 eb e1 de 8a 74 1c 80 fc b0 95 a2 a7 d7 2c 59 5d 45 38 83 58 f5 46 // dc 88 2d f5 b0 b5 5e db 1a b6 aa 14 e2 0d 68 5e 4a 2d d1 fc fa 20 36 // 28 25 1c b5 bf b6 90 b4 c2 7f 5d 2f b3 e7 c9 27 94 cf 49 6f df 04 95 // b5 06 84 1f 48 3e da c5 04 20 94 88 eb 27 d4 3b 36 7f d9 99 2d 1b 7c // 47 8d d4 b9 25 aa 51 a0 4b 10 1f 9c 2c 11 33 7f 03 93 e1 cc e7 66 0d // f3 ff 30 0c 82 25 5f 92 8b c4 b9 d9 e7 f2 e4 c1 69 03 9d dd 1b 6a df // ac 67 e3 a0 53 d3 8a e1 6e 97 ea f5 a0 27 0b e9 a0 f1 20 66 aa 6e cf // b5 69 b6 64 bc 92 0b d5 38 16 08 b3 5f 3a a4 21 0a 79 c4 26 0a 57 4d // 4d a8 c4 0b 9f 01 6f f4 ab 26 b6 17 02 21 ed ff ee 24 c8 39 8c 42 30 // d1 a8 d4 e6 4b 30 e1 a3 54 53 18 e6 78 1f 25 50 9f 55 29 83 45 0a 90 // 4d 0d 2e 85 67 6e 5f b2 e9 8a 1c e3 93 d8 bc b6 4e c3 e1 af 68 a0 69 // 46 dc 71 f9 17 d9 69 84 34 45 1a 13 9a e6 d3 ab 3a 50 4d fb 65 fe 39 // d9 94 1d 78 d6 03 62 f7 10 4e d1 93 0d 55 7f 79 18 74 45 f1 2a 9a 30 // 5a 9f dc 7b 13 f6 b7 f7 e6 3d 9c 44 10 38 8e 53 a0 d0 a7 09 6e d9 ae // c0 18 7e 78 5b 85 59 b2 82 77 15 30 97 ba e6 ca b1 a3 02 14 5e bd 5a // ae f5 2f cf b8 ea 38 55 77 92 60 22 32 81 6a bb 87 2b 89 c5 3c 4a 1f // ba fc 90 28 98 35 93 a8 d4 f0 bd 54 79 18 c8 a0 bb 99 8c e0 51 ff 43 // 6c bd 58 7e 33 a1 a2 f4 d9 f7 c7 fb ce 95 39 78 fe 57 0d f0 7b ca 54 // ec 70 29 3d 9d df 47 38 a1 e3 3d a6 00 98 c1 b3 91 2d ab 27 57 8a 6c // 3f 64 3c 4a 4e cb d4 48 b0 5f 6a 4f f3 90 e8 2f 6c df 67 29 8d 23 fd // 6f a9 4c de 41 2a ec a1 14 2c e8 8d 5e b9 72 3d c0 18 d4 11 64 55 5b // 52 79 ed d6 97 8a e8 ca 99 10 8e c8 50 a3 ae 2f da 6f 66 06 7f f7 80 // 24 66 08 92 ae eb dd 22 89 b8 f0 c3 08 00 00 00 00 07 f6 fc 1d d4 89 // 33 eb 29 c1 00 00 00 00 00 00 00 00 00 00 00 4f 21 d2 71 da 7d e2 a2 // fe fd 29 5c df 9a 4e 5c ae 79 63 e4 67 c0 8a 0a 0b 7b a9 48 5c d1 // 9d} (length 0x30b) // } // ] memcpy( (void*)0x200000000cc0, "lo:" "\226o8\024d\241\272\332\321\240J\022tQ\2616\343\327\\b\213\037\241Y" "\2554\220\235`\322\230\000\000l " "\'Y\027]\025c\312R\335\230OC\211\377\346\204\342\005\200w\322|" "D\215K\024Bx\313uH\302\356c\277<>Y\032\374\0379OB\201\211\267l\355}" "\345\0306\305q@" "n\264\266s\260\000\000\000\000\002\b\000\000\332\357\354E\354\325I\262" "\233\376\215\220?\000\351\344~g:" "\301\262ak\226\273\247\342\300\334\371Q\b\353\001\000\000\000\323\r7" "\216\253d\017tp\202\256\322\025\216+c\366\277\3414>\246-" "\245c\336\327\253\352\037\325s2\234VF\325\030\376\017\217 " "\001\000\000\261\210\353W_" "\245\341\366\212j\312\370m\253\350\231\353\341\336\212t\034\200\374" "\260\225\242\247\327,Y]E8\203X\365F\334\210-\365\260\265^" "\333\032\266\252\024\342\rh^J-\321\374\372 " "6(%\034\265\277\266\220\264\302\177]/" "\263\347\311\'\224\317Io\337\004\225\265\006\204\037H>\332\305\004 " "\224\210\353\'\324;6\177\331\231-\033|G\215\324\271%" "\252Q\240K\020\037\234," "\0213\177\003\223\341\314\347f\r\363\3770\f\202%_" "\222\213\304\271\331\347\362\344\301i\003\235\335\033j\337\254g\343" "\240S\323\212\341n\227\352\365\240\'\v\351\240\361 " "f\252n\317\265i\266d\274\222\v\3258\026\b\263_:\244!\ny\304&" "\nWMM\250\304\v\237\001o\364\253&\266\027\002!\355\377\356$" "\3109\214B0\321\250\324\346K0\341\243TS\030\346x\037%P\237U)" "\203E\n\220M\r.\205gn_" "\262\351\212\034\343\223\330\274\266N\303\341\257h\240iF\334q\371\027" "\331i\2044E\032\023\232\346\323\253:" "PM\373e\3769\331\224\035x\326\003b\367\020N\321\223\rU\177y\030tE\361*" "\2320Z\237\334{\023\366\267\367\346=" "\234D\0208\216S\240\320\247\tn\331\256\300\030~x[" "\205Y\262\202w\0250\227\272\346\312\261\243\002\024^\275Z\256\365/" "\317\270\3528Uw\222`\"2\201j\273\207+\211\305