// autogenerated by syzkaller (http://github.com/google/syzkaller) #ifndef __NR_mmap #define __NR_mmap 9 #endif #ifndef __NR_openat #define __NR_openat 257 #endif #ifndef __NR_ioctl #define __NR_ioctl 16 #endif #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const int kFailStatus = 67; const int kErrorStatus = 68; const int kRetryStatus = 69; __attribute__((noreturn)) void doexit(int status) { volatile unsigned i; syscall(__NR_exit_group, status); for (i = 0;; i++) { } } __attribute__((noreturn)) void fail(const char* msg, ...) { int e = errno; fflush(stdout); 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); } __attribute__((noreturn)) void exitf(const char* msg, ...) { int e = errno; fflush(stdout); va_list args; va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); fprintf(stderr, " (errno %d)\n", e); doexit(kRetryStatus); } static int flag_debug; void debug(const char* msg, ...) { if (!flag_debug) return; va_list args; va_start(args, msg); vfprintf(stdout, msg, args); va_end(args); fflush(stdout); } __thread int skip_segv; __thread jmp_buf segv_env; static void segv_handler(int sig, siginfo_t* info, void* uctx) { uintptr_t addr = (uintptr_t)info->si_addr; const uintptr_t prog_start = 1 << 20; const uintptr_t prog_end = 100 << 20; if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) && (addr < prog_start || addr > prog_end)) { debug("SIGSEGV on %p, skipping\n", addr); _longjmp(segv_env, 1); } debug("SIGSEGV on %p, exiting\n", addr); doexit(sig); for (;;) { } } static void install_segv_handler() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = segv_handler; sa.sa_flags = SA_NODEFER | SA_SIGINFO; sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); } #define NONFAILING(...) \ { \ __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \ if (_setjmp(segv_env) == 0) { \ __VA_ARGS__; \ } \ __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \ } #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; }; void csum_inet_init(struct csum_inet* csum) { csum->acc = 0; } 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); } uint16_t csum_inet_digest(struct csum_inet* csum) { return ~csum->acc; } static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8) { switch (nr) { default: return syscall(nr, a0, a1, a2, a3, a4, a5); } } static void setup_main_process() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8); syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8); install_segv_handler(); char tmpdir_template[] = "./syzkaller.XXXXXX"; char* tmpdir = mkdtemp(tmpdir_template); if (!tmpdir) fail("failed to mkdtemp"); if (chmod(tmpdir, 0777)) fail("failed to chmod"); if (chdir(tmpdir)) fail("failed to chdir"); } static void loop(); static void sandbox_common() { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setpgrp(); setsid(); struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = 128 << 20; setrlimit(RLIMIT_AS, &rlim); rlim.rlim_cur = rlim.rlim_max = 1 << 20; setrlimit(RLIMIT_FSIZE, &rlim); rlim.rlim_cur = rlim.rlim_max = 1 << 20; setrlimit(RLIMIT_STACK, &rlim); rlim.rlim_cur = rlim.rlim_max = 0; setrlimit(RLIMIT_CORE, &rlim); unshare(CLONE_NEWNS); unshare(CLONE_NEWIPC); unshare(CLONE_IO); } static int do_sandbox_none(int executor_pid, bool enable_tun) { int pid = fork(); if (pid) return pid; sandbox_common(); loop(); doexit(1); } long r[8]; void loop() { memset(r, -1, sizeof(r)); r[0] = execute_syscall(__NR_mmap, 0x20000000ul, 0x24000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0); NONFAILING(memcpy((void*)0x20000ff7, "\x2f\x64\x65\x76\x2f\x6b\x76\x6d\x00", 9)); r[2] = execute_syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000ff7ul, 0x0ul, 0x0ul, 0, 0, 0, 0, 0); r[3] = execute_syscall(__NR_ioctl, r[2], 0xae01ul, 0x0ul, 0, 0, 0, 0, 0, 0); r[4] = execute_syscall(__NR_ioctl, r[3], 0xae41ul, 0x0ul, 0, 0, 0, 0, 0, 0); NONFAILING(memcpy( (void*)0x2001f000, "\x91\xc9\xf5\xef\x81\xe7\x23\x8b\xca\x8f\x51\xc2\x18\x94\x45\x7a" "\x06\x66\xde\x83\x3f\x19\x7b\x4b\x74\x5e\x44\xa5\xa4\x9b\x63\x66" "\xc0\x89\x49\x89\xf9\x63\xf9\xd0\xf7\xcc\x3e\x45\x47\xf3\xd4\x73" "\x61\x50\xf7\x90\x74\x66\x4f\x6a\xa3\x4e\x92\x1d\xc1\x31\xd4\xc8" "\xdc\x2e\x16\xa3\x62\xdd\xec\x06\x03\x88\xd2\x54\x05\xdc\xee\xad" "\x74\xeb\x48\xcb\x0e\x19\x43\x6f\xb1\x06\x43\xe8\xad\x7c\x7e\x6d" "\xc4\xc7\x74\x8a\xc5\x94\x00\x00\x00\x00\xff\xff\xff\xff\xb3\x6e" "\xa3\x72\x30\x71\x01\xfe\x6a\xc6\x95\x04\xad\xba\x17\x36\x9e\x92" "\x6c\x02\xc0\x16\x22\x34\x82\x88\xeb\xee\x6f\xb5\x84\xc6\x1f\x04" "\xd6\x12\x66\x88\x39\x40\x5a\xab\x69\xbf\x41\x38\xe2\x51\x8b\x40" "\x19\x99\x94\x8e\xcb\x9f\xb1\xf2\x6d\x85\xdc\xc7\x02\xb2\x56\xf6" "\xf6\xb8\x43\x5b\x19\x19\xcf\xd0\xae\x60\x85\x30\xb0\xc0\x71\xef" "\xe4\xd6\xd9\xb2\x6c\x6e\x3b\xbc\x7a\x13\xee\xbb\xb6\x34\x50\x22" "\x89\x0b\x51\x0c\xb5\xbc\x8f\xde\x7d\xb6\xb0\x3d\xa8\x35\x0f\xf1" "\x31\x64\xd1\x33\x0b\x43\x82\xa0\x28\x07\xdd\x2b\x1b\xaf\x3a\x25" "\xb7\x0c\x39\x41\x70\x71\x15\x07\xf7\x37\x85\x5a\x41\x5e\xf2\x44" "\xbb\xbc\x46\x95\x76\xcf\xa3\x4c\x72\x54\x27\x50\x01\x62\x8a\x8a" "\xf6\x14\x63\xda\xf8\x6d\x86\xd4\xc1\x52\x18\x74\x05\xc2\x41\xe5" "\x67\x7f\xa8\xf9\x75\x6d\x2c\x5f\xd6\xbb\x33\x45\x5d\xa9\xe1\xbf" "\xec\xe3\x87\xb6\x0d\xaf\xe0\xe4\xf5\x88\x5e\x8c\x4a\xb7\x0a\x0d" "\xdc\x10\x6d\x26\x77\xd3\x58\x37\xfa\x52\x9c\xcb\xc3\x84\xcb\xab" "\xce\x04\x93\x73\x18\x6a\x68\x66\xdb\x11\x44\x26\x66\x0c\xe1\xfc" "\x7b\x9a\x86\x09\x2b\xed\x07\x4a\x24\x4f\x7a\xe3\xb8\xe9\xaa\x2d" "\x71\x2c\x5b\xcf\x34\xb7\x30\x34\x41\xe5\x5e\xe3\x07\x44\x50\x95" "\x1a\x49\xb2\x6d\x10\xd2\xb3\xf0\x7c\x32\xba\xf8\xe8\x5b\x28\xe4" "\x08\xe7\x76\x11\xe4\x25\x3f\xb7\x9f\xf2\x9c\xd8\x3b\x17\x51\x86" "\x79\x30\x63\x5c\x12\xa7\x41\x59\xa4\xbc\xb4\x7f\x17\xf4\xbb\xfc" "\xb4\x25\x0a\x09\x49\x35\xbe\x2b\x89\x60\x67\x2f\x44\xab\x6c\xb4" "\xdc\x79\xf9\xee\xf6\xa4\xc8\x53\xe3\xbf\x2d\xc8\x6a\x34\xb4\xe5" "\x2b\xc6\xb2\x03\x1d\x11\x9d\x68\x3c\xea\x49\x82\x64\x88\xf9\xa2" "\x67\x4d\x27\xaa\x23\x46\x32\x02\x6b\x2b\x40\xf6\x1d\x8a\x9b\xce" "\x3b\xcc\x25\x95\x42\x09\xae\x42\x99\x34\xa8\xee\x26\x95\x7e\x32" "\x03\x00\x00\x00\x00\x00\x00\x00\xb6\x88\xe0\x93\x33\xc6\x0a\x8c" "\x7c\x20\x94\x02\x64\x25\x97\x27\x3b\xaf\x06\xb2\xec\xeb\xd1\x7c" "\x20\x61\x78\x3f\x14\x05\xf5\x7a\x90\xcd\x92\x5e\xfa\x4d\xd6\x71" "\x37\xdd\xc4\x5d\x49\xe2\x05\xbd\x4f\x29\x3e\x6e\x7c\x0c\xe2\x68" "\x9f\x92\xa5\x30\xa6\x11\xfa\x69\xa4\x89\x85\x12\x3a\xf4\x88\x35" "\x0e\xc0\xc5\x4e\xaa\x1b\xed\x2e\x2a\x6b\xa3\xe2\x89\x04\x1d\x5c" "\x74\xc4\xf3\x14\x5a\x3b\xf5\x32\xf5\x2d\xd4\x5d\xba\xac\x87\xe7" "\x63\x5a\x1e\xc5\x23\xa6\x38\x7c\xa9\x68\xf4\x1f\x7f\x1c\x4f\x6b" "\xb6\xba\xb5\x54\x32\x2e\x87\x28\x00\x7f\x2b\xa5\xd6\xdb\xb7\xb2" "\xe5\x11\xda\x26\xd4\x60\x3c\x57\x3f\x0e\x4f\x7c\x29\xbd\x24\x05" "\x12\x1e\x8b\xd8\xef\xd1\x0b\x43\x40\x71\x46\xa1\xb4\x29\xc4\xc5" "\x72\xc1\xfc\x72\x75\x56\x16\xf3\x5f\xe8\xa5\x61\xfc\x96\x62\x80" "\xc3\x28\xb0\xd1\x9d\x77\x84\x9d\x82\xd2\x9d\x11\x4d\xf7\x19\x0f" "\x27\x0c\xeb\xfb\xec\x61\x6b\x5d\x57\x90\x79\x44\xfe\x08\xc6\x21" "\xe7\xeb\xdc\xd5\x38\x9f\x9a\x89\x57\xac\xb1\xce\x49\x83\x8d\xd0" "\xb5\xce\xd6\x60\xea\x7e\xf1\x9c\xc2\xac\x5e\x23\x48\xa8\xcb\xb5" "\x68\xd0\x5a\xf0\x34\xf4\xfb\x1c\xc7\x76\xfc\xab\xa1\x7d\x8b\x75" "\xea\x8c\x86\x43\x1b\x3c\xf5\x26\xac\x3c\xb9\x90\x53\xa5\xb5\xef" "\x62\x56\xd3\x00\x71\x9f\xe2\x12\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x6d\x2d\xfb\xa3\xe3\x72\x30\x41\x0a\x3b\x94\x0a\x3e\x08" "\xd6\x09\x10\xcf\xa0\xcc\x83\x2d\xc4\x2d\x54\x5a\x1d\xb7\x31\x99" "\x74\xd8\xd3\x15\x06\x00\x19\xf1\xa0\x29\xe3\xc6\x70\x2d\x39\x43" "\xf1\x54\x56\x3c\x1e\x4e\x68\x5f\x83\x51\xbb\xa4\x45\x13\x8e\x13" "\x71\xd8\x9e\xeb\x81\xe1\x10\xb6\x85\x0e\xa2\xd9\x1f\xfc\x91\xee" "\x67\x0b\x53\x94\x32\x4f\x05\x0f\x37\xdd\xad\x51\xc8\x60\xdb\x3c" "\x4e\x3e\x71\xc3\x04\x12\x12\x7d\xb0\x5e\x0c\x75\x5d\xe0\xe8\x94" "\xc3\x53\x37\x51\xfa\x2c\x97\x37\xa9\xdc\xd9\x12\x00\xf4\x68\xf2" "\x09\xa5\x92\xa3\x43\x57\x38\x08\x54\x85\x97\xad\xae\x95\x25\x40" "\x60\xf8\xcb\x27\x5f\x7d\xa1\x3a\x42\xda\xcc\x5d\x4b\xa7\xc3\xd3" "\xac\x1f\xf8\xe4\x88\xcd\xab\xc6\x83\xe0\xb5\xa5\x55\x9e\x8c\x33" "\x59\xd9\x7a\xfb\xce\xa0\x52\xe8\x90\x11\x88\x62\xa0\x27\xec\xcf" "\x09\x5d\xfd\xc1\xfa\x78\x57\x39\x7c\xf3\x84\xec\xe5\x9a\x09" "\x06", 1024)); r[6] = execute_syscall(__NR_ioctl, r[4], 0x5000aea5ul, 0x2001f000ul, 0, 0, 0, 0, 0, 0); r[7] = execute_syscall(__NR_ioctl, r[4], 0xae80ul, 0, 0, 0, 0, 0, 0, 0); } int main() { setup_main_process(); int pid = do_sandbox_none(0, false); int status = 0; while (waitpid(pid, &status, __WALL) != pid) { } return 0; }