aboutsummaryrefslogtreecommitdiff
path: root/qemu_mode
diff options
context:
space:
mode:
authorAndrea Fioraldi <andreafioraldi@gmail.com>2020-06-03 09:57:44 +0200
committerAndrea Fioraldi <andreafioraldi@gmail.com>2020-06-03 09:57:44 +0200
commit9962de1a4c26d226b15d7bee64b483098fe62b3f (patch)
tree758ee7ec2730d0a7ee0f4e254404286b28f6a41a /qemu_mode
parent304a72c1ff84be6c4d217d2bc3f94884425e853e (diff)
downloadAFLplusplus-9962de1a4c26d226b15d7bee64b483098fe62b3f.tar.gz
shared mem input for qemu persistent hook
Diffstat (limited to 'qemu_mode')
-rw-r--r--qemu_mode/patches/afl-qemu-common.h9
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-inl.h82
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-translate-inl.h3
3 files changed, 80 insertions, 14 deletions
diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h
index 057e1b62..5812596a 100644
--- a/qemu_mode/patches/afl-qemu-common.h
+++ b/qemu_mode/patches/afl-qemu-common.h
@@ -63,7 +63,10 @@
#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 +84,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..dc18ea95 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,36 @@ 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);
+ shared_buf = shmat(shm_id, NULL, 0);
+
+ /* Whooooops. */
+
+ if (shared_buf == (void *)-1) {
+
+ fprintf(stderr, "[AFL] ERROR: could not access fuzzing shared memory\n");
+ exit(1);
+
+ }
+
+ 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");
@@ -247,6 +282,11 @@ void afl_setup(void) {
exit(1);
}
+
+ 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) {
@@ -262,7 +302,7 @@ void afl_setup(void) {
#endif
}
-
+
if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"))
persisent_retaddr_offset =
strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 0);
@@ -278,7 +318,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 +331,15 @@ void afl_forkserver(CPUState *cpu) {
pid_t child_pid;
int t_fd[2];
u8 child_stopped = 0;
+ u32 was_killed;
+ int status;
- // 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);
+ 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. */
@@ -309,17 +349,34 @@ void afl_forkserver(CPUState *cpu) {
afl_forksrv_pid = getpid();
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);
+
+ shared_buf_len = (was_killed >> 8);
+ was_killed = (was_killed & 0xff);
/* If we stopped the child in persistent mode, but there was a race
condition and afl-fuzz already issued SIGKILL, write off the old
@@ -402,6 +459,7 @@ void afl_forkserver(CPUState *cpu) {
}
+
/* A simplified persistent mode handler, used as explained in
* llvm_mode/README.md. */
diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
index 083c27e5..15d5c91c 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);
}