// https://syzkaller.appspot.com/bug?id=0777a1c9e163df248f65aff7c475df75a7cbe841 // 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 #ifndef __NR_bind #define __NR_bind 200 #endif #ifndef __NR_connect #define __NR_connect 203 #endif #ifndef __NR_listen #define __NR_listen 201 #endif #ifndef __NR_mmap #define __NR_mmap 222 #endif #ifndef __NR_sendmmsg #define __NR_sendmmsg 269 #endif #ifndef __NR_socket #define __NR_socket 198 #endif 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 setup_sysctl() { int cad_pid = fork(); if (cad_pid < 0) exit(1); if (cad_pid == 0) { for (;;) sleep(100); } char tmppid[32]; snprintf(tmppid, sizeof(tmppid), "%d", cad_pid); struct { const char* name; const char* data; } files[] = { {"/proc/sys/kernel/hung_task_check_interval_secs", "20"}, {"/proc/sys/net/core/bpf_jit_kallsyms", "1"}, {"/proc/sys/net/core/bpf_jit_harden", "0"}, {"/proc/sys/kernel/kptr_restrict", "0"}, {"/proc/sys/kernel/softlockup_all_cpu_backtrace", "1"}, {"/proc/sys/fs/mount-max", "100"}, {"/proc/sys/vm/oom_dump_tasks", "0"}, {"/proc/sys/debug/exception-trace", "0"}, {"/proc/sys/kernel/printk", "7 4 1 3"}, {"/proc/sys/kernel/keys/gc_delay", "1"}, {"/proc/sys/vm/oom_kill_allocating_task", "1"}, {"/proc/sys/kernel/ctrl-alt-del", "0"}, {"/proc/sys/kernel/cad_pid", tmppid}, }; for (size_t i = 0; i < sizeof(files) / sizeof(files[0]); i++) { if (!write_file(files[i].name, files[i].data)) { } } kill(cad_pid, SIGKILL); while (waitpid(cad_pid, NULL, 0) != cad_pid) ; } uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; int main(void) { syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul); syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul); syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul); setup_sysctl(); const char* reason; (void)reason; intptr_t res = 0; if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { } // socket$unix arguments: [ // domain: const = 0x1 (8 bytes) // type: unix_socket_type = 0x1 (8 bytes) // proto: const = 0x0 (4 bytes) // ] // returns sock_unix res = syscall(__NR_socket, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul, /*proto=*/0); if (res != -1) r[0] = res; // bind$unix arguments: [ // fd: sock_unix (resource) // addr: ptr[in, sockaddr_un] { // union sockaddr_un { // file: sockaddr_un_file { // family: unix_socket_family = 0x1 (2 bytes) // path: buffer: {e9 1f 71 89 59 1e 92 33 61 4b 00 00 00 00 00 00 00 // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00 00 00} (length 0x6c) // } // } // } // addrlen: len = 0x6e (8 bytes) // ] *(uint16_t*)0x20000180 = 1; memcpy( (void*)0x20000182, "\351\037q\211Y\036\2223aK\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 108); syscall(__NR_bind, /*fd=*/r[0], /*addr=*/0x20000180ul, /*addrlen=*/0x6eul); // listen arguments: [ // fd: sock (resource) // backlog: int32 = 0x2 (4 bytes) // ] syscall(__NR_listen, /*fd=*/r[0], /*backlog=*/2); // socket$unix arguments: [ // domain: const = 0x1 (8 bytes) // type: unix_socket_type = 0x1 (8 bytes) // proto: const = 0x0 (4 bytes) // ] // returns sock_unix res = syscall(__NR_socket, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul, /*proto=*/0); if (res != -1) r[1] = res; // connect$unix arguments: [ // fd: sock_unix (resource) // addr: ptr[in, sockaddr_un] { // union sockaddr_un { // file: sockaddr_un_file { // family: unix_socket_family = 0x1 (2 bytes) // path: buffer: {e9 1f 71 89 59 1e 92 33 61 4b 00 00 00 00 00 00 00 // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // 00 00 00} (length 0x6c) // } // } // } // addrlen: len = 0x6e (8 bytes) // ] *(uint16_t*)0x20000080 = 1; memcpy( (void*)0x20000082, "\351\037q\211Y\036\2223aK\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 108); syscall(__NR_connect, /*fd=*/r[1], /*addr=*/0x20000080ul, /*addrlen=*/0x6eul); // sendmmsg$unix arguments: [ // fd: sock_unix (resource) // mmsg: ptr[in, array[send_mmsghdr_un]] { // array[send_mmsghdr_un] { // send_mmsghdr_un { // msg_hdr: send_msghdr_un { // addr: nil // addrlen: len = 0x0 (4 bytes) // pad = 0x0 (4 bytes) // vec: ptr[in, array[iovec[in, array[int8]]]] { // array[iovec[in, array[int8]]] { // iovec[in, array[int8]] { // addr: ptr[in, buffer] { // buffer: {90} (length 0x1) // } // len: len = 0x1 (8 bytes) // } // } // } // vlen: len = 0x1 (8 bytes) // ctrl: ptr[in, array[cmsghdr_un]] { // array[cmsghdr_un] { // union cmsghdr_un { // rights: cmsghdr_t[SOL_SOCKET, SCM_RIGHTS, array[fd]] { // unaligned: cmsghdr_unaligned[SOL_SOCKET, SCM_RIGHTS, // array[fd]] { // cmsg_len: len = 0x14 (8 bytes) // cmsg_level: const = 0x1 (4 bytes) // cmsg_type: const = 0x1 (4 bytes) // data: array[fd] { // fd (resource) // } // } // } // } // } // } // ctrllen: bytesize = 0x18 (8 bytes) // f: send_flags = 0x8801 (4 bytes) // pad = 0x0 (4 bytes) // } // msg_len: const = 0x0 (4 bytes) // pad = 0x0 (4 bytes) // } // } // } // vlen: len = 0x1 (8 bytes) // f: send_flags = 0x20044034 (8 bytes) // ] *(uint64_t*)0x20000140 = 0; *(uint32_t*)0x20000148 = 0; *(uint64_t*)0x20000150 = 0x20000040; *(uint64_t*)0x20000040 = 0x20000340; memset((void*)0x20000340, 144, 1); *(uint64_t*)0x20000048 = 1; *(uint64_t*)0x20000158 = 1; *(uint64_t*)0x20000160 = 0x20000440; *(uint64_t*)0x20000440 = 0x14; *(uint32_t*)0x20000448 = 1; *(uint32_t*)0x2000044c = 1; *(uint32_t*)0x20000450 = r[0]; *(uint64_t*)0x20000168 = 0x18; *(uint32_t*)0x20000170 = 0x8801; *(uint32_t*)0x20000178 = 0; syscall(__NR_sendmmsg, /*fd=*/r[1], /*mmsg=*/0x20000140ul, /*vlen=*/1ul, /*f=MSG_FASTOPEN|MSG_BATCH|MSG_PROBE|MSG_NOSIGNAL|MSG_DONTROUTE|0x20*/ 0x20044034ul); return 0; }