change: slaves only sync from masters

This commit is contained in:
van Hauser
2020-05-15 09:27:15 +02:00
parent 564399bd75
commit d536ddc240
9 changed files with 89 additions and 45 deletions

View File

@ -2,8 +2,6 @@
## Roadmap 2.65+ ## Roadmap 2.65+
- sync_fuzzers(): only masters sync from all, slaves only sync from master
(@andrea: be careful, often people run all slaves)
- AFL_MAP_SIZE for qemu_mode and unicorn_mode - AFL_MAP_SIZE for qemu_mode and unicorn_mode
- random crc32 HASH_CONST per run? because with 65536 paths we have collisions - random crc32 HASH_CONST per run? because with 65536 paths we have collisions
- namespace for targets? e.g. network - namespace for targets? e.g. network

View File

@ -9,8 +9,11 @@ Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>. sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++2.6d (dev) ### Version ++2.65d (dev)
- ... - afl-fuzz:
- -S slaves now only sync from the master to increase performance,
the -M master stilly syncs from everyone. Added checks that exactly
one master is present
### Version ++2.65c (release): ### Version ++2.65c (release):

View File

@ -57,12 +57,14 @@ Each fuzzer will keep its state in a separate subdirectory, like so:
Each instance will also periodically rescan the top-level sync directory Each instance will also periodically rescan the top-level sync directory
for any test cases found by other fuzzers - and will incorporate them into for any test cases found by other fuzzers - and will incorporate them into
its own fuzzing when they are deemed interesting enough. its own fuzzing when they are deemed interesting enough.
For performance reasons only -M masters sync the queue with everyone, the
-S slaves will only sync from the master.
The difference between the -M and -S modes is that the master instance will The difference between the -M and -S modes is that the master instance will
still perform deterministic checks; while the secondary instances will still perform deterministic checks; while the secondary instances will
proceed straight to random tweaks. If you don't want to do deterministic proceed straight to random tweaks.
fuzzing at all, it's OK to run all instances with -S. With very slow or complex
targets, or when running heavily parallelized jobs, this is usually a good plan. Note that you must always have one -M master instance!
Note that running multiple -M instances is wasteful, although there is an Note that running multiple -M instances is wasteful, although there is an
experimental support for parallelizing the deterministic checks. To leverage experimental support for parallelizing the deterministic checks. To leverage

View File

@ -913,6 +913,7 @@ u32 find_start_position(afl_state_t *);
void find_timeout(afl_state_t *); void find_timeout(afl_state_t *);
double get_runnable_processes(void); double get_runnable_processes(void);
void nuke_resume_dir(afl_state_t *); void nuke_resume_dir(afl_state_t *);
int check_master_exists(afl_state_t *);
void setup_dirs_fds(afl_state_t *); void setup_dirs_fds(afl_state_t *);
void setup_cmdline_file(afl_state_t *, char **); void setup_cmdline_file(afl_state_t *, char **);
void setup_stdio_file(afl_state_t *); void setup_stdio_file(afl_state_t *);

View File

@ -160,21 +160,23 @@ struct InsTrim : public ModulePass {
else else
#else #else
if (ngram_size_str) if (ngram_size_str)
#ifdef LLVM_VERSION_STRING #ifdef LLVM_VERSION_STRING
FATAL( FATAL(
"Sorry, NGRAM branch coverage is not supported with llvm version %s!", "Sorry, NGRAM branch coverage is not supported with llvm version %s!",
LLVM_VERSION_STRING); LLVM_VERSION_STRING);
#else #else
#ifndef LLVM_VERSION_PATCH #ifndef LLVM_VERSION_PATCH
FATAL( FATAL(
"Sorry, NGRAM branch coverage is not supported with llvm version %d.%d.%d!", "Sorry, NGRAM branch coverage is not supported with llvm version "
"%d.%d.%d!",
LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, 0); LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, 0);
#else #else
FATAL( FATAL(
"Sorry, NGRAM branch coverage is not supported with llvm version %d.%d.%d!", "Sorry, NGRAM branch coverage is not supported with llvm version "
"%d.%d.%d!",
LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERISON_PATCH); LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERISON_PATCH);
#endif #endif
#endif #endif
#endif #endif
PrevLocSize = 1; PrevLocSize = 1;

View File

@ -211,15 +211,17 @@ bool AFLCoverage::runOnModule(Module &M) {
else else
#else #else
if (ngram_size_str) if (ngram_size_str)
#ifndef LLVM_VERSION_PATCH #ifndef LLVM_VERSION_PATCH
FATAL("Sorry, NGRAM branch coverage is not supported with llvm version %d.%d.%d!", FATAL(
LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, "Sorry, NGRAM branch coverage is not supported with llvm version "
0); "%d.%d.%d!",
#else LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, 0);
FATAL("Sorry, NGRAM branch coverage is not supported with llvm version %d.%d.%d!", #else
LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, FATAL(
LLVM_VERSION_PATCH); "Sorry, NGRAM branch coverage is not supported with llvm version "
#endif "%d.%d.%d!",
LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH);
#endif
#endif #endif
PrevLocSize = 1; PrevLocSize = 1;

View File

@ -1315,6 +1315,36 @@ dir_cleanup_failed:
} }
/* If this is a -S slave, ensure a -M master is running */
int check_master_exists(afl_state_t *afl) {
DIR * sd;
struct dirent *sd_ent;
u8 * fn;
sd = opendir(afl->sync_dir);
if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); }
while ((sd_ent = readdir(sd))) {
/* Skip dot files and our own output directory. */
if (sd_ent->d_name[0] == '.' || !strcmp(afl->sync_id, sd_ent->d_name)) {
continue;
}
fn = alloc_printf("%s/%s/is_master", afl->sync_dir, sd_ent->d_name);
int res = access(fn, F_OK);
free(fn);
if (res == 0) return 1;
}
return 0;
}
/* Prepare output directories and fds. */ /* Prepare output directories and fds. */
void setup_dirs_fds(afl_state_t *afl) { void setup_dirs_fds(afl_state_t *afl) {
@ -1330,7 +1360,6 @@ void setup_dirs_fds(afl_state_t *afl) {
} }
/*
if (afl->is_master) { if (afl->is_master) {
u8 *x = alloc_printf("%s/%s/is_master", afl->sync_dir, afl->sync_id); u8 *x = alloc_printf("%s/%s/is_master", afl->sync_dir, afl->sync_id);
@ -1341,8 +1370,6 @@ void setup_dirs_fds(afl_state_t *afl) {
} }
*/
if (mkdir(afl->out_dir, 0700)) { 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); }

View File

@ -401,20 +401,16 @@ void sync_fuzzers(afl_state_t *afl) {
} }
/*
// a slave only syncs from a master, a master syncs from everyone // a slave only syncs from a master, a master syncs from everyone
if (likely(afl->is_slave)) { if (likely(afl->is_slave)) {
u8 x = alloc_printf("%s/%s/is_master", afl->sync_dir, sd_ent->d_name); u8 *x = alloc_printf("%s/%s/is_master", afl->sync_dir, sd_ent->d_name);
int res = access(x, F_OK); int res = access(x, F_OK);
free(x); free(x);
if (res != 0) if (likely(res != 0)) continue;
continue;
} }
*/
/* Skip anything that doesn't have a queue/ subdirectory. */ /* Skip anything that doesn't have a queue/ subdirectory. */
qd_path = alloc_printf("%s/%s/queue", afl->sync_dir, sd_ent->d_name); qd_path = alloc_printf("%s/%s/queue", afl->sync_dir, sd_ent->d_name);

View File

@ -1065,8 +1065,21 @@ int main(int argc, char **argv_orig, char **envp) {
init_count_class16(); init_count_class16();
if (afl->is_master && check_master_exists(afl) == 1) {
WARNF("It is wasteful to run more than one master!");
}
setup_dirs_fds(afl); setup_dirs_fds(afl);
if (afl->is_slave && check_master_exists(afl) == 0) {
WARNF("no -M master found. You need to run one master!");
sleep(5);
}
setup_custom_mutators(afl); setup_custom_mutators(afl);
setup_cmdline_file(afl, argv + optind); setup_cmdline_file(afl, argv + optind);