// https://syzkaller.appspot.com/bug?id=a7ecc3cf7a6c3f91078de052f071f49e7e0a9dcd // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #ifndef __NR_mkdirat #define __NR_mkdirat 34 #endif #ifndef __NR_mmap #define __NR_mmap 222 #endif #ifndef __NR_mount #define __NR_mount 40 #endif #ifndef __NR_openat #define __NR_openat 56 #endif #ifndef __NR_prctl #define __NR_prctl 167 #endif #ifndef __NR_preadv #define __NR_preadv 69 #endif static long syz_open_procfs(volatile long a0, volatile long a1) { char buf[128]; memset(buf, 0, sizeof(buf)); if (a0 == 0) { snprintf(buf, sizeof(buf), "/proc/self/%s", (char*)a1); } else if (a0 == -1) { snprintf(buf, sizeof(buf), "/proc/thread-self/%s", (char*)a1); } else { snprintf(buf, sizeof(buf), "/proc/self/task/%d/%s", (int)a0, (char*)a1); } int fd = open(buf, O_RDWR); if (fd == -1) fd = open(buf, O_RDONLY); return fd; } uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; int main(void) { syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul); syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000, /*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=*/0x1000, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul); const char* reason; (void)reason; intptr_t res = 0; if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { } // mkdirat arguments: [ // fd: fd_dir (resource) // path: ptr[in, buffer] { // buffer: {2e 2f 6d 79 73 79 73 00} (length 0x8) // } // mode: open_mode = 0x1 (8 bytes) // ] memcpy((void*)0x20000040, "./mysys\000", 8); syscall(__NR_mkdirat, /*fd=*/0xffffff9c, /*path=*/0x20000040ul, /*mode=S_IXOTH*/ 1ul); // mount arguments: [ // src: nil // dst: ptr[in, buffer] { // buffer: {2e 2f 6d 79 73 79 73 00} (length 0x8) // } // type: ptr[in, buffer] { // buffer: {73 79 73 66 73 00} (length 0x6) // } // flags: mount_flags = 0x0 (8 bytes) // data: nil // ] memcpy((void*)0x20000100, "./mysys\000", 8); memcpy((void*)0x20000200, "sysfs\000", 6); syscall(__NR_mount, /*src=*/0ul, /*dst=*/0x20000100ul, /*type=*/0x20000200ul, /*flags=*/0ul, /*data=*/0ul); // openat arguments: [ // fd: fd_dir (resource) // file: ptr[in, buffer] { // buffer: {2e 2f 6d 79 73 79 73 2f 62 75 73 2f 70 63 69 2f 64 65 76 69 // 63 65 73 2f 30 30 30 30 3a 30 30 3a 30 32 2e 30 2f 72 65 73 6f 75 72 // 63 65 30 00} (length 0x2f) // } // flags: open_flags = 0x2 (4 bytes) // mode: open_mode = 0x0 (2 bytes) // ] // returns fd memcpy((void*)0x20000300, "./mysys/bus/pci/devices/0000:00:02.0/resource0\000", 47); res = syscall(__NR_openat, /*fd=*/0xffffff9c, /*file=*/0x20000300ul, /*flags=O_RDWR*/ 2, /*mode=*/0); if (res != -1) r[0] = res; // mmap$binder arguments: [ // addr: VMA[0x3000] // len: len = 0x3000 (4 bytes) // prot: const = 0x1 (8 bytes) // flags: const = 0x11 (8 bytes) // fd: fd_binder (resource) // offset: intptr = 0x0 (8 bytes) // ] // returns binder_ptr syscall(__NR_mmap, /*addr=*/0x20ffd000ul, /*len=*/0x3000, /*prot=*/1ul, /*flags=*/0x11ul, /*fd=*/r[0], /*offset=*/0ul); // prctl$PR_SET_MM arguments: [ // option: const = 0x23 (8 bytes) // opt: prctl_mm_option = 0xa (8 bytes) // arg: VMA[0x2000] // ] syscall(__NR_prctl, /*option=*/0x23ul, /*opt=PR_SET_MM_ENV_START*/ 0xaul, /*arg=*/0x202d5000ul, 0, 0); // syz_open_procfs arguments: [ // pid: pid (resource) // file: ptr[in, buffer] { // buffer: {65 6e 76 69 72 6f 6e 00} (length 0x8) // } // ] // returns fd memcpy((void*)0x200001c0, "environ\000", 8); res = -1; res = syz_open_procfs(/*pid=*/-1, /*file=*/0x200001c0); if (res != -1) r[1] = res; // preadv arguments: [ // fd: fd (resource) // vec: ptr[in, array[iovec[out, array[int8]]]] { // array[iovec[out, array[int8]]] { // iovec[out, array[int8]] { // addr: ptr[out, buffer] { // buffer: (DirOut) // } // len: len = 0x200000b1 (8 bytes) // } // } // } // vlen: len = 0x1 (8 bytes) // off_low: int32 = 0xc002a0 (4 bytes) // off_high: int32 = 0x0 (4 bytes) // ] *(uint64_t*)0x20001400 = 0x20000040; *(uint64_t*)0x20001408 = 0x200000b1; syscall(__NR_preadv, /*fd=*/r[1], /*vec=*/0x20001400ul, /*vlen=*/1ul, /*off_low=*/0xc002a0, /*off_high=*/0); return 0; }