mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-18 20:48:07 +00:00
Merge pull request #2412 from alexandredoyen29/environment_forkserver
Environment variable to discriminate the target and the forkserver
This commit is contained in:
@ -664,6 +664,24 @@ checks or alter some of the more exotic semantics of the tool:
|
|||||||
Note that will not be exact and with slow targets it can take seconds
|
Note that will not be exact and with slow targets it can take seconds
|
||||||
until there is a slice for the time test.
|
until there is a slice for the time test.
|
||||||
|
|
||||||
|
- When using `AFL_PRELOAD` with a preload that disable `fork()` calls in
|
||||||
|
the target, the forkserver becomes unable to fork.
|
||||||
|
To overcome this issue, the `AFL_PRELOAD_DISCRIMINATE_FORKSERVER_PARENT`
|
||||||
|
permits to be able to check in the preloaded library if the environment
|
||||||
|
variable `AFL_FORKSERVER_PARENT` is set, to be able to use vanilla
|
||||||
|
`fork()` in the forkserver, and the placeholder in the target.
|
||||||
|
Here is a POC :
|
||||||
|
```C
|
||||||
|
// AFL_PRELOAD_DISCRIMINATE_FORKSERVER_PARENT=1 afl-fuzz ...
|
||||||
|
pid_t fork(void)
|
||||||
|
{
|
||||||
|
if (getenv("AFL_FORKSERVER_PARENT") == NULL)
|
||||||
|
return 0; // We are in the target
|
||||||
|
else
|
||||||
|
return real_fork(); // We are in the forkserver
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 6) Settings for afl-qemu-trace
|
## 6) Settings for afl-qemu-trace
|
||||||
|
|
||||||
The QEMU wrapper used to instrument binary-only code supports several settings:
|
The QEMU wrapper used to instrument binary-only code supports several settings:
|
||||||
|
@ -118,7 +118,8 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_CFISAN_VERBOSE", "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT",
|
"AFL_CFISAN_VERBOSE", "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT",
|
||||||
"AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", "AFL_USE_QASAN",
|
"AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", "AFL_USE_QASAN",
|
||||||
"AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", "AFL_NO_FASTRESUME",
|
"AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", "AFL_NO_FASTRESUME",
|
||||||
"AFL_SAN_ABSTRACTION", "AFL_SAN_NO_INST", "AFL_SAN_RECOVER", NULL};
|
"AFL_SAN_ABSTRACTION", "AFL_SAN_NO_INST", "AFL_SAN_RECOVER",
|
||||||
|
"AFL_PRELOAD_DISCRIMINATE_FORKSERVER_PARENT", NULL};
|
||||||
|
|
||||||
extern char *afl_environment_variables[];
|
extern char *afl_environment_variables[];
|
||||||
|
|
||||||
|
@ -159,6 +159,8 @@ typedef struct afl_forkserver {
|
|||||||
|
|
||||||
u8 uses_asan; /* Target uses ASAN/LSAN/MSAN? (bit 0/1/2 respectively) */
|
u8 uses_asan; /* Target uses ASAN/LSAN/MSAN? (bit 0/1/2 respectively) */
|
||||||
|
|
||||||
|
bool setenv; /* setenv() to discriminate the forkserver? */
|
||||||
|
|
||||||
bool debug; /* debug mode? */
|
bool debug; /* debug mode? */
|
||||||
|
|
||||||
u8 san_but_not_instrumented; /* Is it sanitizer enabled but not instrumented?
|
u8 san_but_not_instrumented; /* Is it sanitizer enabled but not instrumented?
|
||||||
|
@ -119,6 +119,8 @@ u64 __afl_map_addr;
|
|||||||
u32 __afl_first_final_loc;
|
u32 __afl_first_final_loc;
|
||||||
u32 __afl_old_forkserver;
|
u32 __afl_old_forkserver;
|
||||||
|
|
||||||
|
u8 __afl_forkserver_setenv = 0;
|
||||||
|
|
||||||
#ifdef __AFL_CODE_COVERAGE
|
#ifdef __AFL_CODE_COVERAGE
|
||||||
typedef struct afl_module_info_t afl_module_info_t;
|
typedef struct afl_module_info_t afl_module_info_t;
|
||||||
|
|
||||||
@ -888,6 +890,12 @@ static void __afl_start_forkserver(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getenv("AFL_PRELOAD_DISCRIMINATE_FORKSERVER_PARENT") != NULL) {
|
||||||
|
|
||||||
|
__afl_forkserver_setenv = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Phone home and tell the parent that we're OK. If parent isn't there,
|
/* Phone home and tell the parent that we're OK. If parent isn't there,
|
||||||
assume we're not running in forkserver mode and just execute program. */
|
assume we're not running in forkserver mode and just execute program. */
|
||||||
|
|
||||||
@ -1054,6 +1062,13 @@ static void __afl_start_forkserver(void) {
|
|||||||
|
|
||||||
close(FORKSRV_FD);
|
close(FORKSRV_FD);
|
||||||
close(FORKSRV_FD + 1);
|
close(FORKSRV_FD + 1);
|
||||||
|
|
||||||
|
if (unlikely(__afl_forkserver_setenv)) {
|
||||||
|
|
||||||
|
unsetenv("AFL_FORKSERVER_PARENT");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -250,6 +250,16 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
|||||||
fsrv->child_kill_signal = SIGKILL;
|
fsrv->child_kill_signal = SIGKILL;
|
||||||
fsrv->max_length = MAX_FILE;
|
fsrv->max_length = MAX_FILE;
|
||||||
|
|
||||||
|
if (getenv("AFL_PRELOAD_DISCRIMINATE_FORKSERVER_PARENT") != NULL) {
|
||||||
|
|
||||||
|
fsrv->setenv = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
fsrv->setenv = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* exec related stuff */
|
/* exec related stuff */
|
||||||
fsrv->child_pid = -1;
|
fsrv->child_pid = -1;
|
||||||
fsrv->map_size = get_map_size();
|
fsrv->map_size = get_map_size();
|
||||||
@ -878,6 +888,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
/* CHILD PROCESS */
|
/* CHILD PROCESS */
|
||||||
|
|
||||||
|
if (unlikely(fsrv->setenv)) {
|
||||||
|
|
||||||
|
setenv("AFL_FORKSERVER_PARENT", "1", 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// enable terminating on sigpipe in the children
|
// enable terminating on sigpipe in the children
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
memset((char *)&sa, 0, sizeof(sa));
|
memset((char *)&sa, 0, sizeof(sa));
|
||||||
|
Reference in New Issue
Block a user