mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
if no master is present a slave becomes a temporary master
This commit is contained in:
@ -14,6 +14,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
- -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
|
||||
- If no master is present at sync time one slave automatically becomes
|
||||
a temporary master until a real master shows up
|
||||
- llvm_mode:
|
||||
- lowered minimum required llvm version to 3.4 (except LLVMInsTrim,
|
||||
which needs 3.8.0)
|
||||
|
@ -232,8 +232,8 @@ static void edit_params(int argc, char **argv) {
|
||||
|
||||
}
|
||||
|
||||
modified_file =
|
||||
alloc_printf("%s/.afl-%u-%u-%u.s", tmp_dir, (u32)getpid(), (u32)time(NULL), (u32)random());
|
||||
modified_file = alloc_printf("%s/.afl-%u-%u-%u.s", tmp_dir, (u32)getpid(),
|
||||
(u32)time(NULL), (u32)random());
|
||||
|
||||
wrap_things_up:
|
||||
|
||||
@ -592,8 +592,8 @@ int main(int argc, char **argv) {
|
||||
rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
|
||||
// in fast systems where pids can repeat in the same seconds we need this
|
||||
for (i = 1; i < argc; i++)
|
||||
for (j = 0; j < strlen(argv[i]); j++)
|
||||
rand_seed += argv[i][j];
|
||||
for (j = 0; j < strlen(argv[i]); j++)
|
||||
rand_seed += argv[i][j];
|
||||
|
||||
srandom(rand_seed);
|
||||
|
||||
|
@ -373,7 +373,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
DIR * sd;
|
||||
struct dirent *sd_ent;
|
||||
u32 sync_cnt = 0;
|
||||
u32 sync_cnt = 0, synced = 0, entries = 0;
|
||||
|
||||
sd = opendir(afl->sync_dir);
|
||||
if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); }
|
||||
@ -388,7 +388,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
DIR * qd;
|
||||
struct dirent *qd_ent;
|
||||
u8 * qd_path, *qd_synced_path;
|
||||
u8 qd_synced_path[PATH_MAX], qd_path[PATH_MAX];
|
||||
u32 min_accept = 0, next_min_accept;
|
||||
|
||||
s32 id_fd;
|
||||
@ -401,31 +401,41 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
entries++;
|
||||
|
||||
// a slave only syncs from a master, a master syncs from everyone
|
||||
if (likely(afl->is_slave)) {
|
||||
|
||||
u8 *x = alloc_printf("%s/%s/is_master", afl->sync_dir, sd_ent->d_name);
|
||||
int res = access(x, F_OK);
|
||||
free(x);
|
||||
if (likely(res != 0)) continue;
|
||||
sprintf(qd_path, "%s/%s/is_master", afl->sync_dir, sd_ent->d_name);
|
||||
int res = access(qd_path, F_OK);
|
||||
if (unlikely(afl->is_master)) { // an elected temporary master
|
||||
|
||||
if (likely(res == 0)) { // there is another master? downgrade.
|
||||
|
||||
afl->is_master = 0;
|
||||
sprintf(qd_path, "%s/is_master", afl->out_dir);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (likely(res != 0)) { continue; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
synced++;
|
||||
|
||||
/* Skip anything that doesn't have a queue/ subdirectory. */
|
||||
|
||||
qd_path = alloc_printf("%s/%s/queue", afl->sync_dir, sd_ent->d_name);
|
||||
sprintf(qd_path, "%s/%s/queue", afl->sync_dir, sd_ent->d_name);
|
||||
|
||||
if (!(qd = opendir(qd_path))) {
|
||||
|
||||
ck_free(qd_path);
|
||||
continue;
|
||||
|
||||
}
|
||||
if (!(qd = opendir(qd_path))) { continue; }
|
||||
|
||||
/* Retrieve the ID of the last seen test case. */
|
||||
|
||||
qd_synced_path =
|
||||
alloc_printf("%s/.synced/%s", afl->out_dir, sd_ent->d_name);
|
||||
sprintf(qd_synced_path, "%s/.synced/%s", afl->out_dir, sd_ent->d_name);
|
||||
|
||||
id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600);
|
||||
|
||||
@ -452,7 +462,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
while ((qd_ent = readdir(qd))) {
|
||||
|
||||
u8 * path;
|
||||
u8 path[PATH_MAX];
|
||||
s32 fd;
|
||||
struct stat st;
|
||||
|
||||
@ -472,18 +482,13 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
path = alloc_printf("%s/%s", qd_path, qd_ent->d_name);
|
||||
alloc_printf(path, "%s/%s", qd_path, qd_ent->d_name);
|
||||
|
||||
/* Allow this to fail in case the other fuzzer is resuming or so... */
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
|
||||
ck_free(path);
|
||||
continue;
|
||||
|
||||
}
|
||||
if (fd < 0) { continue; }
|
||||
|
||||
if (fstat(fd, &st)) { PFATAL("fstat() failed"); }
|
||||
|
||||
@ -516,7 +521,6 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
ck_free(path);
|
||||
close(fd);
|
||||
|
||||
}
|
||||
@ -526,13 +530,26 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
close_sync:
|
||||
close(id_fd);
|
||||
closedir(qd);
|
||||
ck_free(qd_path);
|
||||
ck_free(qd_synced_path);
|
||||
|
||||
}
|
||||
|
||||
closedir(sd);
|
||||
|
||||
// If we are a slave and no master was found to sync then become the master
|
||||
if (unlikely(synced == 0) && likely(entries) && likely(afl->is_slave)) {
|
||||
|
||||
// there is a small race condition here that another slave runs at the same
|
||||
// time. If so, the first temporary master running again will demote
|
||||
// themselves so this is not an issue
|
||||
|
||||
u8 path[PATH_MAX];
|
||||
afl->is_master = 1;
|
||||
sprintf(path, "%s/is_master", afl->out_dir);
|
||||
int fd = open(path, O_CREAT | O_RDWR, 0644);
|
||||
if (fd >= 0) { close(fd); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Trim all new test cases to save cycles when doing deterministic checks. The
|
||||
|
Reference in New Issue
Block a user