diff options
| author | richinseattle@gmail.com <richinseattle@gmail.com> | 2021-03-18 01:37:40 -0700 |
|---|---|---|
| committer | richinseattle@gmail.com <richinseattle@gmail.com> | 2021-03-18 01:37:40 -0700 |
| commit | c397becd81229d71b55acf89a31710bead3707aa (patch) | |
| tree | 8306b59e88e22d7090fd786690227dacc99e24e3 /utils/defork/defork.c | |
| parent | 62508c3b446a893f0afead9a6d0546d53d588a13 (diff) | |
| parent | 94312796f936ba1830b61432a0f958e192dd212f (diff) | |
| download | afl++-c397becd81229d71b55acf89a31710bead3707aa.tar.gz | |
Merge branch 'dev' of https://github.com/AFLplusplus/AFLplusplus into dev
Diffstat (limited to 'utils/defork/defork.c')
| -rw-r--r-- | utils/defork/defork.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/utils/defork/defork.c b/utils/defork/defork.c new file mode 100644 index 00000000..c9be3283 --- /dev/null +++ b/utils/defork/defork.c @@ -0,0 +1,51 @@ +#define _GNU_SOURCE +#include <dlfcn.h> +#include <unistd.h> +#include <stdio.h> +#include <stdbool.h> + +#include "../../include/config.h" +#include "../../include/types.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; + +} + |
