diff options
author | Andrea Fioraldi <andreafioraldi@gmail.com> | 2020-12-08 22:43:05 +0100 |
---|---|---|
committer | Andrea Fioraldi <andreafioraldi@gmail.com> | 2020-12-08 22:43:05 +0100 |
commit | ad29eef2712f8d0b69c1acd79c6a5dfb4e2cc7f8 (patch) | |
tree | f74be06e8d1834ada6abe3daf40744e134cb9e3c /utils/defork/defork.c | |
parent | c70b7ffd80ee95cdf3bf1276bfbd4a590e74d3f1 (diff) | |
parent | 6fb74342b8a3e7aa62e9e0cfe79bd84d9076a275 (diff) | |
download | afl++-ad29eef2712f8d0b69c1acd79c6a5dfb4e2cc7f8.tar.gz |
Merge branch 'dev' of github.com:AFLplusplus/AFLplusplus into dev
Diffstat (limited to 'utils/defork/defork.c')
-rw-r--r-- | utils/defork/defork.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/utils/defork/defork.c b/utils/defork/defork.c new file mode 100644 index 00000000..f71d1124 --- /dev/null +++ b/utils/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; + +} + |