From 8197e9b2e44158e65fd778149919e7229c7099c1 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 19 Apr 2020 16:42:40 +0200 Subject: clang-tidy readability-braces (#323) --- src/afl-fuzz-init.c | 440 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 300 insertions(+), 140 deletions(-) (limited to 'src/afl-fuzz-init.c') diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 3da348d2..4dd31ac9 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -42,7 +42,7 @@ void bind_to_free_cpu(afl_state_t *afl) { u8 cpu_used[4096] = {0}; u32 i; - if (afl->cpu_core_count < 2) return; + if (afl->cpu_core_count < 2) { return; } if (afl->afl_env.afl_no_affinity) { @@ -82,7 +82,7 @@ void bind_to_free_cpu(afl_state_t *afl) { u8 tmp[MAX_LINE]; u8 has_vmsize = 0; - if (!isdigit(de->d_name[0])) continue; + if (!isdigit(de->d_name[0])) { continue; } snprintf(fn, PATH_MAX, "/proc/%s/status", de->d_name); @@ -94,7 +94,7 @@ void bind_to_free_cpu(afl_state_t *afl) { /* Processes without VmSize are probably kernel tasks. */ - if (!strncmp(tmp, "VmSize:\t", 8)) has_vmsize = 1; + if (!strncmp(tmp, "VmSize:\t", 8)) { has_vmsize = 1; } if (!strncmp(tmp, "Cpus_allowed_list:\t", 19) && !strchr(tmp, '-') && !strchr(tmp, ',') && sscanf(tmp + 19, "%u", &hval) == 1 && @@ -190,8 +190,12 @@ void bind_to_free_cpu(afl_state_t *afl) { try: #ifndef __ANDROID__ - for (i = cpu_start; i < afl->cpu_core_count; i++) - if (!cpu_used[i]) break; + for (i = cpu_start; i < afl->cpu_core_count; i++) { + + if (!cpu_used[i]) { break; } + + } + if (i == afl->cpu_core_count) { #else @@ -229,8 +233,12 @@ void bind_to_free_cpu(afl_state_t *afl) { #if defined(__linux__) if (sched_setaffinity(0, sizeof(c), &c)) { - if (cpu_start == afl->cpu_core_count) + if (cpu_start == afl->cpu_core_count) { + PFATAL("sched_setaffinity failed for CPU %d, exit", i); + + } + WARNF("sched_setaffinity failed to CPU %d, trying next CPU", i); cpu_start++; goto try @@ -282,30 +290,37 @@ void setup_post(afl_state_t *afl) { u32 tlen = 6; strncpy(tbuf, "hello", tlen); - if (!fn) return; + if (!fn) { return; } ACTF("Loading postprocessor from '%s'...", fn); dh = dlopen(fn, RTLD_NOW); - if (!dh) FATAL("%s", dlerror()); + if (!dh) { FATAL("%s", dlerror()); } afl->post_handler = dlsym(dh, "afl_postprocess"); - if (!afl->post_handler) FATAL("Symbol 'afl_postprocess' not found."); + if (!afl->post_handler) { FATAL("Symbol 'afl_postprocess' not found."); } afl->post_init = dlsym(dh, "afl_postprocess_init"); - if (!afl->post_init) FATAL("Symbol 'afl_postprocess_init' not found."); + if (!afl->post_init) { FATAL("Symbol 'afl_postprocess_init' not found."); } afl->post_deinit = dlsym(dh, "afl_postprocess_deinit"); - if (!afl->post_deinit) FATAL("Symbol 'afl_postprocess_deinit' not found."); + if (!afl->post_deinit) { + + FATAL("Symbol 'afl_postprocess_deinit' not found."); + + } /* Do a quick test. It's better to segfault now than later =) */ u8 *post_buf = NULL; afl->post_data = afl->post_init(afl); - if (!afl->post_data) FATAL("Could not initialize post handler."); + if (!afl->post_data) { FATAL("Could not initialize post handler."); } size_t post_len = afl->post_handler(afl->post_data, tbuf, tlen, &post_buf); - if (!post_len || !post_buf) + if (!post_len || !post_buf) { + SAYF("Empty return in test post handler for buf=\"hello\\0\"."); + } + OKF("Postprocessor installed successfully."); } @@ -342,11 +357,16 @@ void read_testcases(afl_state_t *afl) { /* Auto-detect non-in-place resumption attempts. */ fn1 = alloc_printf("%s/queue", afl->in_dir); - if (!access(fn1, F_OK)) + if (!access(fn1, F_OK)) { + afl->in_dir = fn1; - else + + } else { + ck_free(fn1); + } + ACTF("Scanning '%s'...", afl->in_dir); /* We use scandir() + alphasort() rather than readdir() because otherwise, @@ -357,7 +377,7 @@ void read_testcases(afl_state_t *afl) { if (nl_cnt < 0) { - if (errno == ENOENT || errno == ENOTDIR) + if (errno == ENOENT || errno == ENOTDIR) { SAYF("\n" cLRD "[-] " cRST "The input directory does not seem to be valid - try again. The " @@ -368,6 +388,8 @@ void read_testcases(afl_state_t *afl) { "the input\n" " directory.\n"); + } + PFATAL("Unable to open '%s'", afl->in_dir); } @@ -392,9 +414,12 @@ void read_testcases(afl_state_t *afl) { free(nl[i]); /* not tracked */ - if (lstat(fn2, &st) || access(fn2, R_OK)) + if (lstat(fn2, &st) || access(fn2, R_OK)) { + PFATAL("Unable to access '%s'", fn2); + } + /* This also takes care of . and .. */ if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) { @@ -404,17 +429,20 @@ void read_testcases(afl_state_t *afl) { } - if (st.st_size > MAX_FILE) + if (st.st_size > MAX_FILE) { + FATAL("Test case '%s' is too big (%s, limit is %s)", fn2, stringify_mem_size(val_buf[0], sizeof(val_buf[0]), st.st_size), stringify_mem_size(val_buf[1], sizeof(val_buf[1]), MAX_FILE)); + } + /* Check for metadata that indicates that deterministic fuzzing is complete for this entry. We don't want to repeat deterministic fuzzing when resuming aborted scans, because it would be pointless and probably very time-consuming. */ - if (!access(dfn, F_OK)) passed_det = 1; + if (!access(dfn, F_OK)) { passed_det = 1; } add_to_queue(afl, fn2, st.st_size, passed_det); @@ -462,29 +490,35 @@ void perform_dry_run(afl_state_t *afl) { ACTF("Attempting dry run with '%s'...", fn); fd = open(q->fname, O_RDONLY); - if (fd < 0) PFATAL("Unable to open '%s'", q->fname); + if (fd < 0) { PFATAL("Unable to open '%s'", q->fname); } use_mem = ck_alloc_nozero(q->len); - if (read(fd, use_mem, q->len) != q->len) + if (read(fd, use_mem, q->len) != q->len) { + FATAL("Short read from '%s'", q->fname); + } + close(fd); res = calibrate_case(afl, q, use_mem, 0, 1); ck_free(use_mem); - if (afl->stop_soon) return; + if (afl->stop_soon) { return; } + + if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) { - if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) SAYF(cGRA " len = %u, map size = %u, exec speed = %llu us\n" cRST, q->len, q->bitmap_size, q->exec_us); + } + switch (res) { case FSRV_RUN_OK: - if (afl->crash_mode) FATAL("Test case '%s' does *NOT* crash", fn); + if (afl->crash_mode) { FATAL("Test case '%s' does *NOT* crash", fn); } break; @@ -539,7 +573,7 @@ void perform_dry_run(afl_state_t *afl) { case FSRV_RUN_CRASH: - if (afl->crash_mode) break; + if (afl->crash_mode) { break; } if (skip_crashes) { @@ -635,20 +669,28 @@ void perform_dry_run(afl_state_t *afl) { FATAL("Unable to execute target application ('%s')", afl->argv[0]); - case FSRV_RUN_NOINST: FATAL("No instrumentation detected"); + case FSRV_RUN_NOINST: + FATAL("No instrumentation detected"); case FSRV_RUN_NOBITS: ++afl->useless_at_start; - if (!afl->in_bitmap && !afl->shuffle_queue) + if (!afl->in_bitmap && !afl->shuffle_queue) { + WARNF("No new instrumentation output, test case may be useless."); + } + break; } - if (q->var_behavior) WARNF("Instrumentation output varies across runs."); + if (q->var_behavior) { + + WARNF("Instrumentation output varies across runs."); + + } q = q->next; @@ -656,17 +698,23 @@ void perform_dry_run(afl_state_t *afl) { if (cal_failures) { - if (cal_failures == afl->queued_paths) + if (cal_failures == afl->queued_paths) { + FATAL("All test cases time out%s, giving up!", skip_crashes ? " or crash" : ""); + } + WARNF("Skipped %u test cases (%0.02f%%) due to timeouts%s.", cal_failures, ((double)cal_failures) * 100 / afl->queued_paths, skip_crashes ? " or crashes" : ""); - if (cal_failures * 5 > afl->queued_paths) + if (cal_failures * 5 > afl->queued_paths) { + WARNF(cLRD "High percentage of rejected test cases, check settings!"); + } + } OKF("All test cases processed."); @@ -681,20 +729,23 @@ static void link_or_copy(u8 *old_path, u8 *new_path) { s32 sfd, dfd; u8 *tmp; - if (!i) return; + if (!i) { return; } sfd = open(old_path, O_RDONLY); - if (sfd < 0) PFATAL("Unable to open '%s'", old_path); + if (sfd < 0) { PFATAL("Unable to open '%s'", old_path); } dfd = open(new_path, O_WRONLY | O_CREAT | O_EXCL, 0600); - if (dfd < 0) PFATAL("Unable to create '%s'", new_path); + if (dfd < 0) { PFATAL("Unable to create '%s'", new_path); } tmp = ck_alloc(64 * 1024); - while ((i = read(sfd, tmp, 64 * 1024)) > 0) + while ((i = read(sfd, tmp, 64 * 1024)) > 0) { + ck_write(dfd, tmp, i, new_path); - if (i < 0) PFATAL("read() failed"); + } + + if (i < 0) { PFATAL("read() failed"); } ck_free(tmp); close(sfd); @@ -717,11 +768,16 @@ void pivot_inputs(afl_state_t *afl) { u8 *nfn, *rsl = strrchr(q->fname, '/'); u32 orig_id; - if (!rsl) + if (!rsl) { + rsl = q->fname; - else + + } else { + ++rsl; + } + /* If the original file name conforms to the syntax and the recorded ID matches the one we'd assign, just use the original file name. This is valuable for resuming fuzzing runs. */ @@ -743,11 +799,15 @@ void pivot_inputs(afl_state_t *afl) { if (src_str && sscanf(src_str + 1, "%06u", &src_id) == 1) { struct queue_entry *s = afl->queue; - while (src_id-- && s) + while (src_id-- && s) { + s = s->next; - if (s) q->depth = s->depth + 1; - if (afl->max_depth < q->depth) afl->max_depth = q->depth; + } + + if (s) { q->depth = s->depth + 1; } + + if (afl->max_depth < q->depth) { afl->max_depth = q->depth; } } @@ -760,10 +820,16 @@ void pivot_inputs(afl_state_t *afl) { u8 *use_name = strstr(rsl, ",orig:"); - if (use_name) + if (use_name) { + use_name += 6; - else + + } else { + use_name = rsl; + + } + nfn = alloc_printf("%s/queue/id:%06u,time:0,orig:%s", afl->out_dir, id, use_name); @@ -783,14 +849,14 @@ void pivot_inputs(afl_state_t *afl) { /* Make sure that the passed_det value carries over, too. */ - if (q->passed_det) mark_as_det_done(afl, q); + if (q->passed_det) { mark_as_det_done(afl, q); } q = q->next; ++id; } - if (afl->in_place_resume) nuke_resume_dir(afl); + if (afl->in_place_resume) { nuke_resume_dir(afl); } } @@ -805,27 +871,32 @@ u32 find_start_position(afl_state_t *afl) { s32 fd, i; u32 ret; - if (!afl->resuming_fuzz) return 0; + if (!afl->resuming_fuzz) { return 0; } + + if (afl->in_place_resume) { - if (afl->in_place_resume) fn = alloc_printf("%s/fuzzer_stats", afl->out_dir); - else + + } else { + fn = alloc_printf("%s/../fuzzer_stats", afl->in_dir); + } + fd = open(fn, O_RDONLY); ck_free(fn); - if (fd < 0) return 0; + if (fd < 0) { return 0; } i = read(fd, tmp, sizeof(tmp) - 1); (void)i; /* Ignore errors */ close(fd); off = strstr(tmp, "cur_path : "); - if (!off) return 0; + if (!off) { return 0; } ret = atoi(off + 20); - if (ret >= afl->queued_paths) ret = 0; + if (ret >= afl->queued_paths) { ret = 0; } return ret; } @@ -842,27 +913,32 @@ void find_timeout(afl_state_t *afl) { s32 fd, i; u32 ret; - if (!afl->resuming_fuzz) return; + if (!afl->resuming_fuzz) { return; } + + if (afl->in_place_resume) { - if (afl->in_place_resume) fn = alloc_printf("%s/fuzzer_stats", afl->out_dir); - else + + } else { + fn = alloc_printf("%s/../fuzzer_stats", afl->in_dir); + } + fd = open(fn, O_RDONLY); ck_free(fn); - if (fd < 0) return; + if (fd < 0) { return; } i = read(fd, tmp, sizeof(tmp) - 1); (void)i; /* Ignore errors */ close(fd); off = strstr(tmp, "exec_timeout : "); - if (!off) return; + if (!off) { return; } ret = atoi(off + 20); - if (ret <= 4) return; + if (ret <= 4) { return; } afl->fsrv.exec_tmout = ret; afl->timeout_given = 3; @@ -879,7 +955,7 @@ static u8 delete_files(u8 *path, u8 *prefix) { d = opendir(path); - if (!d) return 0; + if (!d) { return 0; } while ((d_ent = readdir(d))) { @@ -887,7 +963,7 @@ static u8 delete_files(u8 *path, u8 *prefix) { (!prefix || !strncmp(d_ent->d_name, prefix, strlen(prefix)))) { u8 *fname = alloc_printf("%s/%s", path, d_ent->d_name); - if (unlink(fname)) PFATAL("Unable to delete '%s'", fname); + if (unlink(fname)) { PFATAL("Unable to delete '%s'", fname); } ck_free(fname); } @@ -925,14 +1001,17 @@ double get_runnable_processes(void) { u8 tmp[1024]; u32 val = 0; - if (!f) return 0; + if (!f) { return 0; } while (fgets(tmp, sizeof(tmp), f)) { if (!strncmp(tmp, "procs_running ", 14) || - !strncmp(tmp, "procs_blocked ", 14)) + !strncmp(tmp, "procs_blocked ", 14)) { + val += atoi(tmp + 14); + } + } fclose(f); @@ -961,27 +1040,27 @@ void nuke_resume_dir(afl_state_t *afl) { u8 *fn; fn = alloc_printf("%s/_resume/.state/deterministic_done", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/_resume/.state/auto_extras", afl->out_dir); - if (delete_files(fn, "auto_")) goto dir_cleanup_failed; + if (delete_files(fn, "auto_")) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/_resume/.state/redundant_edges", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/_resume/.state/variable_behavior", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/_resume/.state", afl->out_dir); - if (rmdir(fn) && errno != ENOENT) goto dir_cleanup_failed; + if (rmdir(fn) && errno != ENOENT) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/_resume", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); return; @@ -1006,7 +1085,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { (this requires leaving the descriptor open).*/ afl->fsrv.out_dir_fd = open(afl->out_dir, O_RDONLY); - if (afl->fsrv.out_dir_fd < 0) PFATAL("Unable to open '%s'", afl->out_dir); + if (afl->fsrv.out_dir_fd < 0) { PFATAL("Unable to open '%s'", afl->out_dir); } #ifndef __sun @@ -1034,9 +1113,12 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (fscanf(f, "start_time : %llu\n" "last_update : %llu\n", - &start_time2, &last_update) != 2) + &start_time2, &last_update) != 2) { + FATAL("Malformed data in '%s'", fn); + } + fclose(f); /* Autoresume treats a normal run as in_place_resume if a valid out dir @@ -1110,7 +1192,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { if (!afl->in_place_resume) { fn = alloc_printf("%s/.synced", afl->out_dir); - if (delete_files(fn, NULL)) goto dir_cleanup_failed; + if (delete_files(fn, NULL)) { goto dir_cleanup_failed; } ck_free(fn); } @@ -1118,30 +1200,30 @@ static void handle_existing_out_dir(afl_state_t *afl) { /* Next, we need to clean up out_dir>/queue/.state/ subdirectories: */ fn = alloc_printf("%s/queue/.state/deterministic_done", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/queue/.state/auto_extras", afl->out_dir); - if (delete_files(fn, "auto_")) goto dir_cleanup_failed; + if (delete_files(fn, "auto_")) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/queue/.state/redundant_edges", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/queue/.state/variable_behavior", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); /* Then, get rid of the .state subdirectory itself (should be empty by now) and everything matching out_dir>/queue/id:*. */ fn = alloc_printf("%s/queue/.state", afl->out_dir); - if (rmdir(fn) && errno != ENOENT) goto dir_cleanup_failed; + if (rmdir(fn) && errno != ENOENT) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/queue", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); /* All right, let's do out_dir>/crashes/id:* and @@ -1184,7 +1266,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { } - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/hangs", afl->out_dir); @@ -1215,7 +1297,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { } - if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed; + if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } ck_free(fn); /* And now, for some finishing touches. */ @@ -1230,27 +1312,27 @@ static void handle_existing_out_dir(afl_state_t *afl) { } - if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed; + if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/fuzz_bitmap", afl->out_dir); - if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed; + if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; } ck_free(fn); if (!afl->in_place_resume) { fn = alloc_printf("%s/fuzzer_stats", afl->out_dir); - if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed; + if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; } ck_free(fn); } fn = alloc_printf("%s/plot_data", afl->out_dir); - if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed; + if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/cmdline", afl->out_dir); - if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed; + if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; } ck_free(fn); OKF("Output dir cleanup successful."); @@ -1287,28 +1369,37 @@ void setup_dirs_fds(afl_state_t *afl) { ACTF("Setting up output directories..."); - if (afl->sync_id && mkdir(afl->sync_dir, 0700) && errno != EEXIST) + if (afl->sync_id && mkdir(afl->sync_dir, 0700) && errno != EEXIST) { + PFATAL("Unable to create '%s'", afl->sync_dir); + } + if (mkdir(afl->out_dir, 0700)) { - if (errno != EEXIST) PFATAL("Unable to create '%s'", afl->out_dir); + if (errno != EEXIST) { PFATAL("Unable to create '%s'", afl->out_dir); } handle_existing_out_dir(afl); } else { - if (afl->in_place_resume) + if (afl->in_place_resume) { + FATAL("Resume attempted but old output directory not found"); + } + afl->fsrv.out_dir_fd = open(afl->out_dir, O_RDONLY); #ifndef __sun if (afl->fsrv.out_dir_fd < 0 || - flock(afl->fsrv.out_dir_fd, LOCK_EX | LOCK_NB)) + flock(afl->fsrv.out_dir_fd, LOCK_EX | LOCK_NB)) { + PFATAL("Unable to flock() output directory."); + } + #endif /* !__sun */ } @@ -1316,39 +1407,39 @@ void setup_dirs_fds(afl_state_t *afl) { /* Queue directory for any starting & discovered paths. */ tmp = alloc_printf("%s/queue", afl->out_dir); - if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); /* Top-level directory for queue metadata used for session resume and related tasks. */ tmp = alloc_printf("%s/queue/.state/", afl->out_dir); - if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); /* Directory for flagging queue entries that went through deterministic fuzzing in the past. */ tmp = alloc_printf("%s/queue/.state/deterministic_done/", afl->out_dir); - if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); /* Directory with the auto-selected dictionary entries. */ tmp = alloc_printf("%s/queue/.state/auto_extras/", afl->out_dir); - if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); /* The set of paths currently deemed redundant. */ tmp = alloc_printf("%s/queue/.state/redundant_edges/", afl->out_dir); - if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); /* The set of paths showing variable behavior. */ tmp = alloc_printf("%s/queue/.state/variable_behavior/", afl->out_dir); - if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); /* Sync directory for keeping track of cooperating fuzzers. */ @@ -1357,9 +1448,12 @@ void setup_dirs_fds(afl_state_t *afl) { tmp = alloc_printf("%s/.synced/", afl->out_dir); - if (mkdir(tmp, 0700) && (!afl->in_place_resume || errno != EEXIST)) + if (mkdir(tmp, 0700) && (!afl->in_place_resume || errno != EEXIST)) { + PFATAL("Unable to create '%s'", tmp); + } + ck_free(tmp); } @@ -1367,34 +1461,34 @@ void setup_dirs_fds(afl_state_t *afl) { /* All recorded crashes. */ tmp = alloc_printf("%s/crashes", afl->out_dir); - if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); /* All recorded hangs. */ tmp = alloc_printf("%s/hangs", afl->out_dir); - if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp); + if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); /* Generally useful file descriptors. */ afl->fsrv.dev_null_fd = open("/dev/null", O_RDWR); - if (afl->fsrv.dev_null_fd < 0) PFATAL("Unable to open /dev/null"); + if (afl->fsrv.dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); } #ifndef HAVE_ARC4RANDOM afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); - if (afl->fsrv.dev_urandom_fd < 0) PFATAL("Unable to open /dev/urandom"); + if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); } #endif /* Gnuplot output file. */ tmp = alloc_printf("%s/plot_data", afl->out_dir); fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600); - if (fd < 0) PFATAL("Unable to create '%s'", tmp); + if (fd < 0) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); afl->fsrv.plot_file = fdopen(fd, "w"); - if (!afl->fsrv.plot_file) PFATAL("fdopen() failed"); + if (!afl->fsrv.plot_file) { PFATAL("fdopen() failed"); } fprintf(afl->fsrv.plot_file, "# unix_time, cycles_done, cur_path, paths_total, " @@ -1417,11 +1511,11 @@ void setup_cmdline_file(afl_state_t *afl, char **argv) { /* Store the command line to reproduce our findings */ tmp = alloc_printf("%s/cmdline", afl->out_dir); fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600); - if (fd < 0) PFATAL("Unable to create '%s'", tmp); + if (fd < 0) { PFATAL("Unable to create '%s'", tmp); } ck_free(tmp); cmdline_file = fdopen(fd, "w"); - if (!cmdline_file) PFATAL("fdopen() failed"); + if (!cmdline_file) { PFATAL("fdopen() failed"); } while (argv[i]) { @@ -1453,7 +1547,7 @@ void setup_stdio_file(afl_state_t *afl) { afl->fsrv.out_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0600); - if (afl->fsrv.out_fd < 0) PFATAL("Unable to create '%s'", fn); + if (afl->fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", fn); } ck_free(fn); @@ -1501,7 +1595,7 @@ void check_crash_handling(void) { s32 fd = open("/proc/sys/kernel/core_pattern", O_RDONLY); u8 fchar; - if (fd < 0) return; + if (fd < 0) { return; } ACTF("Checking core_pattern..."); @@ -1524,9 +1618,12 @@ void check_crash_handling(void) { " echo core >/proc/sys/kernel/core_pattern\n"); - if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES")) + if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES")) { + FATAL("Pipe at the beginning of 'core_pattern'"); + } + } close(fd); @@ -1544,24 +1641,36 @@ void check_cpu_governor(afl_state_t *afl) { u8 tmp[128]; u64 min = 0, max = 0; - if (afl->afl_env.afl_skip_cpufreq) return; + if (afl->afl_env.afl_skip_cpufreq) { return; } + + if (afl->cpu_aff > 0) { - if (afl->cpu_aff > 0) snprintf(tmp, sizeof(tmp), "%s%d%s", "/sys/devices/system/cpu/cpu", afl->cpu_aff, "/cpufreq/scaling_governor"); - else + + } else { + snprintf(tmp, sizeof(tmp), "%s", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"); + + } + f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "r"); if (!f) { - if (afl->cpu_aff > 0) + if (afl->cpu_aff > 0) { + snprintf(tmp, sizeof(tmp), "%s%d%s", "/sys/devices/system/cpu/cpufreq/policy", afl->cpu_aff, "/scaling_governor"); - else + + } else { + snprintf(tmp, sizeof(tmp), "%s", "/sys/devices/system/cpu/cpufreq/policy0/scaling_governor"); + + } + f = fopen(tmp, "r"); } @@ -1575,17 +1684,17 @@ void check_cpu_governor(afl_state_t *afl) { ACTF("Checking CPU scaling governor..."); - if (!fgets(tmp, 128, f)) PFATAL("fgets() failed"); + if (!fgets(tmp, 128, f)) { PFATAL("fgets() failed"); } fclose(f); - if (!strncmp(tmp, "perf", 4)) return; + if (!strncmp(tmp, "perf", 4)) { return; } f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", "r"); if (f) { - if (fscanf(f, "%llu", &min) != 1) min = 0; + if (fscanf(f, "%llu", &min) != 1) { min = 0; } fclose(f); } @@ -1594,12 +1703,12 @@ void check_cpu_governor(afl_state_t *afl) { if (f) { - if (fscanf(f, "%llu", &max) != 1) max = 0; + if (fscanf(f, "%llu", &max) != 1) { max = 0; } fclose(f); } - if (min == max) return; + if (min == max) { return; } SAYF("\n" cLRD "[-] " cRST "Whoops, your system uses on-demand CPU frequency scaling, adjusted\n" @@ -1752,11 +1861,11 @@ void fix_up_sync(afl_state_t *afl) { u8 *x = afl->sync_id; - if (afl->dumb_mode) FATAL("-S / -M and -n are mutually exclusive"); + if (afl->dumb_mode) { FATAL("-S / -M and -n are mutually exclusive"); } if (afl->skip_deterministic) { - if (afl->force_deterministic) FATAL("use -S instead of -M -d"); + if (afl->force_deterministic) { FATAL("use -S instead of -M -d"); } // else // FATAL("-S already implies -d"); @@ -1764,14 +1873,17 @@ void fix_up_sync(afl_state_t *afl) { while (*x) { - if (!isalnum(*x) && *x != '_' && *x != '-') + if (!isalnum(*x) && *x != '_' && *x != '-') { + FATAL("Non-alphanumeric fuzzer ID specified via -S or -M"); + } + ++x; } - if (strlen(afl->sync_id) > 32) FATAL("Fuzzer ID too long"); + if (strlen(afl->sync_id) > 32) { FATAL("Fuzzer ID too long"); } x = alloc_printf("%s/%s", afl->out_dir, afl->sync_id); @@ -1803,25 +1915,37 @@ void check_asan_opts(void) { if (x) { - if (!strstr(x, "abort_on_error=1")) + if (!strstr(x, "abort_on_error=1")) { + FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!"); - if (!strstr(x, "symbolize=0")) + } + + if (!strstr(x, "symbolize=0")) { + FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); + } + } x = get_afl_env("MSAN_OPTIONS"); if (x) { - if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR))) + if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR))) { + FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY( MSAN_ERROR) " - please fix!"); - if (!strstr(x, "symbolize=0")) + } + + if (!strstr(x, "symbolize=0")) { + FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!"); + } + } } @@ -1868,9 +1992,12 @@ void check_binary(afl_state_t *afl, u8 *fname) { afl->fsrv.target_path = ck_strdup(fname); if (stat(afl->fsrv.target_path, &st) || !S_ISREG(st.st_mode) || - !(st.st_mode & 0111) || (f_len = st.st_size) < 4) + !(st.st_mode & 0111) || (f_len = st.st_size) < 4) { + FATAL("Program '%s' not found or not executable", fname); + } + } else { while (env_path) { @@ -1883,52 +2010,71 @@ void check_binary(afl_state_t *afl, u8 *fname) { memcpy(cur_elem, env_path, delim - env_path); ++delim; - } else + } else { cur_elem = ck_strdup(env_path); + } + env_path = delim; - if (cur_elem[0]) + if (cur_elem[0]) { + afl->fsrv.target_path = alloc_printf("%s/%s", cur_elem, fname); - else + + } else { + afl->fsrv.target_path = ck_strdup(fname); + } + ck_free(cur_elem); if (!stat(afl->fsrv.target_path, &st) && S_ISREG(st.st_mode) && - (st.st_mode & 0111) && (f_len = st.st_size) >= 4) + (st.st_mode & 0111) && (f_len = st.st_size) >= 4) { + break; + } + ck_free(afl->fsrv.target_path); afl->fsrv.target_path = 0; } - if (!afl->fsrv.target_path) + if (!afl->fsrv.target_path) { + FATAL("Program '%s' not found or not executable", fname); + } + } - if (afl->afl_env.afl_skip_bin_check || afl->use_wine) return; + if (afl->afl_env.afl_skip_bin_check || afl->use_wine) { return; } /* Check for blatant user errors. */ if ((!strncmp(afl->fsrv.target_path, "/tmp/", 5) && !strchr(afl->fsrv.target_path + 5, '/')) || (!strncmp(afl->fsrv.target_path, "/var/tmp/", 9) && - !strchr(afl->fsrv.target_path + 9, '/'))) + !strchr(afl->fsrv.target_path + 9, '/'))) { + FATAL("Please don't keep binaries in /tmp or /var/tmp"); + } + fd = open(afl->fsrv.target_path, O_RDONLY); - if (fd < 0) PFATAL("Unable to open '%s'", afl->fsrv.target_path); + if (fd < 0) { PFATAL("Unable to open '%s'", afl->fsrv.target_path); } f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0); - if (f_data == MAP_FAILED) + if (f_data == MAP_FAILED) { + PFATAL("Unable to mmap file '%s'", afl->fsrv.target_path); + } + close(fd); if (f_data[0] == '#' && f_data[1] == '!') { @@ -1955,9 +2101,12 @@ void check_binary(afl_state_t *afl, u8 *fname) { #ifndef __APPLE__ - if (f_data[0] != 0x7f || memcmp(f_data + 1, "ELF", 3)) + if (f_data[0] != 0x7f || memcmp(f_data + 1, "ELF", 3)) { + FATAL("Program '%s' is not an ELF binary", afl->fsrv.target_path); + } + #else #if !defined(__arm__) && !defined(__arm64__) @@ -2011,9 +2160,12 @@ void check_binary(afl_state_t *afl, u8 *fname) { } if (memmem(f_data, f_len, "__asan_init", 11) || - memmem(f_data, f_len, "__msan_init", 11)) + memmem(f_data, f_len, "__msan_init", 11)) { + afl->fsrv.uses_asan = 1; + } + /* Detect persistent & deferred init signatures in the binary. */ if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { @@ -2040,7 +2192,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if (munmap(f_data, f_len)) PFATAL("unmap() failed"); + if (munmap(f_data, f_len)) { PFATAL("unmap() failed"); } } @@ -2057,11 +2209,16 @@ void fix_up_banner(afl_state_t *afl, u8 *name) { } else { u8 *trim = strrchr(name, '/'); - if (!trim) + if (!trim) { + afl->use_banner = name; - else + + } else { + afl->use_banner = trim + 1; + } + } } @@ -2152,21 +2309,24 @@ void save_cmdline(afl_state_t *afl, u32 argc, char **argv) { u32 len = 1, i; u8 *buf; - for (i = 0; i < argc; ++i) + for (i = 0; i < argc; ++i) { + len += strlen(argv[i]) + 1; + } + buf = afl->orig_cmdline = ck_alloc(len); for (i = 0; i < argc; ++i) { u32 l = strlen(argv[i]); - if (!argv[i] || !buf) FATAL("null deref detected"); + if (!argv[i] || !buf) { FATAL("null deref detected"); } memcpy(buf, argv[i], l); buf += l; - if (i != argc - 1) *(buf++) = ' '; + if (i != argc - 1) { *(buf++) = ' '; } } -- cgit 1.4.1 From 66eee34709be9b91808601c7e3e638ffacb858db Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 26 Apr 2020 02:32:09 +0200 Subject: refactored global lists --- include/afl-fuzz.h | 13 ++++++++----- include/common.h | 2 +- src/afl-common.c | 2 +- src/afl-fuzz-init.c | 13 +++---------- src/afl-fuzz-state.c | 33 ++++++++++++++++++++++++++++++++- test/unittests/unit_list.c | 2 +- 6 files changed, 46 insertions(+), 19 deletions(-) (limited to 'src/afl-fuzz-init.c') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 428bfa8e..2203cfdf 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -614,11 +614,6 @@ typedef struct afl_state { } afl_state_t; -/* A global pointer to all instances is needed (for now) for signals to arrive - */ - -extern list_t afl_states; - struct custom_mutator { const char *name; @@ -800,6 +795,14 @@ struct custom_mutator { void afl_state_init(afl_state_t *, uint32_t map_size); void afl_state_deinit(afl_state_t *); + +/* Set stop_soon flag on all childs, kill all childs */ +void afl_states_stop(void); +/* Set clear_screen flag on all states */ +void afl_states_clear_screen(void); +/* Sets the skip flag on all states */ +void afl_states_request_skip(void); + void read_afl_environment(afl_state_t *, char **); /**** Prototypes ****/ diff --git a/include/common.h b/include/common.h index 70ff0744..4aed9572 100644 --- a/include/common.h +++ b/include/common.h @@ -115,7 +115,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms); u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms, volatile u8 *stop_soon_p); -u32 get_map_size(); +u32 get_map_size(void); #endif diff --git a/src/afl-common.c b/src/afl-common.c index 8ae03113..dda62219 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -918,7 +918,7 @@ u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms, } -u32 get_map_size() { +u32 get_map_size(void) { uint32_t map_size = MAP_SIZE; char * ptr; diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 4dd31ac9..32481887 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1903,7 +1903,7 @@ void fix_up_sync(afl_state_t *afl) { static void handle_resize(int sig) { - LIST_FOREACH(&afl_states, afl_state_t, { el->clear_screen = 1; }); + afl_states_clear_screen(); } @@ -1954,14 +1954,7 @@ void check_asan_opts(void) { static void handle_stop_sig(int sig) { - LIST_FOREACH(&afl_states, afl_state_t, { - - el->stop_soon = 1; - - if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, SIGKILL); - if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, SIGKILL); - - }); + afl_states_stop(); } @@ -1969,7 +1962,7 @@ static void handle_stop_sig(int sig) { static void handle_skipreq(int sig) { - LIST_FOREACH(&afl_states, afl_state_t, { el->skip_requested = 1; }); + afl_states_request_skip(); } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index af6fc11f..4f5389e3 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -71,7 +71,7 @@ static void init_mopt_globals(afl_state_t *afl) { /* A global pointer to all instances is needed (for now) for signals to arrive */ -list_t afl_states = {.element_prealloc_count = 0}; +static list_t afl_states = {.element_prealloc_count = 0}; /* Initializes an afl_state_t. */ @@ -398,3 +398,34 @@ void afl_state_deinit(afl_state_t *afl) { } +void afl_states_stop(void) { + + /* We may be inside a signal handler. + Set flags first, send kill signals to child proceses later. */ + LIST_FOREACH(&afl_states, afl_state_t, { + + el->stop_soon = 1; + + }); + + LIST_FOREACH(&afl_states, afl_state_t, { + + if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, SIGKILL); + if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, SIGKILL); + + }); + +} + +void afl_states_clear_screen(void) { + + LIST_FOREACH(&afl_states, afl_state_t, { el->clear_screen = 1; }); + +} + +void afl_states_request_skip(void) { + + LIST_FOREACH(&afl_states, afl_state_t, { el->skip_requested = 1; }); + +} + diff --git a/test/unittests/unit_list.c b/test/unittests/unit_list.c index 90700a11..df4864e4 100644 --- a/test/unittests/unit_list.c +++ b/test/unittests/unit_list.c @@ -40,7 +40,7 @@ int __wrap_printf(const char *format, ...) { return 1; } -list_t testlist; +static list_t testlist = {.element_prealloc_count = 0}; static void test_contains(void **state) { -- cgit 1.4.1