about summary refs log tree commit diff
path: root/qemu_mode
diff options
context:
space:
mode:
Diffstat (limited to 'qemu_mode')
-rwxr-xr-xqemu_mode/build_qemu_support.sh1
-rw-r--r--qemu_mode/patches/afl-qemu-common.h10
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-inl.h85
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-translate-inl.h3
-rw-r--r--qemu_mode/patches/afl-qemu-tcg-runtime-inl.h2
-rw-r--r--qemu_mode/patches/bsd-elfload.diff44
-rw-r--r--qemu_mode/patches/mmap_fixes.diff165
7 files changed, 293 insertions, 17 deletions
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index 1828528e..a7bfe20d 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -193,6 +193,7 @@ patch -p1 <../patches/tcg-runtime-head.diff || exit 1
 patch -p1 <../patches/translator.diff || exit 1
 patch -p1 <../patches/__init__.py.diff || exit 1
 patch -p1 <../patches/make_strncpy_safe.diff || exit 1
+patch -p1 <../patches/mmap_fixes.diff || exit 1
 
 echo "[+] Patching done."
 
diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h
index 057e1b62..6fac32ef 100644
--- a/qemu_mode/patches/afl-qemu-common.h
+++ b/qemu_mode/patches/afl-qemu-common.h
@@ -54,7 +54,7 @@
 #if (defined(__x86_64__) || defined(__i386__)) && defined(AFL_QEMU_NOT_ZERO)
   #define INC_AFL_AREA(loc)           \
     asm volatile(                     \
-        "incb (%0, %1, 1)\n"          \
+        "addb $1, (%0, %1, 1)\n"      \
         "adcb $0, (%0, %1, 1)\n"      \
         : /* no out */                \
         : "r"(afl_area_ptr), "r"(loc) \
@@ -63,7 +63,9 @@
   #define INC_AFL_AREA(loc) afl_area_ptr[loc]++
 #endif
 
-typedef void (*afl_persistent_hook_fn)(uint64_t *regs, uint64_t guest_base);
+typedef void (*afl_persistent_hook_fn)(uint64_t *regs, uint64_t guest_base,
+                                       uint8_t *input_buf,
+                                       uint32_t input_buf_len);
 
 /* Declared in afl-qemu-cpu-inl.h */
 
@@ -81,6 +83,10 @@ extern unsigned char  persistent_save_gpr;
 extern uint64_t       persistent_saved_gpr[AFL_REGS_NUM];
 extern int            persisent_retaddr_offset;
 
+extern u8 * shared_buf;
+extern u32 *shared_buf_len;
+extern u8   sharedmem_fuzzing;
+
 extern afl_persistent_hook_fn afl_persistent_hook_ptr;
 
 extern __thread abi_ulong afl_prev_loc;
diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h
index e4ebaf88..5f579687 100644
--- a/qemu_mode/patches/afl-qemu-cpu-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-inl.h
@@ -83,6 +83,10 @@ unsigned char persistent_save_gpr;
 uint64_t      persistent_saved_gpr[AFL_REGS_NUM];
 int           persisent_retaddr_offset;
 
+u8 * shared_buf;
+u32 *shared_buf_len;
+u8   sharedmem_fuzzing;
+
 afl_persistent_hook_fn afl_persistent_hook_ptr;
 
 /* Instrumentation ratio: */
@@ -128,6 +132,7 @@ static inline TranslationBlock *tb_find(CPUState *, TranslationBlock *, int,
 static inline void              tb_add_jump(TranslationBlock *tb, int n,
                                             TranslationBlock *tb_next);
 int                             open_self_maps(void *cpu_env, int fd);
+static void                     afl_map_shm_fuzz(void);
 
 /*************************
  * ACTUAL IMPLEMENTATION *
@@ -135,6 +140,42 @@ int                             open_self_maps(void *cpu_env, int fd);
 
 /* Set up SHM region and initialize other stuff. */
 
+static void afl_map_shm_fuzz(void) {
+
+  char *id_str = getenv(SHM_FUZZ_ENV_VAR);
+
+  if (id_str) {
+
+    u32 shm_id = atoi(id_str);
+    u8 *map = (u8 *)shmat(shm_id, NULL, 0);
+    /* Whooooops. */
+
+    if (!map || map == (void *)-1) {
+
+      perror("[AFL] ERROR: could not access fuzzing shared memory");
+      exit(1);
+
+    }
+
+    shared_buf_len = (u32 *)map;
+    shared_buf = map + sizeof(u32);
+
+    if (getenv("AFL_DEBUG")) {
+
+      fprintf(stderr, "[AFL] DEBUG: successfully got fuzzing shared memory\n");
+
+    }
+
+  } else {
+
+    fprintf(stderr,
+            "[AFL] ERROR:  variable for fuzzing shared memory is not set\n");
+    exit(1);
+
+  }
+
+}
+
 void afl_setup(void) {
 
   char *id_str = getenv(SHM_ENV_VAR), *inst_r = getenv("AFL_INST_RATIO");
@@ -248,6 +289,11 @@ void afl_setup(void) {
 
     }
 
+    int (*afl_persistent_hook_init_ptr)(void) =
+        dlsym(plib, "afl_persistent_hook_init");
+    if (afl_persistent_hook_init_ptr)
+      sharedmem_fuzzing = afl_persistent_hook_init_ptr();
+
     afl_persistent_hook_ptr = dlsym(plib, "afl_persistent_hook");
     if (!afl_persistent_hook_ptr) {
 
@@ -278,7 +324,7 @@ void afl_setup(void) {
 
 void afl_forkserver(CPUState *cpu) {
 
-  u32           map_size = 0;
+  // u32           map_size = 0;
   unsigned char tmp[4] = {0};
 
   if (forkserver_installed == 1) return;
@@ -291,15 +337,17 @@ void afl_forkserver(CPUState *cpu) {
   pid_t child_pid;
   int   t_fd[2];
   u8    child_stopped = 0;
+  u32   was_killed;
+  int   status = 0;
 
-  // if in the future qemu has non-collding coverage then switch MAP_SIZE
   // with the max ID value
-  if (MAP_SIZE <= 0x800000) {
-
-    map_size = (FS_OPT_ENABLED | FS_OPT_MAPSIZE | FS_OPT_SET_MAPSIZE(MAP_SIZE));
-    memcpy(tmp, &map_size, 4);
-
-  }
+  if (MAP_SIZE <= FS_OPT_MAX_MAPSIZE)
+    status |= (FS_OPT_SET_MAPSIZE(MAP_SIZE) | FS_OPT_MAPSIZE);
+  if (sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
+  if (status) status |= (FS_OPT_ENABLED);
+  if (getenv("AFL_DEBUG"))
+    fprintf(stderr, "Debug: Sending status %08x\n", status);
+  memcpy(tmp, &status, 4);
 
   /* Tell the parent that we're alive. If the parent doesn't want
      to talk, assume that we're not running in forkserver mode. */
@@ -310,13 +358,28 @@ void afl_forkserver(CPUState *cpu) {
 
   int first_run = 1;
 
+  if (sharedmem_fuzzing) {
+
+    if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2);
+
+    if ((was_killed & (0xffffffff & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))) ==
+        (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))
+      afl_map_shm_fuzz();
+    else {
+
+      fprintf(stderr,
+              "[AFL] ERROR: afl-fuzz is old and does not support"
+              " shmem input");
+      exit(1);
+
+    }
+
+  }
+
   /* All right, let's await orders... */
 
   while (1) {
 
-    int status;
-    u32 was_killed;
-
     /* Whoops, parent dead? */
 
     if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2);
diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
index 083c27e5..8553f194 100644
--- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
@@ -161,7 +161,8 @@ static void log_x86_sp_content(void) {
 
 static void callback_to_persistent_hook(void) {
 
-  afl_persistent_hook_ptr(persistent_saved_gpr, guest_base);
+  afl_persistent_hook_ptr(persistent_saved_gpr, guest_base, shared_buf,
+                          *shared_buf_len);
 
 }
 
diff --git a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
index a0246198..400ebf24 100644
--- a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
+++ b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h
@@ -215,7 +215,7 @@ void HELPER(afl_cmplog_rtn)(CPUArchState *env) {
 
 #else
 
-  // dumb code to make it compile
+  // stupid code to make it compile
   void *ptr1 = NULL;
   void *ptr2 = NULL;
   return;
diff --git a/qemu_mode/patches/bsd-elfload.diff b/qemu_mode/patches/bsd-elfload.diff
index 6b021bb6..19e44f5b 100644
--- a/qemu_mode/patches/bsd-elfload.diff
+++ b/qemu_mode/patches/bsd-elfload.diff
@@ -11,7 +11,37 @@ index 7cccf3eb..195875af 100644
  /* from personality.h */
  
  /*
-@@ -1522,6 +1524,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
+@@ -737,9 +739,13 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
+             end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss);
+             end_addr = HOST_PAGE_ALIGN(elf_bss);
+             if (end_addr1 < end_addr) {
+-                mmap((void *)g2h(end_addr1), end_addr - end_addr1,
++                void *p = mmap((void *)g2h(end_addr1), end_addr - end_addr1,
+                      PROT_READ|PROT_WRITE|PROT_EXEC,
+                      MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0);
++                if (p == MAP_FAILED) {
++                    perror("padzero: cannot mmap");
++                    exit(-1);
++                }
+             }
+         }
+ 
+@@ -979,9 +985,13 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex,
+ 
+         /* Map the last of the bss segment */
+         if (last_bss > elf_bss) {
+-            target_mmap(elf_bss, last_bss-elf_bss,
++            void *p = target_mmap(elf_bss, last_bss-elf_bss,
+                         PROT_READ|PROT_WRITE|PROT_EXEC,
+                         MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0);
++            if (p == MAP_FAILED) {
++                perror("load_elf_interp: cannot mmap");
++                exit(-1);
++            }
+         }
+         free(elf_phdata);
+ 
+@@ -1522,6 +1532,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
      info->start_data = start_data;
      info->end_data = end_data;
      info->start_stack = bprm->p;
@@ -20,7 +50,17 @@ index 7cccf3eb..195875af 100644
  
      /* Calling set_brk effectively mmaps the pages that we need for the bss and break
         sections */
-@@ -1549,6 +1553,20 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
+@@ -1544,11 +1556,29 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
+                and some applications "depend" upon this behavior.
+                Since we do not have the power to recompile these, we
+                emulate the SVr4 behavior.  Sigh.  */
+-            target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
++            void *p = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
+                                       MAP_FIXED | MAP_PRIVATE, -1, 0);
++            if (p == MAP_FAILED) {
++                perror("load_elf_binary: cannot mmap");
++                exit(-1);
++            }
      }
  
      info->entry = elf_entry;
diff --git a/qemu_mode/patches/mmap_fixes.diff b/qemu_mode/patches/mmap_fixes.diff
new file mode 100644
index 00000000..1882bd40
--- /dev/null
+++ b/qemu_mode/patches/mmap_fixes.diff
@@ -0,0 +1,165 @@
+diff --git a/exec.c b/exec.c
+index df5571e..d484098 100644
+--- a/exec.c
++++ b/exec.c
+@@ -2457,7 +2457,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
+                     area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
+                                 flags, -1, 0);
+                 }
+-                if (area != vaddr) {
++                if (area == MAP_FAILED || area != vaddr) {
+                     error_report("Could not remap addr: "
+                                  RAM_ADDR_FMT "@" RAM_ADDR_FMT "",
+                                  length, addr);
+diff --git a/linux-user/mmap.c b/linux-user/mmap.c
+index 41e0983..0a8b8e5 100644
+--- a/linux-user/mmap.c
++++ b/linux-user/mmap.c
+@@ -612,9 +612,13 @@ static void mmap_reserve(abi_ulong start, abi_ulong size)
+             real_end -= qemu_host_page_size;
+     }
+     if (real_start != real_end) {
+-        mmap(g2h(real_start), real_end - real_start, PROT_NONE,
++        void *p = mmap(g2h(real_start), real_end - real_start, PROT_NONE,
+                  MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE,
+                  -1, 0);
++        if (p == MAP_FAILED) {
++            perror("mmap_reserve: cannot mmap");
++            exit(-1);
++        }
+     }
+ }
+ 
+diff --git a/roms/SLOF/tools/sloffs.c b/roms/SLOF/tools/sloffs.c
+index 9a1eace..10366f0 100644
+--- a/roms/SLOF/tools/sloffs.c
++++ b/roms/SLOF/tools/sloffs.c
+@@ -308,6 +308,10 @@ sloffs_append(const int file, const char *name, const char *dest)
+ 
+ 	fstat(fd, &stat);
+ 	append = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0);
++	if (append == MAP_FAILED) {
++		perror("sloffs_append: cannot mmap for read");
++		exit(1);
++	}
+ 	header = sloffs_header(file);
+ 
+ 	if (!header)
+@@ -331,6 +335,10 @@ sloffs_append(const int file, const char *name, const char *dest)
+ 	write(out, "", 1);
+ 	write_start = mmap(NULL, new_len, PROT_READ | PROT_WRITE,
+ 			   MAP_SHARED, out, 0);
++	if (write_start == MAP_FAILED) {
++		perror("sloffs_append: cannot mmap for read/write");
++		exit(1);
++	}
+ 
+ 	memset(write_start, 0, new_len);
+ 	memset(&new_file, 0, sizeof(struct sloffs));
+diff --git a/roms/skiboot/core/test/run-trace.c b/roms/skiboot/core/test/run-trace.c
+index 9801688..236b51d 100644
+--- a/roms/skiboot/core/test/run-trace.c
++++ b/roms/skiboot/core/test/run-trace.c
+@@ -178,6 +178,10 @@ static void test_parallel(void)
+ 	i = (CPUS*len + getpagesize()-1)&~(getpagesize()-1);
+ 	p = mmap(NULL, i, PROT_READ|PROT_WRITE,
+ 		 MAP_ANONYMOUS|MAP_SHARED, -1, 0);
++	if (p == MAP_FAILED) {
++		perror("test_parallel: cannot mmap");
++		exit(-1);
++	}
+ 
+ 	for (i = 0; i < CPUS; i++) {
+ 		fake_cpus[i].trace = p + i * len;
+diff --git a/roms/skiboot/external/ffspart/ffspart.c b/roms/skiboot/external/ffspart/ffspart.c
+index 7703477..efbbd5b 100644
+--- a/roms/skiboot/external/ffspart/ffspart.c
++++ b/roms/skiboot/external/ffspart/ffspart.c
+@@ -379,7 +379,7 @@ int main(int argc, char *argv[])
+ 			}
+ 
+ 			data_ptr = mmap(NULL, pactual, PROT_READ, MAP_SHARED, data_fd, 0);
+-			if (!data_ptr) {
++			if (data_ptr == MAP_FAILED) {
+ 				fprintf(stderr, "Couldn't mmap data file for partition '%s': %s\n",
+ 						name, strerror(errno));
+ 				rc = -1;
+diff --git a/roms/skiboot/extract-gcov.c b/roms/skiboot/extract-gcov.c
+index 3d31d1b..ebc03e6 100644
+--- a/roms/skiboot/extract-gcov.c
++++ b/roms/skiboot/extract-gcov.c
+@@ -229,7 +229,11 @@ int main(int argc, char *argv[])
+ 	}
+ 
+ 	addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+-	assert(addr != NULL);
++	assert(addr != MAP_FAILED);
++	if (addr == MAP_FAILED) {
++		perror("main: cannot mmap");
++		exit(-1);
++	}
+ 	skiboot_dump_size = sb.st_size;
+ 
+ 	printf("Skiboot memory dump %p - %p\n",
+diff --git a/roms/skiboot/libstb/create-container.c b/roms/skiboot/libstb/create-container.c
+index 5cf80a0..64699ad 100644
+--- a/roms/skiboot/libstb/create-container.c
++++ b/roms/skiboot/libstb/create-container.c
+@@ -96,7 +96,11 @@ void getSigRaw(ecc_signature_t *sigraw, char *inFile)
+ 	assert(r==0);
+ 
+ 	infile = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fdin, 0);
+-	assert(infile);
++	assert(infile != MAP_FAILED);
++	if (infile == MAP_FAILED) {
++		perror("getSigRaw: cannot mmap");
++		exit(-1);
++	}
+ 
+ 	signature = d2i_ECDSA_SIG(NULL, (const unsigned char **) &infile, 7 + 2*EC_COORDBYTES);
+ 
+@@ -356,7 +360,11 @@ int main(int argc, char* argv[])
+ 	r = fstat(fdin, &s);
+ 	assert(r==0);
+ 	infile = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fdin, 0);
+-	assert(infile);
++	assert(infile != MAP_FAILED);
++	if (infile == MAP_FAILED) {
++		perror("main: cannot mmap");
++		exit(-1);
++	}
+ 	fdout = open(params.imagefn, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ 	assert(fdout > 0);
+ 
+diff --git a/tests/tcg/multiarch/test-mmap.c b/tests/tcg/multiarch/test-mmap.c
+index 11d0e77..14f5919 100644
+--- a/tests/tcg/multiarch/test-mmap.c
++++ b/tests/tcg/multiarch/test-mmap.c
+@@ -203,6 +203,7 @@ void check_aligned_anonymous_fixed_mmaps(void)
+ 		p1 = mmap(addr, pagesize, PROT_READ, 
+ 			  MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
+ 			  -1, 0);
++		fail_unless (p1 != MAP_FAILED);
+ 		/* Make sure we get pages aligned with the pagesize. 
+ 		   The target expects this.  */
+ 		p = (uintptr_t) p1;
+@@ -234,6 +235,7 @@ void check_aligned_anonymous_fixed_mmaps_collide_with_host(void)
+ 		p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE, 
+ 			  MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
+ 			  -1, 0);
++		fail_unless (p1 != MAP_FAILED);
+ 		/* Make sure we get pages aligned with the pagesize. 
+ 		   The target expects this.  */
+ 		p = (uintptr_t) p1;
+@@ -401,6 +403,10 @@ void check_file_fixed_mmaps(void)
+ 		p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ, 
+ 			  MAP_PRIVATE | MAP_FIXED,
+ 			  test_fd, pagesize * 3);
++		fail_unless (p1 != MAP_FAILED);
++		fail_unless (p2 != MAP_FAILED);
++		fail_unless (p3 != MAP_FAILED);
++		fail_unless (p4 != MAP_FAILED);
+ 
+ 		/* Make sure we get pages aligned with the pagesize. 
+ 		   The target expects this.  */
+