I've been scouring the AFL++ and QEMU docs for a while and I can't seem to find an answer to this question: can you instruct QEMU-AFL (AFL++'s fork of QEMU, used when running afl-fuzz -Q
) to follow forks created in the process currently being fuzzed?
A very simple example would be a parent
binary and a child
binary (see code below). The parent
binary "fork + exec"s the child
binary, and the child binary reads a character from stdin
and crashes if it's equal to 'c'
. The crash is propagated to the parent
binary.
When I run this with afl-fuzz -i in/ -o out/ -Q -- ./parent
, I get:
last new find : none yet (odd, check syntax!)
which leads me to believe that AFL++ is not actually tracking coverage in the child process. Since it seems possible to do this with instrumented binaries, I assume the limitation is not in AFL++, but in QEMU-AFL. Is there a way to instruct QEMU-AFL (or QEMU for that matter) to follow forks?
Code for parent.c
:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
printf("Hello from the parent!\n");
pid_t new_pid = fork();
if (new_pid == 0) {
execve("./child", argv, NULL);
return 0;
}
// Wait for child to finish.
int child_retcode = 0;
while (wait(&child_retcode) > 0);
return child_retcode;
}
Code for child.c
:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
printf("Hello from the child!\n");
char c1 = getchar();
char c2 = getchar();
if (c1 == 'c') {
printf("Oh no, we're crashing!\n");
abort();
}
return 0;
}