diff options
author | van Hauser <vh@thc.org> | 2020-08-03 13:39:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-03 13:39:55 +0200 |
commit | d5d8d664d0d4b95792aaccd16264f3a3cff48cc8 (patch) | |
tree | fa82a04acca16ea3e088b0d7d3aaec4b01ddf8f9 /examples/defork/defork.c | |
parent | 4a51cb71fb8785325dedac693cdea4648f6e5279 (diff) | |
parent | 409e4ae945ab5aeb31b1e3a1497ce5fc65226f07 (diff) | |
download | afl++-d5d8d664d0d4b95792aaccd16264f3a3cff48cc8.tar.gz |
Merge pull request #477 from AFLplusplus/dev
Push to stable
Diffstat (limited to 'examples/defork/defork.c')
-rw-r--r-- | examples/defork/defork.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/examples/defork/defork.c b/examples/defork/defork.c new file mode 100644 index 00000000..f71d1124 --- /dev/null +++ b/examples/defork/defork.c @@ -0,0 +1,50 @@ +#define __GNU_SOURCE +#include <dlfcn.h> +#include <unistd.h> +#include <stdio.h> +#include <stdbool.h> + +#include "../../include/config.h" + +/* we want to fork once (for the afl++ forkserver), + then immediately return as child on subsequent forks. */ +static bool forked = 0; + +pid_t (*original_fork)(void); + +/* In case we are not running in afl, we use a dummy original_fork */ +static pid_t nop(void) { + + return 0; + +} + +__attribute__((constructor)) void preeny_fork_orig() { + + if (getenv(SHM_ENV_VAR)) { + + printf("defork: running in AFL++. Allowing forkserver.\n"); + original_fork = dlsym(RTLD_NEXT, "socket"); + + } else { + + printf("defork: no AFL++ detected. Disabling fork from the start.\n"); + original_fork = &nop; + + } + +} + +pid_t fork(void) { + + /* If we forked before, or if we're in the child (pid==0), + we don't want to fork anymore, else, we are still in the forkserver. + The forkserver parent needs to fork infinite times, each child should never + fork again. This can be written without branches and I hate myself for it. + */ + pid_t ret = !forked && original_fork(); + forked = !ret; + return ret; + +} + |