mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-09 16:51:34 +00:00
commit
7ca1b85c5e
1
TODO.md
1
TODO.md
@ -10,7 +10,6 @@
|
||||
- parallel builds for source-only targets
|
||||
- get rid of check_binary, replace with more forkserver communication
|
||||
- first fuzzer should be a main automatically? not sure.
|
||||
- reload fuzz binary on signal
|
||||
|
||||
## Maybe
|
||||
|
||||
|
145
afl-cmin
145
afl-cmin
@ -103,9 +103,10 @@ function usage() {
|
||||
" -o dir - output directory for minimized files\n" \
|
||||
"\n" \
|
||||
"Execution control settings:\n" \
|
||||
" -T tasks - how many parallel tasks to run (default: 1, all=nproc)\n" \
|
||||
" -f file - location read by the fuzzed program (stdin)\n" \
|
||||
" -m megs - memory limit for child process ("mem_limit" MB)\n" \
|
||||
" -t msec - run time limit for child process (default: none)\n" \
|
||||
" -t msec - run time limit for child process (default: 5000)\n" \
|
||||
" -O - use binary-only instrumentation (FRIDA mode)\n" \
|
||||
" -Q - use binary-only instrumentation (QEMU mode)\n" \
|
||||
" -U - use unicorn-based instrumentation (unicorn mode)\n" \
|
||||
@ -119,7 +120,6 @@ function usage() {
|
||||
"For additional tips, please consult README.md\n" \
|
||||
"\n" \
|
||||
"Environment variables used:\n" \
|
||||
"AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp\n" \
|
||||
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \
|
||||
"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \
|
||||
"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
|
||||
@ -159,13 +159,19 @@ BEGIN {
|
||||
# process options
|
||||
Opterr = 1 # default is to diagnose
|
||||
Optind = 1 # skip ARGV[0]
|
||||
while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUXY?")) != -1) {
|
||||
while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUXYT:?")) != -1) {
|
||||
if (_go_c == "i") {
|
||||
if (!Optarg) usage()
|
||||
if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||
in_dir = Optarg
|
||||
continue
|
||||
} else
|
||||
if (_go_c == "T") {
|
||||
if (!Optarg) usage()
|
||||
if (threads) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||
threads = Optarg
|
||||
continue
|
||||
} else
|
||||
if (_go_c == "o") {
|
||||
if (!Optarg) usage()
|
||||
if (out_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"}
|
||||
@ -234,7 +240,7 @@ BEGIN {
|
||||
} # while options
|
||||
|
||||
if (!mem_limit) mem_limit = "none"
|
||||
if (!timeout) timeout = "none"
|
||||
if (!timeout) timeout = "5000"
|
||||
|
||||
# get program args
|
||||
i = 0
|
||||
@ -253,21 +259,30 @@ BEGIN {
|
||||
# Do a sanity check to discourage the use of /tmp, since we can't really
|
||||
# handle this safely from an awk script.
|
||||
|
||||
if (!ENVIRON["AFL_ALLOW_TMP"]) {
|
||||
dirlist[0] = in_dir
|
||||
dirlist[1] = target_bin
|
||||
dirlist[2] = out_dir
|
||||
dirlist[3] = stdin_file
|
||||
"pwd" | getline dirlist[4] # current directory
|
||||
for (dirind in dirlist) {
|
||||
dir = dirlist[dirind]
|
||||
#if (!ENVIRON["AFL_ALLOW_TMP"]) {
|
||||
# dirlist[0] = in_dir
|
||||
# dirlist[1] = target_bin
|
||||
# dirlist[2] = out_dir
|
||||
# dirlist[3] = stdin_file
|
||||
# "pwd" | getline dirlist[4] # current directory
|
||||
# for (dirind in dirlist) {
|
||||
# dir = dirlist[dirind]
|
||||
#
|
||||
# if (dir ~ /^(\/var)?\/tmp/) {
|
||||
# print "[-] Error: do not use this script in /tmp or /var/tmp." > "/dev/stderr"
|
||||
# exit 1
|
||||
# }
|
||||
# }
|
||||
# delete dirlist
|
||||
#}
|
||||
|
||||
if (dir ~ /^(\/var)?\/tmp/) {
|
||||
print "[-] Error: do not use this script in /tmp or /var/tmp." > "/dev/stderr"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
delete dirlist
|
||||
if (threads && stdin_file) {
|
||||
print "[-] Error: -T and -f cannot be used together." > "/dev/stderr"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (!threads && !stdin_file && !nyx_mode) {
|
||||
print "[*] Are you aware of the '-T all' parallelize option that improves the speed for large/slow corpuses?"
|
||||
}
|
||||
|
||||
# If @@ is specified, but there's no -f, let's come up with a temporary input
|
||||
@ -350,6 +365,18 @@ BEGIN {
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (threads) {
|
||||
"nproc" | getline nproc
|
||||
if (threads == "all") {
|
||||
threads = nproc
|
||||
} else {
|
||||
if (!(threads > 1 && threads <= nproc)) {
|
||||
print "[-] Error: -T option must be between 1 and "nproc" or \"all\"." > "/dev/stderr"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Check for the more efficient way to copy files...
|
||||
if (0 != system("mkdir -p -m 0700 "trace_dir)) {
|
||||
print "[-] Error: Cannot create directory "trace_dir > "/dev/stderr"
|
||||
@ -459,27 +486,79 @@ BEGIN {
|
||||
# STEP 1: Collecting traces #
|
||||
#############################
|
||||
|
||||
if (threads) {
|
||||
|
||||
inputsperfile = in_count / threads
|
||||
if (in_count % threads) {
|
||||
inputsperfile++;
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
tmpfile=out_dir "/.filelist"
|
||||
for (instance = 1; instance < threads; instance++) {
|
||||
for (i = 0; i < inputsperfile; i++) {
|
||||
print in_dir"/"infilesSmallToBigFull[cnt] >> tmpfile"."instance
|
||||
cnt++
|
||||
}
|
||||
}
|
||||
for (; cnt < in_count; cnt++) {
|
||||
print in_dir"/"infilesSmallToBigFull[cnt] >> tmpfile"."threads
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
print "[*] Obtaining traces for "in_count" input files in '"in_dir"'."
|
||||
|
||||
cur = 0;
|
||||
if (!stdin_file) {
|
||||
print " Processing "in_count" files (forkserver mode)..."
|
||||
# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string
|
||||
retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string)
|
||||
} else {
|
||||
print " Processing "in_count" files (forkserver mode)..."
|
||||
# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null"
|
||||
retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null")
|
||||
}
|
||||
|
||||
if (retval && (!AFL_CMIN_CRASHES_ONLY && !AFL_CMIN_ALLOW_ANY)) {
|
||||
print "[!] Exit code "retval" != 0 received from afl-showmap (this means a crashing or timeout input is likely present), terminating..."
|
||||
if (threads > 1) {
|
||||
|
||||
if (!ENVIRON["AFL_KEEP_TRACES"]) {
|
||||
system("rm -rf "trace_dir" 2>/dev/null")
|
||||
system("rmdir "out_dir)
|
||||
print "[*] Creating " threads " parallel tasks with about " inputsperfile " each."
|
||||
for (i = 1; i <= threads; i++) {
|
||||
|
||||
if (!stdin_file) {
|
||||
# print " { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -- \""target_bin"\" "prog_args_string"; > "tmpfile"."i".done ; } &"
|
||||
retval = system(" { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -- \""target_bin"\" "prog_args_string"; > "tmpfile"."i".done ; } &")
|
||||
} else {
|
||||
stdin_file=tmpfile"."i".stdin"
|
||||
# print " { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null; > "tmpfile"."i".done ; } &"
|
||||
retval = system(" { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null; > "tmpfile"."i".done ; } &")
|
||||
}
|
||||
}
|
||||
exit retval
|
||||
print "[*] Waiting for parallel tasks to complete ..."
|
||||
# wait for all processes to finish
|
||||
ok=0
|
||||
while (ok < threads) {
|
||||
ok=0
|
||||
for (i = 1; i <= threads; i++) {
|
||||
if (system("test -f "tmpfile"."i".done") == 0) {
|
||||
ok++
|
||||
}
|
||||
}
|
||||
}
|
||||
print "[*] Done!"
|
||||
system("rm -f "tmpfile"*")
|
||||
} else {
|
||||
if (!stdin_file) {
|
||||
print " Processing "in_count" files (forkserver mode)..."
|
||||
# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string
|
||||
retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string)
|
||||
} else {
|
||||
print " Processing "in_count" files (forkserver mode)..."
|
||||
# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null"
|
||||
retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null")
|
||||
}
|
||||
|
||||
if (retval && (!AFL_CMIN_CRASHES_ONLY && !AFL_CMIN_ALLOW_ANY)) {
|
||||
print "[!] Exit code "retval" != 0 received from afl-showmap (this means a crashing or timeout input is likely present), terminating..."
|
||||
|
||||
if (!ENVIRON["AFL_KEEP_TRACES"]) {
|
||||
system("rm -rf "trace_dir" 2>/dev/null")
|
||||
system("rmdir "out_dir)
|
||||
}
|
||||
exit retval
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#######################################################
|
||||
|
112
afl-cmin.bash
112
afl-cmin.bash
@ -7,6 +7,8 @@
|
||||
#
|
||||
# Copyright 2014, 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Copyright 2019-2023 AFLplusplus
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at:
|
||||
@ -36,7 +38,7 @@
|
||||
# array sizes.
|
||||
#
|
||||
|
||||
echo "corpus minimization tool for afl-fuzz by Michal Zalewski"
|
||||
echo "corpus minimization tool for afl-fuzz"
|
||||
echo
|
||||
|
||||
#########
|
||||
@ -46,14 +48,14 @@ echo
|
||||
# Process command-line options...
|
||||
|
||||
MEM_LIMIT=none
|
||||
TIMEOUT=none
|
||||
TIMEOUT=5000
|
||||
|
||||
unset IN_DIR OUT_DIR STDIN_FILE EXTRA_PAR MEM_LIMIT_GIVEN \
|
||||
AFL_CMIN_CRASHES_ONLY AFL_CMIN_ALLOW_ANY QEMU_MODE UNICORN_MODE
|
||||
unset IN_DIR OUT_DIR STDIN_FILE EXTRA_PAR MEM_LIMIT_GIVEN F_ARG \
|
||||
AFL_CMIN_CRASHES_ONLY AFL_CMIN_ALLOW_ANY QEMU_MODE UNICORN_MODE T_ARG
|
||||
|
||||
export AFL_QUIET=1
|
||||
|
||||
while getopts "+i:o:f:m:t:eOQUAChXY" opt; do
|
||||
while getopts "+i:o:f:m:t:T:eOQUAChXY" opt; do
|
||||
|
||||
case "$opt" in
|
||||
|
||||
@ -69,6 +71,7 @@ while getopts "+i:o:f:m:t:eOQUAChXY" opt; do
|
||||
;;
|
||||
"f")
|
||||
STDIN_FILE="$OPTARG"
|
||||
F_ARG=1
|
||||
;;
|
||||
"m")
|
||||
MEM_LIMIT="$OPTARG"
|
||||
@ -106,6 +109,9 @@ while getopts "+i:o:f:m:t:eOQUAChXY" opt; do
|
||||
EXTRA_PAR="$EXTRA_PAR -U"
|
||||
UNICORN_MODE=1
|
||||
;;
|
||||
"T")
|
||||
T_ARG="$OPTARG"
|
||||
;;
|
||||
"?")
|
||||
exit 1
|
||||
;;
|
||||
@ -130,9 +136,10 @@ Required parameters:
|
||||
|
||||
Execution control settings:
|
||||
|
||||
-f file - location read by the fuzzed program (stdin)
|
||||
-m megs - memory limit for child process ($MEM_LIMIT MB)
|
||||
-t msec - run time limit for child process (none)
|
||||
-T tasks - how many parallel processes to create (default=1, "all"=nproc)
|
||||
-f file - location read by the fuzzed program (default: stdin)
|
||||
-m megs - memory limit for child process (default=$MEM_LIMIT MB)
|
||||
-t msec - run time limit for child process (default: 5000ms)
|
||||
-O - use binary-only instrumentation (FRIDA mode)
|
||||
-Q - use binary-only instrumentation (QEMU mode)
|
||||
-U - use unicorn-based instrumentation (Unicorn mode)
|
||||
@ -199,6 +206,11 @@ fi
|
||||
|
||||
# Check for obvious errors.
|
||||
|
||||
if [ ! "$T_ARG" = "" -a ! "$F_ARG" = "" -a ! "$NYX_MODE" == 1 ]; then
|
||||
echo "[-] Error: -T and -f can not be used together." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! "$MEM_LIMIT" = "none" ]; then
|
||||
|
||||
if [ "$MEM_LIMIT" -lt "5" ]; then
|
||||
@ -233,7 +245,7 @@ if [ "$NYX_MODE" = "" ]; then
|
||||
|
||||
fi
|
||||
|
||||
grep -aq AFL_DUMP_MAP_SIZE "./$TARGET_BIN" && {
|
||||
grep -aq AFL_DUMP_MAP_SIZE "$TARGET_BIN" && {
|
||||
echo "[!] Trying to obtain the map size of the target ..."
|
||||
MAPSIZE=`AFL_DUMP_MAP_SIZE=1 "./$TARGET_BIN" 2>/dev/null`
|
||||
test -n "$MAPSIZE" && {
|
||||
@ -299,14 +311,34 @@ if [ ! -x "$SHOWMAP" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
THREADS=
|
||||
if [ ! "$T_ARG" = "" ]; then
|
||||
if [ "$T_ARG" = "all" ]; then
|
||||
THREADS=$(nproc)
|
||||
else
|
||||
if [ "$T_ARG" -gt 1 -a "$T_ARG" -le "$(nproc)" ]; then
|
||||
THREADS=$T_ARG
|
||||
else
|
||||
echo "[-] Error: -T parameter must between 2 and $(nproc) or \"all\"." 1>&2
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ "$F_ARG" = ""]; then
|
||||
echo "[*] Are you aware of the '-T all' parallelize option that massively improves the speed?"
|
||||
fi
|
||||
fi
|
||||
|
||||
IN_COUNT=$((`ls -- "$IN_DIR" 2>/dev/null | wc -l`))
|
||||
|
||||
if [ "$IN_COUNT" = "0" ]; then
|
||||
echo "[+] Hmm, no inputs in the target directory. Nothing to be done."
|
||||
echo "[-] Hmm, no inputs in the target directory. Nothing to be done."
|
||||
rm -rf "$TRACE_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[*] Are you aware that afl-cmin is faster than this afl-cmin.bash script?"
|
||||
echo "[+] Found $IN_COUNT files for minimizing."
|
||||
|
||||
FIRST_FILE=`ls "$IN_DIR" | head -1`
|
||||
|
||||
# Make sure that we're not dealing with a directory.
|
||||
@ -355,6 +387,18 @@ else
|
||||
|
||||
fi
|
||||
|
||||
TMPFILE=$OUT_DIR/.list.$$
|
||||
if [ ! "$THREADS" = "" ]; then
|
||||
ls -- "$IN_DIR" > $TMPFILE 2>/dev/null
|
||||
IN_COUNT=$(cat $TMPFILE | wc -l)
|
||||
SPLIT=$(($IN_COUNT / $THREADS))
|
||||
if [ "$(($IN_COUNT % $THREADS))" -gt 0 ]; then
|
||||
SPLIT=$(($SPLIT + 1))
|
||||
fi
|
||||
echo "[+] Splitting workload into $THREADS tasks with $SPLIT items on average each."
|
||||
split -l $SPLIT $TMPFILE $TMPFILE.
|
||||
fi
|
||||
|
||||
# Let's roll!
|
||||
|
||||
#############################
|
||||
@ -363,6 +407,7 @@ fi
|
||||
|
||||
echo "[*] Obtaining traces for input files in '$IN_DIR'..."
|
||||
|
||||
if [ "$THREADS" = "" ]; then
|
||||
(
|
||||
|
||||
CUR=0
|
||||
@ -386,17 +431,58 @@ echo "[*] Obtaining traces for input files in '$IN_DIR'..."
|
||||
printf "\\r Processing file $CUR/$IN_COUNT... "
|
||||
|
||||
cp "$IN_DIR/$fn" "$STDIN_FILE"
|
||||
|
||||
"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" </dev/null
|
||||
|
||||
done
|
||||
|
||||
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
)
|
||||
|
||||
echo
|
||||
else
|
||||
|
||||
PIDS=
|
||||
CNT=0
|
||||
for inputs in $(ls ${TMPFILE}.*); do
|
||||
|
||||
(
|
||||
|
||||
if [ "$STDIN_FILE" = "" ]; then
|
||||
|
||||
cat $inputs | while read -r fn; do
|
||||
|
||||
"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn"
|
||||
|
||||
done
|
||||
|
||||
else
|
||||
|
||||
STDIN_FILE="$inputs.$$"
|
||||
cat $inputs | while read -r fn; do
|
||||
|
||||
cp "$IN_DIR/$fn" "$STDIN_FILE"
|
||||
"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" </dev/null
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
) &
|
||||
|
||||
PIDS="$PIDS $!"
|
||||
done
|
||||
|
||||
echo "[+] Waiting for running tasks IDs:$PIDS"
|
||||
wait
|
||||
echo "[+] all $THREADS running tasks completed."
|
||||
rm -f ${TMPFILE}*
|
||||
|
||||
echo trace dir files: $(ls $TRACE_DIR/*|wc -l)
|
||||
|
||||
fi
|
||||
|
||||
|
||||
##########################
|
||||
# STEP 2: SORTING TUPLES #
|
||||
|
7
custom_mutators/atnwalk/Makefile
Normal file
7
custom_mutators/atnwalk/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
all: atnwalk.so
|
||||
|
||||
atnwalk.so: atnwalk.c
|
||||
$(CC) -I ../../include/ -shared -fPIC -O3 -o atnwalk.so atnwalk.c
|
||||
|
||||
clean:
|
||||
rm -f *.so *.o *~ core
|
@ -6,9 +6,7 @@ Refer to [https://github.com/atnwalk/testbed](https://github.com/atnwalk/testbed
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
gcc -I ../../include/ -shared -fPIC -Wall -O3 atnwalk.c -o atnwalk.so
|
||||
```
|
||||
Just type `make` to build `atnwalk.so`.
|
||||
|
||||
## Run
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
#ifndef CUSTOM_MUTATOR_HELPERS
|
||||
#define CUSTOM_MUTATOR_HELPERS
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "afl-fuzz.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define INITIAL_GROWTH_SIZE (64)
|
||||
|
||||
/* Use in a struct: creates a name_buf and a name_size variable. */
|
||||
#define BUF_VAR(type, name) \
|
||||
type * name##_buf; \
|
||||
size_t name##_size;
|
||||
/* this filles in `&structptr->something_buf, &structptr->something_size`. */
|
||||
#define BUF_PARAMS(struct, name) \
|
||||
(void **)&struct->name##_buf, &struct->name##_size
|
||||
|
||||
#undef INITIAL_GROWTH_SIZE
|
||||
|
||||
#endif
|
||||
|
@ -3,14 +3,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "custom_mutator_helpers.h"
|
||||
#include "afl-fuzz.h"
|
||||
#include "mangle.h"
|
||||
|
||||
#define NUMBER_OF_MUTATIONS 5
|
||||
|
||||
uint8_t * queue_input;
|
||||
uint8_t *queue_input;
|
||||
size_t queue_input_size;
|
||||
afl_state_t * afl_struct;
|
||||
afl_state_t *afl_struct;
|
||||
run_t run;
|
||||
honggfuzz_t global;
|
||||
struct _dynfile_t dynfile;
|
||||
@ -18,8 +18,8 @@ struct _dynfile_t dynfile;
|
||||
typedef struct my_mutator {
|
||||
|
||||
afl_state_t *afl;
|
||||
run_t * run;
|
||||
u8 * mutator_buf;
|
||||
run_t *run;
|
||||
u8 *mutator_buf;
|
||||
unsigned int seed;
|
||||
unsigned int extras_cnt, a_extras_cnt;
|
||||
|
||||
@ -65,9 +65,9 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||
/* When a new queue entry is added we check if there are new dictionary
|
||||
entries to add to honggfuzz structure */
|
||||
|
||||
uint8_t afl_custom_queue_new_entry(my_mutator_t * data,
|
||||
const uint8_t *filename_new_queue,
|
||||
const uint8_t *filename_orig_queue) {
|
||||
void afl_custom_queue_new_entry(my_mutator_t *data,
|
||||
const uint8_t *filename_new_queue,
|
||||
const uint8_t *filename_orig_queue) {
|
||||
|
||||
if (run.global->mutate.dictionaryCnt >= 1024) return;
|
||||
|
||||
@ -97,7 +97,7 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t * data,
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
../examples/custom_mutator_helpers.h
|
@ -1,6 +1,5 @@
|
||||
// This simple example just creates random buffer <= 100 filled with 'A'
|
||||
// needs -I /path/to/AFLplusplus/include
|
||||
//#include "custom_mutator_helpers.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@ -8,19 +7,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "radamsa.h"
|
||||
#include "custom_mutator_helpers.h"
|
||||
#include "afl-fuzz.h"
|
||||
|
||||
typedef struct my_mutator {
|
||||
|
||||
afl_t *afl;
|
||||
|
||||
u8 *mutator_buf;
|
||||
|
||||
afl_state_t *afl;
|
||||
u8 *mutator_buf;
|
||||
unsigned int seed;
|
||||
|
||||
} my_mutator_t;
|
||||
|
||||
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
|
||||
my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
|
||||
|
||||
srand(seed);
|
||||
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||
|
@ -5,10 +5,19 @@
|
||||
|
||||
### Version ++4.07a (dev)
|
||||
- afl-fuzz:
|
||||
- reverse reading the seeds only on restarts (increases performance)
|
||||
- new env `AFL_POST_PROCESS_KEEP_ORIGINAL` to keep the orignal
|
||||
data before post process on finds
|
||||
data before post process on finds (for atnwalk custom mutator)
|
||||
- new env `AFL_IGNORE_PROBLEMS_COVERAGE` to ignore coverage from
|
||||
loaded libs after forkserver initialization (required by Mozilla)
|
||||
- afl-cc:
|
||||
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
|
||||
(https://github.com/fgsect/WAFL) project
|
||||
- afl-showmap:
|
||||
- added custom mutator post_process and send support
|
||||
- add `-I filelist` option, an alternative to `-i in_dir`
|
||||
- afl-cmin + afl-cmin.bash:
|
||||
- `-T threads` parallel task support, can be a huge speedup!
|
||||
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
|
||||
|
||||
|
||||
|
@ -229,7 +229,8 @@ If you find an interesting or important question missing, submit it via
|
||||
If this is not a viable option, you can set `AFL_IGNORE_PROBLEMS=1` but then
|
||||
the existing map will be used also for the newly loaded libraries, which
|
||||
allows it to work, however, the efficiency of the fuzzing will be partially
|
||||
degraded.
|
||||
degraded. Note that there is additionally `AFL_IGNORE_PROBLEMS_COVERAGE` to
|
||||
additionally tell AFL++ to ignore any coverage from the late loaded libaries.
|
||||
</p></details>
|
||||
|
||||
<details>
|
||||
|
@ -156,7 +156,7 @@ Available options:
|
||||
- LTO - LTO instrumentation
|
||||
- NATIVE - clang's original pcguard based instrumentation
|
||||
- NGRAM-x - deeper previous location coverage (from NGRAM-2 up to NGRAM-16)
|
||||
- PCGUARD - our own pcgard based instrumentation (default)
|
||||
- PCGUARD - our own pcguard based instrumentation (default)
|
||||
|
||||
#### CMPLOG
|
||||
|
||||
@ -240,7 +240,9 @@ combined.
|
||||
the default `0x10000`. A value of 0 or empty sets the map address to be
|
||||
dynamic (the original AFL way, which is slower).
|
||||
- `AFL_LLVM_MAP_DYNAMIC` sets the shared memory address to be dynamic.
|
||||
|
||||
- `AFL_LLVM_LTO_SKIPINIT` skips adding initialization code. Some global vars
|
||||
(e.g. the highest location ID) are not injected. Needed to instrument with
|
||||
[WAFL](https://github.com/fgsect/WAFL.git).
|
||||
For more information, see
|
||||
[instrumentation/README.lto.md](../instrumentation/README.lto.md).
|
||||
|
||||
@ -404,7 +406,8 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
|
||||
- If afl-fuzz encounters an incorrect fuzzing setup during a fuzzing session
|
||||
(not at startup), it will terminate. If you do not want this, then you can
|
||||
set `AFL_IGNORE_PROBLEMS`.
|
||||
set `AFL_IGNORE_PROBLEMS`. If you additionally want to also ignore coverage
|
||||
from late loaded libraries, you can set `AFL_IGNORE_PROBLEMS_COVERAGE`.
|
||||
|
||||
- When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the
|
||||
fuzzer to import test cases from other instances before doing anything else.
|
||||
|
@ -106,6 +106,7 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_HARDEN",
|
||||
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES",
|
||||
"AFL_IGNORE_PROBLEMS",
|
||||
"AFL_IGNORE_PROBLEMS_COVERAGE",
|
||||
"AFL_IGNORE_TIMEOUTS",
|
||||
"AFL_IGNORE_UNKNOWN_ENVS",
|
||||
"AFL_IMPORT_FIRST",
|
||||
@ -160,8 +161,9 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_LLVM_SKIP_NEVERZERO",
|
||||
"AFL_NO_AFFINITY",
|
||||
"AFL_TRY_AFFINITY",
|
||||
"AFL_LLVM_LTO_STARTID",
|
||||
"AFL_LLVM_LTO_DONTWRITEID",
|
||||
"AFL_LLVM_LTO_SKIPINIT"
|
||||
"AFL_LLVM_LTO_STARTID",
|
||||
"AFL_NO_ARITH",
|
||||
"AFL_NO_AUTODICT",
|
||||
"AFL_NO_BUILTIN",
|
||||
|
@ -1005,7 +1005,8 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
|
||||
// afl++ START
|
||||
if (dFile.is_open()) dFile.close();
|
||||
|
||||
if (!getenv("AFL_LLVM_LTO_DONTWRITEID") || dictionary.size() || map_addr) {
|
||||
if (!getenv("AFL_LLVM_LTO_SKIPINIT") &&
|
||||
(!getenv("AFL_LLVM_LTO_DONTWRITEID") || dictionary.size() || map_addr)) {
|
||||
|
||||
// yes we could create our own function, insert it into ctors ...
|
||||
// but this would be a pain in the butt ... so we use afl-llvm-rt-lto.o
|
||||
|
@ -1563,17 +1563,27 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
||||
"[-] FATAL: forkserver is already up, but an instrumented dlopen() "
|
||||
"library loaded afterwards. You must AFL_PRELOAD such libraries to "
|
||||
"be able to fuzz them or LD_PRELOAD to run outside of afl-fuzz.\n"
|
||||
"To ignore this set AFL_IGNORE_PROBLEMS=1 but this will be bad for "
|
||||
"coverage.\n");
|
||||
"To ignore this set AFL_IGNORE_PROBLEMS=1 but this will lead to "
|
||||
"ambiguous coverage data.\n"
|
||||
"In addition, you can set AFL_IGNORE_PROBLEMS_COVERAGE=1 to "
|
||||
"ignore the additional coverage instead (use with caution!).\n");
|
||||
abort();
|
||||
|
||||
} else {
|
||||
|
||||
u8 ignore_dso_after_fs = !!getenv("AFL_IGNORE_PROBLEMS_COVERAGE");
|
||||
if (__afl_debug && ignore_dso_after_fs) {
|
||||
|
||||
fprintf(stderr, "Ignoring coverage from dynamically loaded code\n");
|
||||
|
||||
}
|
||||
|
||||
static u32 offset = 5;
|
||||
|
||||
while (start < stop) {
|
||||
|
||||
if (likely(inst_ratio == 100) || R(100) < inst_ratio) {
|
||||
if (!ignore_dso_after_fs &&
|
||||
(likely(inst_ratio == 100) || R(100) < inst_ratio)) {
|
||||
|
||||
*(start++) = offset;
|
||||
|
||||
|
@ -2099,6 +2099,8 @@ int main(int argc, char **argv, char **envp) {
|
||||
"bb\n"
|
||||
" AFL_REAL_LD: use this lld linker instead of the compiled in "
|
||||
"path\n"
|
||||
" AFL_LLVM_LTO_SKIPINIT: don't inject initialization code "
|
||||
"(used in WAFL mode)\n"
|
||||
"If anything fails - be sure to read README.lto.md!\n");
|
||||
#endif
|
||||
|
||||
|
@ -718,10 +718,21 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
|
||||
|
||||
if (nl_cnt) {
|
||||
|
||||
i = nl_cnt;
|
||||
u32 done = 0;
|
||||
|
||||
if (unlikely(afl->in_place_resume)) {
|
||||
|
||||
i = nl_cnt;
|
||||
|
||||
} else {
|
||||
|
||||
i = 0;
|
||||
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
--i;
|
||||
if (unlikely(afl->in_place_resume)) { --i; }
|
||||
|
||||
struct stat st;
|
||||
u8 dfn[PATH_MAX];
|
||||
@ -745,7 +756,7 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
|
||||
free(nl[i]); /* not tracked */
|
||||
read_testcases(afl, fn2);
|
||||
ck_free(fn2);
|
||||
continue;
|
||||
goto next_entry;
|
||||
|
||||
}
|
||||
|
||||
@ -754,7 +765,7 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
|
||||
if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn2, "/README.txt")) {
|
||||
|
||||
ck_free(fn2);
|
||||
continue;
|
||||
goto next_entry;
|
||||
|
||||
}
|
||||
|
||||
@ -801,18 +812,18 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
|
||||
next_entry:
|
||||
if (unlikely(afl->in_place_resume)) {
|
||||
|
||||
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size,
|
||||
HASH_CONST); afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
|
||||
afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
|
||||
if (unlikely(i == 0)) { done = 1; }
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
*/
|
||||
if (unlikely(++i >= (u32)nl_cnt)) { done = 1; }
|
||||
|
||||
} while (i > 0);
|
||||
}
|
||||
|
||||
} while (!done);
|
||||
|
||||
}
|
||||
|
||||
|
@ -259,6 +259,8 @@ static void usage(u8 *argv0, int more_help) {
|
||||
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
|
||||
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
|
||||
"AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n"
|
||||
"AFL_IGNORE_PROBLEMS_COVERAGE: if set in addition to AFL_IGNORE_PROBLEMS - also\n"
|
||||
" ignore those libs for coverage\n"
|
||||
"AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n"
|
||||
"AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
|
||||
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
|
||||
|
@ -69,7 +69,9 @@ static afl_state_t *afl;
|
||||
static char *stdin_file; /* stdin file */
|
||||
|
||||
static u8 *in_dir = NULL, /* input folder */
|
||||
*out_file = NULL, *at_file = NULL; /* Substitution string for @@ */
|
||||
*out_file = NULL, /* output file or directory */
|
||||
*at_file = NULL, /* Substitution string for @@ */
|
||||
*in_filelist = NULL; /* input file list */
|
||||
|
||||
static u8 outfile[PATH_MAX];
|
||||
|
||||
@ -878,6 +880,103 @@ u32 execute_testcases(u8 *dir) {
|
||||
|
||||
}
|
||||
|
||||
u32 execute_testcases_filelist(u8 *fn) {
|
||||
|
||||
u32 done = 0;
|
||||
u8 buf[4096];
|
||||
u8 val_buf[2][STRINGIFY_VAL_SIZE_MAX];
|
||||
FILE *f;
|
||||
|
||||
if (!be_quiet) { ACTF("Reading from '%s'...", fn); }
|
||||
|
||||
if ((f = fopen(fn, "r")) == NULL) { FATAL("could not open '%s'", fn); }
|
||||
|
||||
while (fgets(buf, sizeof(buf), f) != NULL) {
|
||||
|
||||
struct stat st;
|
||||
u8 *fn2 = buf, *fn3;
|
||||
|
||||
while (*fn2 == ' ') {
|
||||
|
||||
++fn2;
|
||||
|
||||
}
|
||||
|
||||
while (*fn2 &&
|
||||
(fn2[strlen(fn2) - 1] == '\r' || fn2[strlen(fn2) - 1] == '\n' ||
|
||||
fn2[strlen(fn2) - 1] == ' ')) {
|
||||
|
||||
fn2[strlen(fn2) - 1] = 0;
|
||||
|
||||
}
|
||||
|
||||
if (debug) { printf("Getting coverage for '%s'\n", fn2); }
|
||||
|
||||
if (!*fn2) { continue; }
|
||||
|
||||
if (lstat(fn2, &st) || access(fn2, R_OK)) {
|
||||
|
||||
WARNF("Unable to access '%s'", fn2);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
++done;
|
||||
|
||||
if (!S_ISREG(st.st_mode) || !st.st_size) { continue; }
|
||||
|
||||
if ((fn3 = strrchr(fn2, '/'))) {
|
||||
|
||||
++fn3;
|
||||
|
||||
} else {
|
||||
|
||||
fn3 = fn2;
|
||||
|
||||
}
|
||||
|
||||
if (st.st_size > MAX_FILE && !be_quiet && !quiet_mode) {
|
||||
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
if (!collect_coverage) {
|
||||
|
||||
snprintf(outfile, sizeof(outfile), "%s/%s", out_file, fn3);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (child_crashed && debug) { WARNF("crashed: %s", fn2); }
|
||||
|
||||
if (collect_coverage)
|
||||
analyze_results(fsrv);
|
||||
else
|
||||
tcnt = write_results_to_file(fsrv, outfile);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return done;
|
||||
|
||||
}
|
||||
|
||||
/* Show banner. */
|
||||
|
||||
static void show_banner(void) {
|
||||
@ -920,6 +1019,7 @@ static void usage(u8 *argv0) {
|
||||
" With -C, -o is a file, without -C it must be a "
|
||||
"directory\n"
|
||||
" and each bitmap will be written there individually.\n"
|
||||
" -I filelist - alternatively to -i, -I is a list of files\n"
|
||||
" -C - collect coverage, writes all edges to -o and gives a "
|
||||
"summary\n"
|
||||
" Must be combined with -i.\n"
|
||||
@ -932,7 +1032,7 @@ static void usage(u8 *argv0) {
|
||||
"This tool displays raw tuple data captured by AFL instrumentation.\n"
|
||||
"For additional help, consult %s/README.md.\n\n"
|
||||
|
||||
"If you use -i mode, then custom mutator post_process send send "
|
||||
"If you use -i/-I mode, then custom mutator post_process send send "
|
||||
"functionality\n"
|
||||
"is supported.\n\n"
|
||||
|
||||
@ -994,7 +1094,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (getenv("AFL_QUIET") != NULL) { be_quiet = true; }
|
||||
|
||||
while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrshXY")) > 0) {
|
||||
while ((opt = getopt(argc, argv, "+i:I:o:f:m:t:AeqCZOH:QUWbcrshXY")) > 0) {
|
||||
|
||||
switch (opt) {
|
||||
|
||||
@ -1012,6 +1112,11 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
in_dir = optarg;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
if (in_filelist) { FATAL("Multiple -I options not supported"); }
|
||||
in_filelist = optarg;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
|
||||
if (out_file) { FATAL("Multiple -o options not supported"); }
|
||||
@ -1234,10 +1339,12 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (optind == argc || !out_file) { usage(argv[0]); }
|
||||
|
||||
if (in_dir) {
|
||||
if (in_dir && in_filelist) { FATAL("you can only specify either -i or -I"); }
|
||||
|
||||
if (in_dir || in_filelist) {
|
||||
|
||||
if (!out_file && !collect_coverage)
|
||||
FATAL("for -i you need to specify either -C and/or -o");
|
||||
FATAL("for -i/-I you need to specify either -C and/or -o");
|
||||
|
||||
}
|
||||
|
||||
@ -1294,7 +1401,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (in_dir) {
|
||||
if (in_dir || in_filelist) {
|
||||
|
||||
/* If we don't have a file name chosen yet, use a safe default. */
|
||||
u8 *use_dir = ".";
|
||||
@ -1400,7 +1507,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
if (!fsrv->nyx_mode && in_dir) {
|
||||
if (!fsrv->nyx_mode && (in_dir || in_filelist)) {
|
||||
|
||||
(void)check_binary_signatures(fsrv->target_path);
|
||||
|
||||
@ -1483,7 +1590,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (in_dir) {
|
||||
if (in_dir || in_filelist) {
|
||||
|
||||
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||
afl->afl_env.afl_custom_mutator_library =
|
||||
@ -1496,33 +1603,46 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
if (getenv("AFL_CUSTOM_MUTATOR_LIBRARY") || getenv("AFL_PYTHON_MODULE")) {
|
||||
|
||||
WARNF(
|
||||
"Custom mutator environment detected, this is only supported in -i "
|
||||
"mode!\n");
|
||||
"Custom mutator environment detected, this is only supported in "
|
||||
"-i/-I mode!\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (in_dir) {
|
||||
if (in_dir || in_filelist) {
|
||||
|
||||
DIR *dir_in, *dir_out = NULL;
|
||||
u8 *dn = NULL;
|
||||
|
||||
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true;
|
||||
|
||||
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
|
||||
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
||||
|
||||
// if a queue subdirectory exists switch to that
|
||||
u8 *dn = alloc_printf("%s/queue", in_dir);
|
||||
if ((dir_in = opendir(dn)) != NULL) {
|
||||
if (in_filelist) {
|
||||
|
||||
closedir(dir_in);
|
||||
in_dir = dn;
|
||||
if (!be_quiet) ACTF("Reading from file list '%s'...", in_filelist);
|
||||
|
||||
} else
|
||||
} else {
|
||||
|
||||
ck_free(dn);
|
||||
if (!be_quiet) ACTF("Reading from directory '%s'...", in_dir);
|
||||
// if a queue subdirectory exists switch to that
|
||||
dn = alloc_printf("%s/queue", in_dir);
|
||||
|
||||
if ((dir_in = opendir(dn)) != NULL) {
|
||||
|
||||
closedir(dir_in);
|
||||
in_dir = dn;
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(dn);
|
||||
|
||||
}
|
||||
|
||||
if (!be_quiet) ACTF("Reading from directory '%s'...", in_dir);
|
||||
|
||||
}
|
||||
|
||||
if (!collect_coverage) {
|
||||
|
||||
@ -1576,9 +1696,21 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
||||
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
||||
|
||||
if (execute_testcases(in_dir) == 0) {
|
||||
if (in_dir) {
|
||||
|
||||
FATAL("could not read input testcases from %s", in_dir);
|
||||
if (execute_testcases(in_dir) == 0) {
|
||||
|
||||
FATAL("could not read input testcases from %s", in_dir);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (execute_testcases_filelist(in_filelist) == 0) {
|
||||
|
||||
FATAL("could not read input testcases from %s", in_filelist);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user