mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-17 04:18:06 +00:00
afl-cmin/afl-cmin.bash/afl-showmap -i descend into subdirectories
This commit is contained in:
@ -31,6 +31,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
- afl_analyze:
|
- afl_analyze:
|
||||||
- fix timeout handling
|
- fix timeout handling
|
||||||
- add forkserver support for better performance
|
- add forkserver support for better performance
|
||||||
|
- afl-cmin, afl-cmin.bash and afl-showmap -i do now descend into
|
||||||
|
subdirectories (like afl-fuzz does)
|
||||||
- ensure afl-compiler-rt is built for gcc_module
|
- ensure afl-compiler-rt is built for gcc_module
|
||||||
|
|
||||||
### Version ++3.13c (release)
|
### Version ++3.13c (release)
|
||||||
|
@ -67,6 +67,8 @@ static char *stdin_file; /* stdin file */
|
|||||||
static u8 *in_dir = NULL, /* input folder */
|
static u8 *in_dir = NULL, /* input folder */
|
||||||
*out_file = NULL, *at_file = NULL; /* Substitution string for @@ */
|
*out_file = NULL, *at_file = NULL; /* Substitution string for @@ */
|
||||||
|
|
||||||
|
static u8 outfile[PATH_MAX];
|
||||||
|
|
||||||
static u8 *in_data, /* Input data */
|
static u8 *in_data, /* Input data */
|
||||||
*coverage_map; /* Coverage map */
|
*coverage_map; /* Coverage map */
|
||||||
|
|
||||||
@ -88,7 +90,8 @@ static bool quiet_mode, /* Hide non-essential messages? */
|
|||||||
have_coverage, /* have coverage? */
|
have_coverage, /* have coverage? */
|
||||||
no_classify, /* do not classify counts */
|
no_classify, /* do not classify counts */
|
||||||
debug, /* debug mode */
|
debug, /* debug mode */
|
||||||
print_filenames; /* print the current filename */
|
print_filenames, /* print the current filename */
|
||||||
|
wait_for_gdb;
|
||||||
|
|
||||||
static volatile u8 stop_soon, /* Ctrl-C pressed? */
|
static volatile u8 stop_soon, /* Ctrl-C pressed? */
|
||||||
child_crashed; /* Child crashed? */
|
child_crashed; /* Child crashed? */
|
||||||
@ -692,6 +695,93 @@ static void setup_signal_handlers(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 execute_testcases(u8 *dir) {
|
||||||
|
|
||||||
|
struct dirent **nl;
|
||||||
|
s32 nl_cnt, subdirs = 1;
|
||||||
|
u32 i, done = 0;
|
||||||
|
u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX];
|
||||||
|
|
||||||
|
if (!be_quiet) { ACTF("Scanning '%s'...", dir); }
|
||||||
|
|
||||||
|
/* We use scandir() + alphasort() rather than readdir() because otherwise,
|
||||||
|
the ordering of test cases would vary somewhat randomly and would be
|
||||||
|
difficult to control. */
|
||||||
|
|
||||||
|
nl_cnt = scandir(dir, &nl, NULL, alphasort);
|
||||||
|
|
||||||
|
if (nl_cnt < 0) { return 0; }
|
||||||
|
|
||||||
|
for (i = 0; i < (u32)nl_cnt; ++i) {
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
u8 *fn2 = alloc_printf("%s/%s", dir, nl[i]->d_name);
|
||||||
|
|
||||||
|
if (lstat(fn2, &st) || access(fn2, R_OK)) {
|
||||||
|
|
||||||
|
PFATAL("Unable to access '%s'", fn2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* obviously we want to skip "descending" into . and .. directories,
|
||||||
|
however it is a good idea to skip also directories that start with
|
||||||
|
a dot */
|
||||||
|
if (subdirs && S_ISDIR(st.st_mode) && nl[i]->d_name[0] != '.') {
|
||||||
|
|
||||||
|
free(nl[i]); /* not tracked */
|
||||||
|
done += execute_testcases(fn2);
|
||||||
|
ck_free(fn2);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
free(nl[i]);
|
||||||
|
|
||||||
|
if (!S_ISREG(st.st_mode) || !st.st_size) {
|
||||||
|
|
||||||
|
ck_free(fn2);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st.st_size > MAX_FILE && !be_quiet) {
|
||||||
|
|
||||||
|
WARNF("Test case '%s' is too big (%s, limit is %s), partial reading", 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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// DO
|
||||||
|
if (read_file(fn2)) {
|
||||||
|
|
||||||
|
if (wait_for_gdb) {
|
||||||
|
|
||||||
|
fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
|
||||||
|
fprintf(stderr, "exec: kill -CONT %d\n", getpid());
|
||||||
|
kill(0, SIGSTOP);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
showmap_run_target_forkserver(fsrv, in_data, in_len);
|
||||||
|
ck_free(in_data);
|
||||||
|
++done;
|
||||||
|
|
||||||
|
if (collect_coverage)
|
||||||
|
analyze_results(fsrv);
|
||||||
|
else
|
||||||
|
tcnt = write_results_to_file(fsrv, outfile);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
free(nl); /* not tracked */
|
||||||
|
return done;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Show banner. */
|
/* Show banner. */
|
||||||
|
|
||||||
static void show_banner(void) {
|
static void show_banner(void) {
|
||||||
@ -1136,15 +1226,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (in_dir) {
|
if (in_dir) {
|
||||||
|
|
||||||
DIR * dir_in, *dir_out = NULL;
|
DIR *dir_in, *dir_out = NULL;
|
||||||
struct dirent **file_list;
|
|
||||||
|
|
||||||
// int done = 0;
|
|
||||||
u8 infile[PATH_MAX], outfile[PATH_MAX];
|
|
||||||
u8 wait_for_gdb = 0;
|
|
||||||
#if !defined(DT_REG)
|
|
||||||
struct stat statbuf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true;
|
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true;
|
||||||
|
|
||||||
@ -1245,65 +1327,12 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
||||||
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
||||||
|
|
||||||
int file_count = scandir(in_dir, &file_list, NULL, alphasort);
|
if (execute_testcases(in_dir) == 0) {
|
||||||
if (file_count < 0) {
|
|
||||||
|
|
||||||
PFATAL("Failed to read from input dir at %s\n", in_dir);
|
FATAL("could not read input testcases from %s", in_dir);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < file_count; i++) {
|
|
||||||
|
|
||||||
struct dirent *dir_ent = file_list[i];
|
|
||||||
|
|
||||||
if (dir_ent->d_name[0] == '.') {
|
|
||||||
|
|
||||||
continue; // skip anything that starts with '.'
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DT_REG) /* Posix and Solaris do not know d_type and DT_REG */
|
|
||||||
if (dir_ent->d_type != DT_REG) {
|
|
||||||
|
|
||||||
continue; // only regular files
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
snprintf(infile, sizeof(infile), "%s/%s", in_dir, dir_ent->d_name);
|
|
||||||
|
|
||||||
#if !defined(DT_REG) /* use stat() */
|
|
||||||
if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!collect_coverage)
|
|
||||||
snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name);
|
|
||||||
|
|
||||||
if (read_file(infile)) {
|
|
||||||
|
|
||||||
if (wait_for_gdb) {
|
|
||||||
|
|
||||||
fprintf(stderr, "exec: gdb -p %d\n", fsrv->child_pid);
|
|
||||||
fprintf(stderr, "exec: kill -CONT %d\n", getpid());
|
|
||||||
kill(0, SIGSTOP);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
showmap_run_target_forkserver(fsrv, in_data, in_len);
|
|
||||||
ck_free(in_data);
|
|
||||||
if (collect_coverage)
|
|
||||||
analyze_results(fsrv);
|
|
||||||
else
|
|
||||||
tcnt = write_results_to_file(fsrv, outfile);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
free(file_list);
|
|
||||||
file_list = NULL;
|
|
||||||
|
|
||||||
if (!quiet_mode) { OKF("Processed %llu input files.", fsrv->total_execs); }
|
if (!quiet_mode) { OKF("Processed %llu input files.", fsrv->total_execs); }
|
||||||
|
|
||||||
if (dir_out) { closedir(dir_out); }
|
if (dir_out) { closedir(dir_out); }
|
||||||
|
Reference in New Issue
Block a user