TL;DR Why process map in /proc/<pid>/maps
does not show where the executed binary is loaded?
I am trying to do some post-mortem analysis of the fuzzed program once it finishes.
Basically what I am seeing is that /proc/<pid>/maps
shows what looks to be the memory map of the parent instead of the child. I was unable to replicate the behavior on a smaller scale but I'll provide a patch to github.com/google/AFL. (Add an empty raw after the else
last row if patch fails)
diff --git a/afl-fuzz.c b/afl-fuzz.c
index 46a216c..e31125f 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -2283,6 +2283,14 @@ EXP_ST void init_forkserver(char** argv) {
}
+static void read_map(int pid, char *map) {
+ FILE *proc;
+ char path[50];
+ sprintf(path, "/proc/%d/maps", pid);
+ proc = fopen(path, "r");
+ fread(map, 4096, 1, proc);
+ fclose(proc);
+}
/* Execute target application, monitoring for timeouts. Return status
information. The called program will update trace_bits[]. */
@@ -2423,7 +2431,14 @@ static u8 run_target(char** argv, u32 timeout) {
if (dumb_mode == 1 || no_forkserver) {
- if (waitpid(child_pid, &status, 0) <= 0) PFATAL("waitpid() failed");
+ int res;
+ char map[4096];
+ while (!(res = waitpid(child_pid, &status, WNOHANG))) {
+ if (res < 0)
+ PFATAL("waitpid() failed");
+ read_map(child_pid, map);
+ }
+ printf("%s\n", map);
} else {
After applying the patch you can run the following to check things out
mkdir input output
echo "hello" > input/test1
./afl-fuzz -i input -o output -n -- /bin/ls
What you'll probably is the map for afl-fuzz
?
The patch is waiting for the execv
to finish while reading the /proc/<pid>/maps
, once it's finished prints the last map that was read.
I'm curious what I am missing in me reading the map or what triggers this. (Also I don't think this is regarding AFL itself is just where I've seen this, it would be nice to see a smaller program that replicates the behavior since I was unable to replicate it)