persistent mode: shared memory test case transfer

This commit is contained in:
van Hauser
2020-05-25 16:40:55 +02:00
parent 4c394a9d7b
commit 707145c491
13 changed files with 341 additions and 31 deletions

View File

@ -76,6 +76,8 @@ u8 __afl_area_initial[MAP_SIZE];
#endif
u8 *__afl_area_ptr = __afl_area_initial;
u8 *__afl_dictionary;
u8 *__afl_fuzz_ptr;
u32 __afl_fuzz_len;
u32 __afl_final_loc;
u32 __afl_map_size = MAP_SIZE;
@ -92,6 +94,8 @@ __thread u32 __afl_prev_ctx;
__thread u32 __afl_cmp_counter;
#endif
int __afl_sharedmem_fuzzing __attribute__((weak));
struct cmp_map *__afl_cmp_map;
/* Running in persistent mode? */
@ -109,6 +113,59 @@ void send_forkserver_error(int error) {
}
/* SHM fuzzing setup. */
static void __afl_map_shm_fuzz() {
char *id_str = getenv(SHM_FUZZ_ENV_VAR);
if (id_str) {
#ifdef USEMMAP
const char * shm_file_path = id_str;
int shm_fd = -1;
unsigned char *shm_base = NULL;
/* create the shared memory segment as if it was a file */
shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
if (shm_fd == -1) {
fprintf(stderr, "shm_open() failed for fuzz\n");
send_forkserver_error(FS_ERROR_SHM_OPEN);
exit(1);
}
__afl_fuzz_ptr = mmap(0, MAX_FILE, PROT_READ, MAP_SHARED, shm_fd, 0);
#else
u32 shm_id = atoi(id_str);
__afl_fuzz_ptr = shmat(shm_id, NULL, 0);
#endif
/* Whooooops. */
if (__afl_fuzz_ptr == (void *)-1) {
fprintf(stderr, "Error: could not access fuzzing shared memory\n");
exit(1);
}
if (getenv("AFL_DEBUG"))
fprintf(stderr, "DEBUG: successfully got fuzzing shared memory\n");
} else {
fprintf(stderr, "Error: variable for fuzzing shared memory is not set\n");
exit(1);
}
}
/* SHM setup. */
static void __afl_map_shm(void) {
@ -310,17 +367,25 @@ static void __afl_start_snapshots(void) {
assume we're not running in forkserver mode and just execute program. */
status |= (FS_OPT_ENABLED | FS_OPT_SNAPSHOT);
if (__afl_sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
if (__afl_dictionary_len > 0 && __afl_dictionary) status |= FS_OPT_AUTODICT;
if (__afl_dictionary_len && __afl_dictionary) status |= FS_OPT_AUTODICT;
memcpy(tmp, &status, 4);
if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
if (__afl_dictionary_len > 0 && __afl_dictionary) {
if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) {
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
if ((was_killed & (0xffffffff & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))) ==
(FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
__afl_map_shm_fuzz();
}
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_AUTODICT)) ==
(FS_OPT_ENABLED | FS_OPT_AUTODICT)) {
@ -357,7 +422,7 @@ static void __afl_start_snapshots(void) {
// uh this forkserver master does not understand extended option passing
// or does not want the dictionary
already_read_first = 1;
if (!__afl_fuzz_ptr) already_read_first = 1;
}
@ -378,6 +443,9 @@ static void __afl_start_snapshots(void) {
}
__afl_fuzz_len = (was_killed >> 8);
was_killed = (was_killed & 0xff);
/* If we stopped the child in persistent mode, but there was a race
condition and afl-fuzz already issued SIGKILL, write off the old
process. */
@ -473,7 +541,8 @@ static void __afl_start_forkserver(void) {
if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
if (__afl_dictionary_len > 0 && __afl_dictionary) status |= FS_OPT_AUTODICT;
if (__afl_dictionary_len && __afl_dictionary) status |= FS_OPT_AUTODICT;
if (__afl_sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
if (status) status |= (FS_OPT_ENABLED);
memcpy(tmp, &status, 4);
@ -482,10 +551,17 @@ static void __afl_start_forkserver(void) {
if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
if (__afl_dictionary_len > 0 && __afl_dictionary) {
if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) {
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) ==
(FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) {
__afl_map_shm_fuzz();
}
if ((was_killed & (FS_OPT_ENABLED | FS_OPT_AUTODICT)) ==
(FS_OPT_ENABLED | FS_OPT_AUTODICT)) {
@ -522,7 +598,7 @@ static void __afl_start_forkserver(void) {
// uh this forkserver master does not understand extended option passing
// or does not want the dictionary
already_read_first = 1;
if (!__afl_fuzz_ptr) already_read_first = 1;
}
@ -544,6 +620,9 @@ static void __afl_start_forkserver(void) {
}
__afl_fuzz_len = (was_killed >> 8);
was_killed = (was_killed & 0xff);
/* If we stopped the child in persistent mode, but there was a race
condition and afl-fuzz already issued SIGKILL, write off the old
process. */