xref: /aosp_15_r20/external/AFLplusplus/utils/defork/defork.c (revision 08b48e0b10e97b33e7b60c5b6e2243bd915777f2)
1*08b48e0bSAndroid Build Coastguard Worker #define _GNU_SOURCE
2*08b48e0bSAndroid Build Coastguard Worker #include <dlfcn.h>
3*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
4*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
5*08b48e0bSAndroid Build Coastguard Worker #include <stdbool.h>
6*08b48e0bSAndroid Build Coastguard Worker 
7*08b48e0bSAndroid Build Coastguard Worker #include "../../include/config.h"
8*08b48e0bSAndroid Build Coastguard Worker #include "../../include/types.h"
9*08b48e0bSAndroid Build Coastguard Worker 
10*08b48e0bSAndroid Build Coastguard Worker /* we want to fork once (for the afl++ forkserver),
11*08b48e0bSAndroid Build Coastguard Worker    then immediately return as child on subsequent forks. */
12*08b48e0bSAndroid Build Coastguard Worker static bool forked = 0;
13*08b48e0bSAndroid Build Coastguard Worker 
14*08b48e0bSAndroid Build Coastguard Worker pid_t (*original_fork)(void);
15*08b48e0bSAndroid Build Coastguard Worker 
16*08b48e0bSAndroid Build Coastguard Worker /* In case we are not running in afl, we use a dummy original_fork */
nop(void)17*08b48e0bSAndroid Build Coastguard Worker static pid_t nop(void) {
18*08b48e0bSAndroid Build Coastguard Worker 
19*08b48e0bSAndroid Build Coastguard Worker   return 0;
20*08b48e0bSAndroid Build Coastguard Worker 
21*08b48e0bSAndroid Build Coastguard Worker }
22*08b48e0bSAndroid Build Coastguard Worker 
preeny_fork_orig()23*08b48e0bSAndroid Build Coastguard Worker __attribute__((constructor)) void preeny_fork_orig() {
24*08b48e0bSAndroid Build Coastguard Worker 
25*08b48e0bSAndroid Build Coastguard Worker   if (getenv(SHM_ENV_VAR)) {
26*08b48e0bSAndroid Build Coastguard Worker 
27*08b48e0bSAndroid Build Coastguard Worker     printf("defork: running in AFL++. Allowing forkserver.\n");
28*08b48e0bSAndroid Build Coastguard Worker     original_fork = dlsym(RTLD_NEXT, "socket");
29*08b48e0bSAndroid Build Coastguard Worker 
30*08b48e0bSAndroid Build Coastguard Worker   } else {
31*08b48e0bSAndroid Build Coastguard Worker 
32*08b48e0bSAndroid Build Coastguard Worker     printf("defork: no AFL++ detected. Disabling fork from the start.\n");
33*08b48e0bSAndroid Build Coastguard Worker     original_fork = &nop;
34*08b48e0bSAndroid Build Coastguard Worker 
35*08b48e0bSAndroid Build Coastguard Worker   }
36*08b48e0bSAndroid Build Coastguard Worker 
37*08b48e0bSAndroid Build Coastguard Worker }
38*08b48e0bSAndroid Build Coastguard Worker 
fork(void)39*08b48e0bSAndroid Build Coastguard Worker pid_t fork(void) {
40*08b48e0bSAndroid Build Coastguard Worker 
41*08b48e0bSAndroid Build Coastguard Worker   /* If we forked before, or if we're in the child (pid==0),
42*08b48e0bSAndroid Build Coastguard Worker     we don't want to fork anymore, else, we are still in the forkserver.
43*08b48e0bSAndroid Build Coastguard Worker     The forkserver parent needs to fork infinite times, each child should never
44*08b48e0bSAndroid Build Coastguard Worker     fork again. This can be written without branches and I hate myself for it.
45*08b48e0bSAndroid Build Coastguard Worker   */
46*08b48e0bSAndroid Build Coastguard Worker   pid_t ret = !forked && original_fork();
47*08b48e0bSAndroid Build Coastguard Worker   forked = !ret;
48*08b48e0bSAndroid Build Coastguard Worker   return ret;
49*08b48e0bSAndroid Build Coastguard Worker 
50*08b48e0bSAndroid Build Coastguard Worker }
51*08b48e0bSAndroid Build Coastguard Worker 
52