| // Copyright 2018 syzkaller project authors. All rights reserved. |
| // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. |
| |
| // This file is shared between executor and csource package. |
| |
| #include <stdlib.h> |
| #include <unistd.h> |
| |
| #if SYZ_EXECUTOR || __NR_syz_mmap |
| #include <sys/mman.h> |
| |
| // syz_mmap(addr vma, len len[addr]) |
| static long syz_mmap(volatile long a0, volatile long a1) |
| { |
| return (long)mmap((void*)a0, a1, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0); |
| } |
| #endif |
| |
| #if SYZ_EXECUTOR || __NR_syz_errno |
| #include <errno.h> |
| |
| // syz_errno(v int32) |
| static long syz_errno(volatile long v) |
| { |
| errno = v; |
| return v == 0 ? 0 : -1; |
| } |
| #endif |
| |
| #if SYZ_EXECUTOR || __NR_syz_exit |
| // syz_exit(status int32) |
| static long syz_exit(volatile long status) |
| { |
| _exit(status); |
| return 0; |
| } |
| #endif |
| |
| #if SYZ_EXECUTOR || __NR_syz_sleep_ms |
| // syz_sleep_ms(ms intptr) |
| static long syz_sleep_ms(volatile long ms) |
| { |
| sleep_ms(ms); |
| return 0; |
| } |
| #endif |
| |
| #if SYZ_EXECUTOR || __NR_syz_compare |
| #include <errno.h> |
| #include <string.h> |
| |
| // syz_compare(want ptr[in, string], want_len len[want], got ptr[in, compare_data], got_len len[got]) |
| static long syz_compare(volatile long want, volatile long want_len, volatile long got, volatile long got_len) |
| { |
| if (want_len != got_len) { |
| errno = EBADF; |
| goto error; |
| } |
| if (memcmp((void*)want, (void*)got, want_len)) { |
| errno = EINVAL; |
| goto error; |
| } |
| return 0; |
| |
| error: |
| debug("syz_compare: want (%lu):\n", want_len); |
| debug_dump_data((char*)want, want_len); |
| debug("got (%lu):\n", got_len); |
| debug_dump_data((char*)got, got_len); |
| return -1; |
| } |
| #endif |
| |
| #if SYZ_EXECUTOR || __NR_syz_compare_int |
| #include <errno.h> |
| #include <stdarg.h> |
| |
| // syz_compare_int$4(n const[2], v0 intptr, v1 intptr, v2 intptr, v3 intptr) |
| static long syz_compare_int(volatile long n, ...) |
| { |
| va_list args; |
| va_start(args, n); |
| long v0 = va_arg(args, long); |
| long v1 = va_arg(args, long); |
| long v2 = va_arg(args, long); |
| long v3 = va_arg(args, long); |
| va_end(args); |
| if (n < 2 || n > 4) |
| return errno = E2BIG, -1; |
| if (n <= 2 && v2 != 0) |
| return errno = EFAULT, -1; |
| if (n <= 3 && v3 != 0) |
| return errno = EFAULT, -1; |
| if (v0 != v1) |
| return errno = EINVAL, -1; |
| if (n > 2 && v0 != v2) |
| return errno = EINVAL, -1; |
| if (n > 3 && v0 != v3) |
| return errno = EINVAL, -1; |
| return 0; |
| } |
| #endif |
| |
| #if SYZ_EXECUTOR || __NR_syz_compare_zlib |
| #include "common_zlib.h" |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <sys/stat.h> |
| |
| // syz_compare_zlib(data ptr[in, array[int8]], size bytesize[data], zdata ptr[in, compressed_image], zsize bytesize[zdata]) |
| static long syz_compare_zlib(volatile long data, volatile long size, volatile long zdata, volatile long zsize) |
| { |
| int fd = open("./uncompressed", O_RDWR | O_CREAT | O_EXCL, 0666); |
| if (fd == -1) |
| return -1; |
| if (puff_zlib_to_file((unsigned char*)zdata, zsize, fd)) |
| return -1; |
| struct stat statbuf; |
| if (fstat(fd, &statbuf)) |
| return -1; |
| void* uncompressed = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
| if (uncompressed == MAP_FAILED) |
| return -1; |
| return syz_compare(data, size, (long)uncompressed, statbuf.st_size); |
| } |
| #endif |
| |
| #if SYZ_EXECUTOR || SYZ_SANDBOX_NONE |
| static void loop(); |
| static int do_sandbox_none(void) |
| { |
| loop(); |
| return 0; |
| } |
| #endif |