mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
Merge branch 'dev' of https://github.com/AFLplusplus/AFLplusplus into dev
This commit is contained in:
@ -69,7 +69,7 @@ ifneq "$(shell uname -m)" "x86_64"
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
|
CFLAGS ?= -O3 -funroll-loops $(CFLAGS_OPT)
|
||||||
override CFLAGS += -Wall -g -Wno-pointer-sign \
|
override CFLAGS += -Wall -g -Wno-pointer-sign -Wmissing-declarations\
|
||||||
-I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \
|
-I include/ -Werror -DAFL_PATH=\"$(HELPER_PATH)\" \
|
||||||
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
|
||||||
|
|
||||||
|
5
TODO.md
5
TODO.md
@ -1,11 +1,12 @@
|
|||||||
# TODO list for AFL++
|
# TODO list for AFL++
|
||||||
|
|
||||||
## Roadmap 2.64
|
## Roadmap 2.65
|
||||||
|
|
||||||
|
- AFL_MAP_SIZE for afl-llvm-pass, qemu_mode and unicorn_mode
|
||||||
|
- fix stability calculation bug
|
||||||
- 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
|
||||||
- libradamsa as a custom module?
|
- libradamsa as a custom module?
|
||||||
- fix stability calculation bug
|
|
||||||
|
|
||||||
## Further down the road
|
## Further down the road
|
||||||
|
|
||||||
|
@ -12,21 +12,27 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
### Version ++2.63d (development):
|
### Version ++2.63d (development):
|
||||||
- llvm_mode LTO mode:
|
- llvm_mode LTO mode:
|
||||||
- now requires llvm11 - but compiles all targets! :)
|
- now requires llvm11 - but compiles all targets! :)
|
||||||
- autodictionary feature added, enable with AFL_LLVM_LTO_AUTODICTIONARY
|
- autodictionary feature added, enable with `AFL_LLVM_LTO_AUTODICTIONARY`
|
||||||
- variable map size usage
|
- variable map size usage
|
||||||
- afl-fuzz:
|
- afl-fuzz:
|
||||||
- variable map size support added (only LTO mode can use this)
|
- variable map size support added (only LTO mode can use this)
|
||||||
- snapshot feature usage now visible in UI
|
- snapshot feature usage now visible in UI
|
||||||
- Now setting "-L -1" will enable MOpt in parallel to normal mutation.
|
- Now setting `-L -1` will enable MOpt in parallel to normal mutation.
|
||||||
Additionally this allows to run dictionaries, radamsa and cmplog.
|
Additionally, this allows to run dictionaries, radamsa and cmplog.
|
||||||
|
- fix for cmplog/redqueen mode if stdin was used
|
||||||
|
- fix for writing a better plot_data file
|
||||||
|
- qemu_mode: fix for persistent mode
|
||||||
- compare-transform/AFL_LLVM_LAF_TRANSFORM_COMPARES now transforms also
|
- compare-transform/AFL_LLVM_LAF_TRANSFORM_COMPARES now transforms also
|
||||||
static global and local variable comparisons (cannot find all though)
|
static global and local variable comparisons (cannot find all though)
|
||||||
- extended forkserver: map_size and more information is communicated to
|
- extended forkserver: map_size and more information is communicated to
|
||||||
afl-fuzz (and afl-fuzz acts accordingly)
|
afl-fuzz (and afl-fuzz acts accordingly)
|
||||||
- more refactoring
|
- new environment variable: AFL_MAP_SIZE to specify the size of the shared map
|
||||||
- if AFL_CC/AFL_CXX is set but empty afl compilers did fail, fixed
|
- if AFL_CC/AFL_CXX is set but empty afl compilers did fail, fixed
|
||||||
(this bug is in vanilla afl too)
|
(this bug is in vanilla afl too)
|
||||||
- added NO_PYTHON flag to disable python support when building afl-fuzz
|
- added NO_PYTHON flag to disable python support when building afl-fuzz
|
||||||
|
- Bugfix: in persistent mode, fuzzing could get stuck after initial crash (#319)
|
||||||
|
- Bugfix: alf-plot output (#320)
|
||||||
|
- more refactoring
|
||||||
|
|
||||||
|
|
||||||
### Version ++2.63c (release):
|
### Version ++2.63c (release):
|
||||||
@ -314,7 +320,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
you use the new -p option :-) - see docs/power_schedules.md
|
you use the new -p option :-) - see docs/power_schedules.md
|
||||||
- added afl-system-config script to set all system performance options for fuzzing
|
- added afl-system-config script to set all system performance options for fuzzing
|
||||||
- llvm_mode works with llvm 3.9 up to including 8 !
|
- llvm_mode works with llvm 3.9 up to including 8 !
|
||||||
- qemu_mode got upgraded from 2.1 to 3.1 - incorporated from
|
- qemu_mode got upgraded from 2.1 to 3.1 - incorporated from
|
||||||
https://github.com/andreafioraldi/afl and with community patches added
|
https://github.com/andreafioraldi/afl and with community patches added
|
||||||
|
|
||||||
|
|
||||||
|
@ -243,6 +243,11 @@ checks or alter some of the more exotic semantics of the tool:
|
|||||||
normally indicated by the cycle counter in the UI turning green. May be
|
normally indicated by the cycle counter in the UI turning green. May be
|
||||||
convenient for some types of automated jobs.
|
convenient for some types of automated jobs.
|
||||||
|
|
||||||
|
- AFL_MAP_SIZE sets the size of the shared map that afl-fuzz, afl-showmap,
|
||||||
|
afl-tmin and afl-analyze create to gather instrumentation data from
|
||||||
|
the target. This must be equal or larger than the size the target was
|
||||||
|
compiled with.
|
||||||
|
|
||||||
- Setting AFL_NO_AFFINITY disables attempts to bind to a specific CPU core
|
- Setting AFL_NO_AFFINITY disables attempts to bind to a specific CPU core
|
||||||
on Linux systems. This slows things down, but lets you run more instances
|
on Linux systems. This slows things down, but lets you run more instances
|
||||||
of afl-fuzz than would be prudent (if you really want to).
|
of afl-fuzz than would be prudent (if you really want to).
|
||||||
|
@ -364,6 +364,16 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
be_quiet = 1;
|
be_quiet = 1;
|
||||||
|
|
||||||
|
u8 *ptr;
|
||||||
|
if (!be_quiet &&
|
||||||
|
((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE")))) {
|
||||||
|
|
||||||
|
u32 map_size = atoi(ptr);
|
||||||
|
if (map_size != MAP_SIZE)
|
||||||
|
FATAL("AFL_MAP_SIZE is not supported by afl-gcc-fast");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
check_environment_vars(envp);
|
check_environment_vars(envp);
|
||||||
|
|
||||||
find_obj(argv[0]);
|
find_obj(argv[0]);
|
||||||
|
@ -443,11 +443,11 @@ typedef struct afl_state {
|
|||||||
fast_cal, /* Try to calibrate faster? */
|
fast_cal, /* Try to calibrate faster? */
|
||||||
disable_trim; /* Never trim in fuzz_one */
|
disable_trim; /* Never trim in fuzz_one */
|
||||||
|
|
||||||
u8 virgin_bits[MAP_SIZE], /* Regions yet untouched by fuzzing */
|
u8 *virgin_bits, /* Regions yet untouched by fuzzing */
|
||||||
virgin_tmout[MAP_SIZE], /* Bits we haven't seen in tmouts */
|
*virgin_tmout, /* Bits we haven't seen in tmouts */
|
||||||
virgin_crash[MAP_SIZE]; /* Bits we haven't seen in crashes */
|
*virgin_crash; /* Bits we haven't seen in crashes */
|
||||||
|
|
||||||
u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */
|
u8 *var_bytes; /* Bytes that appear to be variable */
|
||||||
|
|
||||||
volatile u8 stop_soon, /* Ctrl-C pressed? */
|
volatile u8 stop_soon, /* Ctrl-C pressed? */
|
||||||
clear_screen; /* Window resized? */
|
clear_screen; /* Window resized? */
|
||||||
@ -535,7 +535,7 @@ typedef struct afl_state {
|
|||||||
*queue_top, /* Top of the list */
|
*queue_top, /* Top of the list */
|
||||||
*q_prev100; /* Previous 100 marker */
|
*q_prev100; /* Previous 100 marker */
|
||||||
|
|
||||||
struct queue_entry *top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
|
struct queue_entry **top_rated; /* Top entries for bitmap bytes */
|
||||||
|
|
||||||
struct extra_data *extras; /* Extra tokens to fuzz with */
|
struct extra_data *extras; /* Extra tokens to fuzz with */
|
||||||
u32 extras_cnt; /* Total number of tokens read */
|
u32 extras_cnt; /* Total number of tokens read */
|
||||||
@ -584,9 +584,9 @@ typedef struct afl_state {
|
|||||||
u64 stats_last_stats_ms, stats_last_plot_ms, stats_last_ms, stats_last_execs;
|
u64 stats_last_stats_ms, stats_last_plot_ms, stats_last_ms, stats_last_execs;
|
||||||
double stats_avg_exec;
|
double stats_avg_exec;
|
||||||
|
|
||||||
u8 clean_trace[MAP_SIZE];
|
u8 *clean_trace;
|
||||||
u8 clean_trace_custom[MAP_SIZE];
|
u8 *clean_trace_custom;
|
||||||
u8 first_trace[MAP_SIZE];
|
u8 *first_trace;
|
||||||
|
|
||||||
/*needed for afl_fuzz_one */
|
/*needed for afl_fuzz_one */
|
||||||
// TODO: see which we can reuse
|
// TODO: see which we can reuse
|
||||||
@ -608,6 +608,9 @@ typedef struct afl_state {
|
|||||||
u8 * ex_buf;
|
u8 * ex_buf;
|
||||||
size_t ex_size;
|
size_t ex_size;
|
||||||
|
|
||||||
|
u8 * map_tmp_buf;
|
||||||
|
size_t map_tmp_size;
|
||||||
|
|
||||||
} afl_state_t;
|
} afl_state_t;
|
||||||
|
|
||||||
/* A global pointer to all instances is needed (for now) for signals to arrive
|
/* A global pointer to all instances is needed (for now) for signals to arrive
|
||||||
@ -794,7 +797,7 @@ struct custom_mutator {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void afl_state_init(afl_state_t *);
|
void afl_state_init(afl_state_t *, uint32_t map_size);
|
||||||
void afl_state_deinit(afl_state_t *);
|
void afl_state_deinit(afl_state_t *);
|
||||||
void read_afl_environment(afl_state_t *, char **);
|
void read_afl_environment(afl_state_t *, char **);
|
||||||
|
|
||||||
@ -808,6 +811,7 @@ u8 trim_case_custom(afl_state_t *, struct queue_entry *q, u8 *in_buf);
|
|||||||
/* Python */
|
/* Python */
|
||||||
#ifdef USE_PYTHON
|
#ifdef USE_PYTHON
|
||||||
|
|
||||||
|
void load_custom_mutator_py(afl_state_t *, char *);
|
||||||
void finalize_py_module(void *);
|
void finalize_py_module(void *);
|
||||||
|
|
||||||
size_t pre_save_py(void *, u8 *, size_t, u8 **);
|
size_t pre_save_py(void *, u8 *, size_t, u8 **);
|
||||||
@ -835,7 +839,6 @@ u32 calculate_score(afl_state_t *, struct queue_entry *);
|
|||||||
|
|
||||||
/* Bitmap */
|
/* Bitmap */
|
||||||
|
|
||||||
void read_bitmap(afl_state_t *, u8 *);
|
|
||||||
void write_bitmap(afl_state_t *);
|
void write_bitmap(afl_state_t *);
|
||||||
u32 count_bits(afl_state_t *, u8 *);
|
u32 count_bits(afl_state_t *, u8 *);
|
||||||
u32 count_bytes(afl_state_t *, u8 *);
|
u32 count_bytes(afl_state_t *, u8 *);
|
||||||
@ -873,7 +876,7 @@ void show_init_stats(afl_state_t *);
|
|||||||
|
|
||||||
/* Run */
|
/* Run */
|
||||||
|
|
||||||
fsrv_run_result_t run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);
|
fsrv_run_result_t fuzz_run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);
|
||||||
void write_to_testcase(afl_state_t *, void *, u32);
|
void write_to_testcase(afl_state_t *, void *, u32);
|
||||||
u8 calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8);
|
u8 calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8);
|
||||||
void sync_fuzzers(afl_state_t *);
|
void sync_fuzzers(afl_state_t *);
|
||||||
|
@ -51,6 +51,16 @@ char * get_afl_env(char *env);
|
|||||||
extern u8 be_quiet;
|
extern u8 be_quiet;
|
||||||
extern u8 *doc_path; /* path to documentation dir */
|
extern u8 *doc_path; /* path to documentation dir */
|
||||||
|
|
||||||
|
/* Find binary, used by analyze, showmap, tmin
|
||||||
|
@returns the path, allocating the string */
|
||||||
|
|
||||||
|
u8 *find_binary(u8 *fname);
|
||||||
|
|
||||||
|
/* Read a bitmap from file fname to memory
|
||||||
|
This is for the -B option again. */
|
||||||
|
|
||||||
|
void read_bitmap(u8 *fname, u8 *map, size_t len);
|
||||||
|
|
||||||
/* Get unix time in milliseconds */
|
/* Get unix time in milliseconds */
|
||||||
|
|
||||||
u64 get_cur_time(void);
|
u64 get_cur_time(void);
|
||||||
@ -105,5 +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,
|
u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms,
|
||||||
volatile u8 *stop_soon_p);
|
volatile u8 *stop_soon_p);
|
||||||
|
|
||||||
|
u32 get_map_size();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -407,8 +407,7 @@
|
|||||||
#define FS_OPT_SNAPSHOT 0x20000000
|
#define FS_OPT_SNAPSHOT 0x20000000
|
||||||
#define FS_OPT_AUTODICT 0x10000000
|
#define FS_OPT_AUTODICT 0x10000000
|
||||||
#define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1)
|
#define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1)
|
||||||
#define FS_OPT_SET_MAPSIZE(x) \
|
#define FS_OPT_SET_MAPSIZE(x) (x <= 1 || x > 0x1000000 ? 0 : ((x - 1) << 1))
|
||||||
(x <= 1 || x > MAP_SIZE || x > 0x1000000 ? 0 : ((x - 1) << 1))
|
|
||||||
|
|
||||||
#endif /* ! _HAVE_CONFIG_H */
|
#endif /* ! _HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
/* __FUNCTION__ is non-iso */
|
/* __FUNCTION__ is non-iso */
|
||||||
#ifdef __func__
|
#ifdef __func__
|
||||||
#define __FUNCTION__ __func__
|
#define __FUNCTION__ __func__
|
||||||
#else
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
|
@ -61,11 +61,12 @@ typedef struct afl_forkserver {
|
|||||||
u64 total_execs; /* How often run_target was called */
|
u64 total_execs; /* How often run_target was called */
|
||||||
|
|
||||||
u8 *out_file, /* File to fuzz, if any */
|
u8 *out_file, /* File to fuzz, if any */
|
||||||
*target_path; /* Path of the target */
|
*target_path; /* Path of the target */
|
||||||
|
|
||||||
FILE *plot_file; /* Gnuplot output file */
|
FILE *plot_file; /* Gnuplot output file */
|
||||||
|
|
||||||
u8 last_run_timed_out; /* Traced process timed out? */
|
/* Note: lat_run_timed_out is u32 to send it to the child as 4 byte array */
|
||||||
|
u32 last_run_timed_out; /* Traced process timed out? */
|
||||||
|
|
||||||
u8 last_kill_signal; /* Signal that killed the child */
|
u8 last_kill_signal; /* Signal that killed the child */
|
||||||
|
|
||||||
@ -100,12 +101,10 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from);
|
|||||||
void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||||
volatile u8 *stop_soon_p, u8 debug_child_output);
|
volatile u8 *stop_soon_p, u8 debug_child_output);
|
||||||
void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len);
|
void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len);
|
||||||
fsrv_run_result_t afl_fsrv_run_target(
|
fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
||||||
afl_forkserver_t *fsrv, u32 timeout,
|
volatile u8 *stop_soon_p);
|
||||||
void(classify_counts_func)(afl_forkserver_t *fsrv),
|
void afl_fsrv_killall(void);
|
||||||
volatile u8 *stop_soon_p);
|
void afl_fsrv_deinit(afl_forkserver_t *fsrv);
|
||||||
void afl_fsrv_killall(void);
|
|
||||||
void afl_fsrv_deinit(afl_forkserver_t *fsrv);
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define MSG_FORK_ON_APPLE \
|
#define MSG_FORK_ON_APPLE \
|
||||||
|
@ -44,8 +44,7 @@ typedef struct sharedmem {
|
|||||||
|
|
||||||
u8 *map; /* shared memory region */
|
u8 *map; /* shared memory region */
|
||||||
|
|
||||||
size_t size_alloc; /* actual allocated size */
|
size_t map_size; /* actual allocated size */
|
||||||
size_t size_used; /* in use by shmem app */
|
|
||||||
|
|
||||||
int cmplog_mode;
|
int cmplog_mode;
|
||||||
struct cmp_map *cmp_map;
|
struct cmp_map *cmp_map;
|
||||||
|
@ -223,10 +223,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!(getenv("AFL_LLVM_LTO_AUTODICTIONARY") // disabled when autodictionary
|
if (getenv("LAF_TRANSFORM_COMPARES") ||
|
||||||
&& instrument_mode != INSTRUMENT_LTO)) // and lto_mode is used
|
getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
|
||||||
&& (getenv("LAF_TRANSFORM_COMPARES") ||
|
|
||||||
getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES"))) {
|
if (!be_quiet && getenv("AFL_LLVM_LTO_AUTODICTIONARY") &&
|
||||||
|
instrument_mode != INSTRUMENT_LTO)
|
||||||
|
WARNF(
|
||||||
|
"using AFL_LLVM_LAF_TRANSFORM_COMPARES together with "
|
||||||
|
"AFL_LLVM_LTO_AUTODICTIONARY makes no sense. Use only "
|
||||||
|
"AFL_LLVM_LTO_AUTODICTIONARY.");
|
||||||
|
|
||||||
cc_params[cc_par_cnt++] = "-Xclang";
|
cc_params[cc_par_cnt++] = "-Xclang";
|
||||||
cc_params[cc_par_cnt++] = "-load";
|
cc_params[cc_par_cnt++] = "-load";
|
||||||
@ -716,30 +721,30 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
"Environment variables used:\n"
|
"Environment variables used:\n"
|
||||||
"AFL_CC: path to the C compiler to use\n"
|
"AFL_CC: path to the C compiler to use\n"
|
||||||
"AFL_CXX: path to the C++ compiler to use\n"
|
"AFL_CXX: path to the C++ compiler to use\n"
|
||||||
"AFL_PATH: path to instrumenting pass and runtime "
|
|
||||||
"(afl-llvm-rt.*o)\n"
|
|
||||||
"AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n"
|
|
||||||
"AFL_NO_BUILTIN: compile for use with libtokencap.so\n"
|
|
||||||
"AFL_INST_RATIO: percentage of branches to instrument\n"
|
|
||||||
"AFL_QUIET: suppress verbose output\n"
|
|
||||||
"AFL_DEBUG: enable developer debugging output\n"
|
"AFL_DEBUG: enable developer debugging output\n"
|
||||||
|
"AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n"
|
||||||
"AFL_HARDEN: adds code hardening to catch memory bugs\n"
|
"AFL_HARDEN: adds code hardening to catch memory bugs\n"
|
||||||
"AFL_USE_ASAN: activate address sanitizer\n"
|
"AFL_INST_RATIO: percentage of branches to instrument\n"
|
||||||
"AFL_USE_MSAN: activate memory sanitizer\n"
|
|
||||||
"AFL_USE_UBSAN: activate undefined behaviour sanitizer\n"
|
|
||||||
"AFL_USE_CFISAN: activate control flow sanitizer\n"
|
|
||||||
"AFL_LLVM_WHITELIST: enable whitelisting (selective "
|
|
||||||
"instrumentation)\n"
|
|
||||||
"AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n"
|
"AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n"
|
||||||
"AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n"
|
"AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n"
|
||||||
"AFL_LLVM_LAF_SPLIT_SWITCHES: casc. comp. in 'switch'\n"
|
|
||||||
"AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison "
|
|
||||||
"function calls\n"
|
|
||||||
" to cascaded comparisons\n"
|
|
||||||
"AFL_LLVM_LAF_SPLIT_FLOATS: transform floating point comp. to "
|
"AFL_LLVM_LAF_SPLIT_FLOATS: transform floating point comp. to "
|
||||||
"cascaded "
|
"cascaded "
|
||||||
"comp.\n"
|
"comp.\n"
|
||||||
"AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n",
|
"AFL_LLVM_LAF_SPLIT_SWITCHES: casc. comp. in 'switch'\n"
|
||||||
|
" to cascaded comparisons\n"
|
||||||
|
"AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison "
|
||||||
|
"function calls\n"
|
||||||
|
"AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n"
|
||||||
|
"AFL_LLVM_WHITELIST: enable whitelisting (selective "
|
||||||
|
"instrumentation)\n"
|
||||||
|
"AFL_NO_BUILTIN: compile for use with libtokencap.so\n"
|
||||||
|
"AFL_PATH: path to instrumenting pass and runtime "
|
||||||
|
"(afl-llvm-rt.*o)\n"
|
||||||
|
"AFL_QUIET: suppress verbose output\n"
|
||||||
|
"AFL_USE_ASAN: activate address sanitizer\n"
|
||||||
|
"AFL_USE_CFISAN: activate control flow sanitizer\n"
|
||||||
|
"AFL_USE_MSAN: activate memory sanitizer\n"
|
||||||
|
"AFL_USE_UBSAN: activate undefined behaviour sanitizer\n",
|
||||||
callname, BIN_PATH, BIN_PATH);
|
callname, BIN_PATH, BIN_PATH);
|
||||||
|
|
||||||
SAYF(
|
SAYF(
|
||||||
@ -747,21 +752,21 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
"AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n"
|
"AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n"
|
||||||
"AFL_LLVM_INSTRUMENT: set instrumentation mode: DEFAULT, CFG "
|
"AFL_LLVM_INSTRUMENT: set instrumentation mode: DEFAULT, CFG "
|
||||||
"(INSTRIM), LTO, CTX, NGRAM-2 ... NGRAM-16\n"
|
"(INSTRIM), LTO, CTX, NGRAM-2 ... NGRAM-16\n"
|
||||||
"You can also use the old environment variables:"
|
" You can also use the old environment variables instead:"
|
||||||
"AFL_LLVM_CTX: use context sensitive coverage\n"
|
" AFL_LLVM_CTX: use context sensitive coverage\n"
|
||||||
"AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n"
|
" AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n"
|
||||||
"AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage\n"
|
" AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage\n"
|
||||||
"AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n"
|
" AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n"
|
||||||
"AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub "
|
" AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub "
|
||||||
"option to INSTRIM)\n");
|
"option to INSTRIM)\n");
|
||||||
|
|
||||||
#ifdef AFL_CLANG_FLTO
|
#ifdef AFL_CLANG_FLTO
|
||||||
SAYF(
|
SAYF(
|
||||||
"\nafl-clang-lto specific environment variables:\n"
|
"\nafl-clang-lto specific environment variables:\n"
|
||||||
"AFL_LLVM_LTO_STARTID: from which ID to start counting from for a "
|
|
||||||
"bb\n"
|
|
||||||
"AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a "
|
"AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a "
|
||||||
"global var\n"
|
"global var\n"
|
||||||
|
"AFL_LLVM_LTO_STARTID: from which ID to start counting from for a "
|
||||||
|
"bb\n"
|
||||||
"AFL_REAL_LD: use this lld linker instead of the compiled in path\n"
|
"AFL_REAL_LD: use this lld linker instead of the compiled in path\n"
|
||||||
"\nafl-clang-lto was built with linker target \"%s\" and LTO flags "
|
"\nafl-clang-lto was built with linker target \"%s\" and LTO flags "
|
||||||
"\"%s\"\n"
|
"\"%s\"\n"
|
||||||
@ -796,6 +801,16 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 *ptr2;
|
||||||
|
if (!be_quiet && instrument_mode != INSTRUMENT_LTO &&
|
||||||
|
((ptr2 = getenv("AFL_MAP_SIZE")) || (ptr2 = getenv("AFL_MAPSIZE")))) {
|
||||||
|
|
||||||
|
u32 map_size = atoi(ptr2);
|
||||||
|
if (map_size != MAP_SIZE)
|
||||||
|
FATAL("AFL_MAP_SIZE is not supported by afl-clang-fast");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
|
||||||
SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd());
|
SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd());
|
||||||
|
@ -608,20 +608,22 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save highest location ID to global variable
|
}
|
||||||
// do this after each function to fail faster
|
|
||||||
if (afl_global_id > MAP_SIZE) {
|
|
||||||
|
|
||||||
uint32_t pow2map = 1, map = afl_global_id;
|
// save highest location ID to global variable
|
||||||
while ((map = map >> 1))
|
// do this after each function to fail faster
|
||||||
pow2map++;
|
if (!be_quiet && afl_global_id > MAP_SIZE) {
|
||||||
FATAL(
|
|
||||||
"We have %u blocks to instrument but the map size is only %u! Edit "
|
|
||||||
"config.h and set MAP_SIZE_POW2 from %u to %u, then recompile "
|
|
||||||
"afl-fuzz and llvm_mode.",
|
|
||||||
afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map);
|
|
||||||
|
|
||||||
}
|
uint32_t pow2map = 1, map = afl_global_id;
|
||||||
|
while ((map = map >> 1))
|
||||||
|
pow2map++;
|
||||||
|
WARNF(
|
||||||
|
"We have %u blocks to instrument but the map size is only %u. Either "
|
||||||
|
"edit config.h and set MAP_SIZE_POW2 from %u to %u, then recompile "
|
||||||
|
"afl-fuzz and llvm_mode and then make this target - or set "
|
||||||
|
"AFL_MAP_SIZE with at least size %u when running afl-fuzz with this "
|
||||||
|
"target.",
|
||||||
|
afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map, afl_global_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,7 +637,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
if (!f) {
|
if (!f) {
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error: init function could not be found (this hould not "
|
"Error: init function could not be found (this should not "
|
||||||
"happen)\n");
|
"happen)\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
||||||
|
@ -125,6 +125,7 @@ class AFLCoverage : public ModulePass {
|
|||||||
std::list<std::string> myWhitelist;
|
std::list<std::string> myWhitelist;
|
||||||
uint32_t ngram_size = 0;
|
uint32_t ngram_size = 0;
|
||||||
uint32_t debug = 0;
|
uint32_t debug = 0;
|
||||||
|
uint32_t map_size = MAP_SIZE;
|
||||||
char * ctx_str = NULL;
|
char * ctx_str = NULL;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -192,6 +193,19 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
|
|
||||||
be_quiet = 1;
|
be_quiet = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
char *ptr;
|
||||||
|
if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
|
||||||
|
|
||||||
|
map_size = atoi(ptr);
|
||||||
|
if (map_size < 8 || map_size > (1 << 29))
|
||||||
|
FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30",
|
||||||
|
map_size); if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/* Decide instrumentation ratio */
|
/* Decide instrumentation ratio */
|
||||||
|
|
||||||
char * inst_ratio_str = getenv("AFL_INST_RATIO");
|
char * inst_ratio_str = getenv("AFL_INST_RATIO");
|
||||||
@ -365,7 +379,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
// if yes we store a context ID for this function in the global var
|
// if yes we store a context ID for this function in the global var
|
||||||
if (has_calls) {
|
if (has_calls) {
|
||||||
|
|
||||||
ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(MAP_SIZE));
|
ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size));
|
||||||
StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext);
|
StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext);
|
||||||
StoreCtx->setMetadata(M.getMDKindID("nosanitize"),
|
StoreCtx->setMetadata(M.getMDKindID("nosanitize"),
|
||||||
MDNode::get(C, None));
|
MDNode::get(C, None));
|
||||||
@ -509,7 +523,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
/* Make up cur_loc */
|
/* Make up cur_loc */
|
||||||
|
|
||||||
// cur_loc++;
|
// cur_loc++;
|
||||||
cur_loc = AFL_R(MAP_SIZE);
|
cur_loc = AFL_R(map_size);
|
||||||
|
|
||||||
/* There is a problem with Ubuntu 18.04 and llvm 6.0 (see issue #63).
|
/* There is a problem with Ubuntu 18.04 and llvm 6.0 (see issue #63).
|
||||||
The inline function successors() is not inlined and also not found at runtime
|
The inline function successors() is not inlined and also not found at runtime
|
||||||
@ -705,6 +719,56 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// This is currently disabled because we not only need to create/insert a
|
||||||
|
// function (easy), but also add it as a constructor with an ID < 5
|
||||||
|
|
||||||
|
if (getenv("AFL_LLVM_DONTWRITEID") == NULL) {
|
||||||
|
|
||||||
|
// 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.o
|
||||||
|
|
||||||
|
Function *f = ...
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error: init function could not be created (this should not
|
||||||
|
happen)\n"); exit(-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
... constructor for f = 4
|
||||||
|
|
||||||
|
BasicBlock *bb = &f->getEntryBlock();
|
||||||
|
if (!bb) {
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error: init function does not have an EntryBlock (this should
|
||||||
|
not happen)\n"); exit(-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicBlock::iterator IP = bb->getFirstInsertionPt();
|
||||||
|
IRBuilder<> IRB(&(*IP));
|
||||||
|
|
||||||
|
if (map_size <= 0x800000) {
|
||||||
|
|
||||||
|
GlobalVariable *AFLFinalLoc = new GlobalVariable(
|
||||||
|
M, Int32Ty, true, GlobalValue::ExternalLinkage, 0,
|
||||||
|
"__afl_final_loc", 0, GlobalVariable::GeneralDynamicTLSModel, 0,
|
||||||
|
false);
|
||||||
|
ConstantInt *const_loc = ConstantInt::get(Int32Ty, map_size);
|
||||||
|
StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc);
|
||||||
|
StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"),
|
||||||
|
MDNode::get(C, None));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/* Say something nice. */
|
/* Say something nice. */
|
||||||
|
|
||||||
if (!be_quiet) {
|
if (!be_quiet) {
|
||||||
|
@ -233,7 +233,9 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then
|
|||||||
gcc test-instr.c -o test-instr || exit 1
|
gcc test-instr.c -o test-instr || exit 1
|
||||||
|
|
||||||
unset AFL_INST_RATIO
|
unset AFL_INST_RATIO
|
||||||
|
export ASAN_OPTIONS=detect_leaks=0
|
||||||
|
|
||||||
|
echo "[*] Comparing two afl-showmap -Q outputs..."
|
||||||
echo 0 | ./afl-showmap -m none -Q -q -o .test-instr0 ./test-instr || exit 1
|
echo 0 | ./afl-showmap -m none -Q -q -o .test-instr0 ./test-instr || exit 1
|
||||||
echo 1 | ./afl-showmap -m none -Q -q -o .test-instr1 ./test-instr || exit 1
|
echo 1 | ./afl-showmap -m none -Q -q -o .test-instr1 ./test-instr || exit 1
|
||||||
|
|
||||||
|
@ -293,8 +293,8 @@ static void print_mappings(void) {
|
|||||||
|
|
||||||
void afl_forkserver(CPUState *cpu) {
|
void afl_forkserver(CPUState *cpu) {
|
||||||
|
|
||||||
u32 map_size = 0;
|
u32 map_size = 0;
|
||||||
static unsigned char tmp[4] = {0, 0, 0, 0};
|
unsigned char tmp[4] = {0};
|
||||||
|
|
||||||
if (forkserver_installed == 1) return;
|
if (forkserver_installed == 1) return;
|
||||||
forkserver_installed = 1;
|
forkserver_installed = 1;
|
||||||
|
@ -84,6 +84,7 @@ static volatile u8 stop_soon, /* Ctrl-C pressed? */
|
|||||||
|
|
||||||
static u8 *target_path;
|
static u8 *target_path;
|
||||||
static u8 qemu_mode;
|
static u8 qemu_mode;
|
||||||
|
static u32 map_size = MAP_SIZE;
|
||||||
|
|
||||||
/* Constants used for describing byte behavior. */
|
/* Constants used for describing byte behavior. */
|
||||||
|
|
||||||
@ -115,7 +116,7 @@ static u8 count_class_lookup[256] = {
|
|||||||
|
|
||||||
static void classify_counts(u8 *mem) {
|
static void classify_counts(u8 *mem) {
|
||||||
|
|
||||||
u32 i = MAP_SIZE;
|
u32 i = map_size;
|
||||||
|
|
||||||
if (edges_only) {
|
if (edges_only) {
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ static void classify_counts(u8 *mem) {
|
|||||||
static inline u8 anything_set(void) {
|
static inline u8 anything_set(void) {
|
||||||
|
|
||||||
u32 *ptr = (u32 *)trace_bits;
|
u32 *ptr = (u32 *)trace_bits;
|
||||||
u32 i = (MAP_SIZE >> 2);
|
u32 i = (map_size >> 2);
|
||||||
|
|
||||||
while (i--)
|
while (i--)
|
||||||
if (*(ptr++)) return 1;
|
if (*(ptr++)) return 1;
|
||||||
@ -209,7 +210,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
|
|||||||
/* Execute target application. Returns exec checksum, or 0 if program
|
/* Execute target application. Returns exec checksum, or 0 if program
|
||||||
times out. */
|
times out. */
|
||||||
|
|
||||||
static u32 run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
||||||
|
|
||||||
static struct itimerval it;
|
static struct itimerval it;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
@ -217,7 +218,7 @@ static u32 run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
|||||||
s32 prog_in_fd;
|
s32 prog_in_fd;
|
||||||
u32 cksum;
|
u32 cksum;
|
||||||
|
|
||||||
memset(trace_bits, 0, MAP_SIZE);
|
memset(trace_bits, 0, map_size);
|
||||||
MEM_BARRIER();
|
MEM_BARRIER();
|
||||||
|
|
||||||
prog_in_fd = write_to_file(prog_in, mem, len);
|
prog_in_fd = write_to_file(prog_in, mem, len);
|
||||||
@ -311,7 +312,7 @@ static u32 run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);
|
cksum = hash32(trace_bits, map_size, HASH_CONST);
|
||||||
|
|
||||||
/* We don't actually care if the target is crashing or not,
|
/* We don't actually care if the target is crashing or not,
|
||||||
except that when it does, the checksum should be different. */
|
except that when it does, the checksum should be different. */
|
||||||
@ -560,16 +561,16 @@ static void analyze(char **argv) {
|
|||||||
code. */
|
code. */
|
||||||
|
|
||||||
in_data[i] ^= 0xff;
|
in_data[i] ^= 0xff;
|
||||||
xor_ff = run_target(argv, in_data, in_len, 0);
|
xor_ff = analyze_run_target(argv, in_data, in_len, 0);
|
||||||
|
|
||||||
in_data[i] ^= 0xfe;
|
in_data[i] ^= 0xfe;
|
||||||
xor_01 = run_target(argv, in_data, in_len, 0);
|
xor_01 = analyze_run_target(argv, in_data, in_len, 0);
|
||||||
|
|
||||||
in_data[i] = (in_data[i] ^ 0x01) - 0x10;
|
in_data[i] = (in_data[i] ^ 0x01) - 0x10;
|
||||||
sub_10 = run_target(argv, in_data, in_len, 0);
|
sub_10 = analyze_run_target(argv, in_data, in_len, 0);
|
||||||
|
|
||||||
in_data[i] += 0x20;
|
in_data[i] += 0x20;
|
||||||
add_10 = run_target(argv, in_data, in_len, 0);
|
add_10 = analyze_run_target(argv, in_data, in_len, 0);
|
||||||
in_data[i] -= 0x10;
|
in_data[i] -= 0x10;
|
||||||
|
|
||||||
/* Classify current behavior. */
|
/* Classify current behavior. */
|
||||||
@ -795,8 +796,10 @@ static void usage(u8 *argv0) {
|
|||||||
" (must contain abort_on_error=1 and symbolize=0)\n"
|
" (must contain abort_on_error=1 and symbolize=0)\n"
|
||||||
"MSAN_OPTIONS: custom settings for MSAN\n"
|
"MSAN_OPTIONS: custom settings for MSAN\n"
|
||||||
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
|
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
|
||||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
|
||||||
"AFL_ANALYZE_HEX: print file offsets in hexadecimal instead of decimal\n"
|
"AFL_ANALYZE_HEX: print file offsets in hexadecimal instead of decimal\n"
|
||||||
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
||||||
|
" the target was compiled for\n"
|
||||||
|
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||||
"AFL_SKIP_BIN_CHECK: skip checking the location of and the target\n"
|
"AFL_SKIP_BIN_CHECK: skip checking the location of and the target\n"
|
||||||
|
|
||||||
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
|
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
|
||||||
@ -805,61 +808,6 @@ static void usage(u8 *argv0) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find binary. */
|
|
||||||
|
|
||||||
static void find_binary(u8 *fname) {
|
|
||||||
|
|
||||||
u8 * env_path = 0;
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
|
|
||||||
|
|
||||||
target_path = ck_strdup(fname);
|
|
||||||
|
|
||||||
if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||
|
|
||||||
!(st.st_mode & 0111) || st.st_size < 4)
|
|
||||||
FATAL("Program '%s' not found or not executable", fname);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
while (env_path) {
|
|
||||||
|
|
||||||
u8 *cur_elem, *delim = strchr(env_path, ':');
|
|
||||||
|
|
||||||
if (delim) {
|
|
||||||
|
|
||||||
cur_elem = ck_alloc(delim - env_path + 1);
|
|
||||||
memcpy(cur_elem, env_path, delim - env_path);
|
|
||||||
delim++;
|
|
||||||
|
|
||||||
} else
|
|
||||||
|
|
||||||
cur_elem = ck_strdup(env_path);
|
|
||||||
|
|
||||||
env_path = delim;
|
|
||||||
|
|
||||||
if (cur_elem[0])
|
|
||||||
target_path = alloc_printf("%s/%s", cur_elem, fname);
|
|
||||||
else
|
|
||||||
target_path = ck_strdup(fname);
|
|
||||||
|
|
||||||
ck_free(cur_elem);
|
|
||||||
|
|
||||||
if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
|
|
||||||
(st.st_mode & 0111) && st.st_size >= 4)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ck_free(target_path);
|
|
||||||
target_path = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_path) FATAL("Program '%s' not found or not executable", fname);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main entry point */
|
/* Main entry point */
|
||||||
|
|
||||||
int main(int argc, char **argv, char **envp) {
|
int main(int argc, char **argv, char **envp) {
|
||||||
@ -902,7 +850,7 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
if (!optarg) { FATAL("Bad syntax used for -m"); }
|
if (!optarg) { FATAL("Wrong usage of -m"); }
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none")) {
|
||||||
|
|
||||||
@ -986,18 +934,20 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
if (optind == argc || !in_file) usage(argv[0]);
|
if (optind == argc || !in_file) usage(argv[0]);
|
||||||
|
|
||||||
|
map_size = get_map_size();
|
||||||
|
|
||||||
use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX");
|
use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX");
|
||||||
|
|
||||||
check_environment_vars(envp);
|
check_environment_vars(envp);
|
||||||
|
|
||||||
sharedmem_t shm = {0};
|
sharedmem_t shm = {0};
|
||||||
trace_bits = afl_shm_init(&shm, MAP_SIZE, 0);
|
trace_bits = afl_shm_init(&shm, map_size, 0);
|
||||||
atexit(at_exit_handler);
|
atexit(at_exit_handler);
|
||||||
setup_signal_handlers();
|
setup_signal_handlers();
|
||||||
|
|
||||||
set_up_environment();
|
set_up_environment();
|
||||||
|
|
||||||
find_binary(argv[optind]);
|
target_path = find_binary(argv[optind]);
|
||||||
detect_file_args(argv + optind, prog_in, &use_stdin);
|
detect_file_args(argv + optind, prog_in, &use_stdin);
|
||||||
|
|
||||||
if (qemu_mode) {
|
if (qemu_mode) {
|
||||||
@ -1020,7 +970,7 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
|
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
|
||||||
mem_limit, exec_tmout, edges_only ? ", edges only" : "");
|
mem_limit, exec_tmout, edges_only ? ", edges only" : "");
|
||||||
|
|
||||||
run_target(use_argv, in_data, in_len, 1);
|
analyze_run_target(use_argv, in_data, in_len, 1);
|
||||||
|
|
||||||
if (child_timed_out)
|
if (child_timed_out)
|
||||||
FATAL("Target binary times out (adjusting -t may help).");
|
FATAL("Target binary times out (adjusting -t may help).");
|
||||||
@ -1032,6 +982,8 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
OKF("We're done here. Have a nice day!\n");
|
OKF("We're done here. Have a nice day!\n");
|
||||||
|
|
||||||
|
if (target_path) ck_free(target_path);
|
||||||
|
|
||||||
afl_shm_deinit(&shm);
|
afl_shm_deinit(&shm);
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
115
src/afl-common.c
115
src/afl-common.c
@ -37,6 +37,10 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
u8 be_quiet = 0;
|
u8 be_quiet = 0;
|
||||||
u8 *doc_path = "";
|
u8 *doc_path = "";
|
||||||
@ -68,7 +72,7 @@ char *afl_environment_variables[] = {
|
|||||||
"AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
|
"AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
|
||||||
"AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
|
"AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
|
||||||
"AFL_NO_X86", // not really an env but we dont want to warn on it
|
"AFL_NO_X86", // not really an env but we dont want to warn on it
|
||||||
"AFL_PATH", "AFL_PERFORMANCE_FILE",
|
"AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE",
|
||||||
//"AFL_PERSISTENT", // not implemented anymore, so warn additionally
|
//"AFL_PERSISTENT", // not implemented anymore, so warn additionally
|
||||||
"AFL_POST_LIBRARY", "AFL_PRELOAD", "AFL_PYTHON_MODULE", "AFL_QEMU_COMPCOV",
|
"AFL_POST_LIBRARY", "AFL_PRELOAD", "AFL_PYTHON_MODULE", "AFL_QEMU_COMPCOV",
|
||||||
"AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE",
|
"AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE",
|
||||||
@ -218,10 +222,12 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
ck_free(own_copy);
|
ck_free(own_copy);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) {
|
if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) {
|
||||||
|
|
||||||
if (cp) ck_free(cp);
|
if (cp) ck_free(cp);
|
||||||
@ -353,6 +359,79 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find binary, used by analyze, showmap, tmin
|
||||||
|
@returns the path, allocating the string */
|
||||||
|
|
||||||
|
u8 *find_binary(u8 *fname) {
|
||||||
|
|
||||||
|
// TODO: Merge this function with check_binary of afl-fuzz-init.c
|
||||||
|
|
||||||
|
u8 *env_path = NULL;
|
||||||
|
u8 *target_path = NULL;
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
|
||||||
|
|
||||||
|
target_path = ck_strdup(fname);
|
||||||
|
|
||||||
|
if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||
|
||||||
|
!(st.st_mode & 0111) || st.st_size < 4) {
|
||||||
|
|
||||||
|
free(target_path);
|
||||||
|
FATAL("Program '%s' not found or not executable", fname);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while (env_path) {
|
||||||
|
|
||||||
|
u8 *cur_elem, *delim = strchr(env_path, ':');
|
||||||
|
|
||||||
|
if (delim) {
|
||||||
|
|
||||||
|
cur_elem = ck_alloc(delim - env_path + 1);
|
||||||
|
memcpy(cur_elem, env_path, delim - env_path);
|
||||||
|
delim++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cur_elem = ck_strdup(env_path);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
env_path = delim;
|
||||||
|
|
||||||
|
if (cur_elem[0]) {
|
||||||
|
|
||||||
|
target_path = alloc_printf("%s/%s", cur_elem, fname);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
target_path = ck_strdup(fname);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ck_free(cur_elem);
|
||||||
|
|
||||||
|
if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
|
||||||
|
(st.st_mode & 0111) && st.st_size >= 4)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ck_free(target_path);
|
||||||
|
target_path = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target_path) FATAL("Program '%s' not found or not executable", fname);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return target_path;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void check_environment_vars(char **envp) {
|
void check_environment_vars(char **envp) {
|
||||||
|
|
||||||
if (be_quiet) return;
|
if (be_quiet) return;
|
||||||
@ -414,6 +493,20 @@ char *get_afl_env(char *env) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read mask bitmap from file. This is for the -B option. */
|
||||||
|
|
||||||
|
void read_bitmap(u8 *fname, u8 *map, size_t len) {
|
||||||
|
|
||||||
|
s32 fd = open(fname, O_RDONLY);
|
||||||
|
|
||||||
|
if (fd < 0) PFATAL("Unable to open '%s'", fname);
|
||||||
|
|
||||||
|
ck_read(fd, map, len, fname);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
u64 get_cur_time(void) {
|
u64 get_cur_time(void) {
|
||||||
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@ -805,3 +898,21 @@ u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 get_map_size() {
|
||||||
|
|
||||||
|
uint32_t map_size = MAP_SIZE;
|
||||||
|
char * ptr;
|
||||||
|
|
||||||
|
if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
|
||||||
|
|
||||||
|
map_size = atoi(ptr);
|
||||||
|
if (map_size < 8 || map_size > (1 << 29))
|
||||||
|
FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size);
|
||||||
|
if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return map_size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
|||||||
void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
|
void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
|
||||||
|
|
||||||
fsrv_to->use_stdin = from->use_stdin;
|
fsrv_to->use_stdin = from->use_stdin;
|
||||||
|
fsrv_to->out_fd = from->out_fd;
|
||||||
fsrv_to->dev_null_fd = from->dev_null_fd;
|
fsrv_to->dev_null_fd = from->dev_null_fd;
|
||||||
fsrv_to->exec_tmout = from->exec_tmout;
|
fsrv_to->exec_tmout = from->exec_tmout;
|
||||||
fsrv_to->mem_limit = from->mem_limit;
|
fsrv_to->mem_limit = from->mem_limit;
|
||||||
@ -107,7 +108,6 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// These are forkserver specific.
|
// These are forkserver specific.
|
||||||
fsrv_to->out_fd = -1;
|
|
||||||
fsrv_to->out_dir_fd = -1;
|
fsrv_to->out_dir_fd = -1;
|
||||||
fsrv_to->child_pid = -1;
|
fsrv_to->child_pid = -1;
|
||||||
fsrv_to->use_fauxsrv = 0;
|
fsrv_to->use_fauxsrv = 0;
|
||||||
@ -395,7 +395,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
|
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
|
||||||
|
|
||||||
if (!be_quiet)
|
if (!be_quiet && getenv("AFL_DEBUG"))
|
||||||
ACTF("Extended forkserver functions received (%08x).", status);
|
ACTF("Extended forkserver functions received (%08x).", status);
|
||||||
|
|
||||||
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
|
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
|
||||||
@ -407,15 +407,26 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) {
|
if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) {
|
||||||
|
|
||||||
fsrv->map_size = FS_OPT_GET_MAPSIZE(status);
|
u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status);
|
||||||
if (fsrv->map_size % 8) // should not happen
|
|
||||||
fsrv->map_size = (((fsrv->map_size + 8) >> 3) << 3);
|
if (!fsrv->map_size) fsrv->map_size = MAP_SIZE;
|
||||||
if (!be_quiet) ACTF("Target map size: %u", fsrv->map_size);
|
|
||||||
if (fsrv->map_size > MAP_SIZE)
|
if (unlikely(tmp_map_size % 8)) {
|
||||||
|
|
||||||
|
// should not happen
|
||||||
|
WARNF("Target reported non-aligned map size of %ud", tmp_map_size);
|
||||||
|
tmp_map_size = (((tmp_map_size + 8) >> 3) << 3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!be_quiet) ACTF("Target map size: %u", tmp_map_size);
|
||||||
|
if (tmp_map_size > fsrv->map_size)
|
||||||
FATAL(
|
FATAL(
|
||||||
"Target's coverage map size of %u is larger than the one this "
|
"Target's coverage map size of %u is larger than the one this "
|
||||||
"afl++ is compiled with (%u)\n",
|
"afl++ is set with (%u) (change MAP_SIZE_POW2 in config.h and "
|
||||||
fsrv->map_size, MAP_SIZE);
|
"recompile or set AFL_MAP_SIZE)\n",
|
||||||
|
tmp_map_size, fsrv->map_size);
|
||||||
|
fsrv->map_size = tmp_map_size;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +455,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
u32 len = status, offset = 0, count = 0;
|
u32 len = status, offset = 0, count = 0;
|
||||||
u8 *dict = ck_alloc(len);
|
u8 *dict = ck_alloc(len);
|
||||||
if (dict == NULL)
|
if (dict == NULL)
|
||||||
FATAL("Could not allocate %u bytes of autodictionary memmory", len);
|
FATAL("Could not allocate %u bytes of autodictionary memory", len);
|
||||||
|
|
||||||
while (len != 0) {
|
while (len != 0) {
|
||||||
|
|
||||||
@ -695,10 +706,8 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
|
|||||||
/* Execute target application, monitoring for timeouts. Return status
|
/* Execute target application, monitoring for timeouts. Return status
|
||||||
information. The called program will update afl->fsrv->trace_bits. */
|
information. The called program will update afl->fsrv->trace_bits. */
|
||||||
|
|
||||||
fsrv_run_result_t afl_fsrv_run_target(
|
fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
||||||
afl_forkserver_t *fsrv, u32 timeout,
|
volatile u8 *stop_soon_p) {
|
||||||
void(classify_counts_func)(afl_forkserver_t *fsrv),
|
|
||||||
volatile u8 *stop_soon_p) {
|
|
||||||
|
|
||||||
s32 res;
|
s32 res;
|
||||||
u32 exec_ms;
|
u32 exec_ms;
|
||||||
@ -727,7 +736,7 @@ fsrv_run_result_t afl_fsrv_run_target(
|
|||||||
|
|
||||||
if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) {
|
if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) {
|
||||||
|
|
||||||
if (stop_soon_p) return 0;
|
if (*stop_soon_p) return 0;
|
||||||
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
|
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -784,9 +793,6 @@ fsrv_run_result_t afl_fsrv_run_target(
|
|||||||
behave very normally and do not have to be treated as volatile. */
|
behave very normally and do not have to be treated as volatile. */
|
||||||
|
|
||||||
MEM_BARRIER();
|
MEM_BARRIER();
|
||||||
u32 tb4 = *(u32 *)fsrv->trace_bits;
|
|
||||||
|
|
||||||
if (likely(classify_counts_func)) classify_counts_func(fsrv);
|
|
||||||
|
|
||||||
/* Report outcome to caller. */
|
/* Report outcome to caller. */
|
||||||
|
|
||||||
@ -811,7 +817,8 @@ fsrv_run_result_t afl_fsrv_run_target(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR;
|
// Fauxserver should handle this now.
|
||||||
|
// if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR;
|
||||||
|
|
||||||
return FSRV_RUN_OK;
|
return FSRV_RUN_OK;
|
||||||
|
|
||||||
|
@ -43,21 +43,7 @@ void write_bitmap(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", fname);
|
if (fd < 0) PFATAL("Unable to open '%s'", fname);
|
||||||
|
|
||||||
ck_write(fd, afl->virgin_bits, MAP_SIZE, fname);
|
ck_write(fd, afl->virgin_bits, afl->fsrv.map_size, fname);
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read bitmap from file. This is for the -B option again. */
|
|
||||||
|
|
||||||
void read_bitmap(afl_state_t *afl, u8 *fname) {
|
|
||||||
|
|
||||||
s32 fd = open(fname, O_RDONLY);
|
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", fname);
|
|
||||||
|
|
||||||
ck_read(fd, afl->virgin_bits, MAP_SIZE, fname);
|
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@ -88,7 +74,8 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
|
|||||||
u32 i = (afl->fsrv.map_size >> 2);
|
u32 i = (afl->fsrv.map_size >> 2);
|
||||||
|
|
||||||
#endif /* ^WORD_SIZE_64 */
|
#endif /* ^WORD_SIZE_64 */
|
||||||
if (i == 0) i = 1;
|
// the map size must be a minimum of 8 bytes.
|
||||||
|
// for variable/dynamic map sizes this is ensured in the forkserver
|
||||||
|
|
||||||
u8 ret = 0;
|
u8 ret = 0;
|
||||||
|
|
||||||
@ -98,6 +85,7 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
|
|||||||
that have not been already cleared from the virgin map - since this will
|
that have not been already cleared from the virgin map - since this will
|
||||||
almost always be the case. */
|
almost always be the case. */
|
||||||
|
|
||||||
|
// the (*current) is unnecessary but speeds up the overall comparison
|
||||||
if (unlikely(*current) && unlikely(*current & *virgin)) {
|
if (unlikely(*current) && unlikely(*current & *virgin)) {
|
||||||
|
|
||||||
if (likely(ret < 2)) {
|
if (likely(ret < 2)) {
|
||||||
@ -110,18 +98,20 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
|
|||||||
|
|
||||||
#ifdef WORD_SIZE_64
|
#ifdef WORD_SIZE_64
|
||||||
|
|
||||||
if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||
|
if (*virgin == 0xffffffffffffffff || (cur[0] && vir[0] == 0xff) ||
|
||||||
(cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff) ||
|
(cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) ||
|
||||||
(cur[4] && vir[4] == 0xff) || (cur[5] && vir[5] == 0xff) ||
|
(cur[3] && vir[3] == 0xff) || (cur[4] && vir[4] == 0xff) ||
|
||||||
(cur[6] && vir[6] == 0xff) || (cur[7] && vir[7] == 0xff))
|
(cur[5] && vir[5] == 0xff) || (cur[6] && vir[6] == 0xff) ||
|
||||||
|
(cur[7] && vir[7] == 0xff))
|
||||||
ret = 2;
|
ret = 2;
|
||||||
else
|
else
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||
|
if (*virgin == 0xffffffff || (cur[0] && vir[0] == 0xff) ||
|
||||||
(cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff))
|
(cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) ||
|
||||||
|
(cur[3] && vir[3] == 0xff))
|
||||||
ret = 2;
|
ret = 2;
|
||||||
else
|
else
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -139,7 +129,7 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(ret) && unlikely(virgin_map == afl->virgin_bits))
|
if (unlikely(ret) && likely(virgin_map == afl->virgin_bits))
|
||||||
afl->bitmap_changed = 1;
|
afl->bitmap_changed = 1;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -155,8 +145,6 @@ u32 count_bits(afl_state_t *afl, u8 *mem) {
|
|||||||
u32 i = (afl->fsrv.map_size >> 2);
|
u32 i = (afl->fsrv.map_size >> 2);
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
|
|
||||||
if (i == 0) i = 1;
|
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
u32 v = *(ptr++);
|
u32 v = *(ptr++);
|
||||||
@ -191,8 +179,6 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) {
|
|||||||
u32 i = (afl->fsrv.map_size >> 2);
|
u32 i = (afl->fsrv.map_size >> 2);
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
|
|
||||||
if (i == 0) i = 1;
|
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
u32 v = *(ptr++);
|
u32 v = *(ptr++);
|
||||||
@ -218,8 +204,6 @@ u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) {
|
|||||||
u32 i = (afl->fsrv.map_size >> 2);
|
u32 i = (afl->fsrv.map_size >> 2);
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
|
|
||||||
if (i == 0) i = 1;
|
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
u32 v = *(ptr++);
|
u32 v = *(ptr++);
|
||||||
@ -256,8 +240,6 @@ void simplify_trace(afl_state_t *afl, u64 *mem) {
|
|||||||
|
|
||||||
u32 i = (afl->fsrv.map_size >> 3);
|
u32 i = (afl->fsrv.map_size >> 3);
|
||||||
|
|
||||||
if (i == 0) i = 1;
|
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
/* Optimize for sparse bitmaps. */
|
/* Optimize for sparse bitmaps. */
|
||||||
@ -291,8 +273,6 @@ void simplify_trace(afl_state_t *afl, u32 *mem) {
|
|||||||
|
|
||||||
u32 i = (afl->fsrv.map_size >> 2);
|
u32 i = (afl->fsrv.map_size >> 2);
|
||||||
|
|
||||||
if (i == 0) i = 1;
|
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
/* Optimize for sparse bitmaps. */
|
/* Optimize for sparse bitmaps. */
|
||||||
@ -357,8 +337,6 @@ void classify_counts(afl_forkserver_t *fsrv) {
|
|||||||
|
|
||||||
u32 i = (fsrv->map_size >> 3);
|
u32 i = (fsrv->map_size >> 3);
|
||||||
|
|
||||||
if (i == 0) i = 1;
|
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
/* Optimize for sparse bitmaps. */
|
/* Optimize for sparse bitmaps. */
|
||||||
@ -388,8 +366,6 @@ void classify_counts(afl_forkserver_t *fsrv) {
|
|||||||
|
|
||||||
u32 i = (fsrv->map_size >> 2);
|
u32 i = (fsrv->map_size >> 2);
|
||||||
|
|
||||||
if (i == 0) i = 1;
|
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
/* Optimize for sparse bitmaps. */
|
/* Optimize for sparse bitmaps. */
|
||||||
@ -649,7 +625,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
|
|
||||||
u8 new_fault;
|
u8 new_fault;
|
||||||
write_to_testcase(afl, mem, len);
|
write_to_testcase(afl, mem, len);
|
||||||
new_fault = run_target(afl, &afl->fsrv, afl->hang_tmout);
|
new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
|
||||||
|
|
||||||
/* A corner case that one user reported bumping into: increasing the
|
/* A corner case that one user reported bumping into: increasing the
|
||||||
timeout actually uncovers a crash. Make sure we don't discard it if
|
timeout actually uncovers a crash. Make sure we don't discard it if
|
||||||
|
@ -62,7 +62,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
write_to_testcase(afl, out_buf, len);
|
write_to_testcase(afl, out_buf, len);
|
||||||
|
|
||||||
fault = run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
if (afl->stop_soon) return 1;
|
if (afl->stop_soon) return 1;
|
||||||
|
|
||||||
|
@ -442,23 +442,6 @@ void read_testcases(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Examine map coverage. Called once, for first test case. */
|
|
||||||
|
|
||||||
static void check_map_coverage(afl_state_t *afl) {
|
|
||||||
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
if (count_bytes(afl, afl->fsrv.trace_bits) < 100) return;
|
|
||||||
|
|
||||||
for (i = (1 << (MAP_SIZE_POW2 - 1)); i < MAP_SIZE; ++i)
|
|
||||||
if (afl->fsrv.trace_bits[i]) return;
|
|
||||||
|
|
||||||
if (afl->fsrv.map_size != MAP_SIZE) return;
|
|
||||||
|
|
||||||
WARNF("Recompile binary with newer version of afl to improve coverage!");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perform dry run of all test cases to confirm that the app is working as
|
/* Perform dry run of all test cases to confirm that the app is working as
|
||||||
expected. This is done only for the initial inputs, and only once. */
|
expected. This is done only for the initial inputs, and only once. */
|
||||||
|
|
||||||
@ -501,8 +484,6 @@ void perform_dry_run(afl_state_t *afl) {
|
|||||||
|
|
||||||
case FSRV_RUN_OK:
|
case FSRV_RUN_OK:
|
||||||
|
|
||||||
if (q == afl->queue) check_map_coverage(afl);
|
|
||||||
|
|
||||||
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;
|
break;
|
||||||
@ -1419,6 +1400,8 @@ void setup_dirs_fds(afl_state_t *afl) {
|
|||||||
"# unix_time, cycles_done, cur_path, paths_total, "
|
"# unix_time, cycles_done, cur_path, paths_total, "
|
||||||
"pending_total, pending_favs, map_size, unique_crashes, "
|
"pending_total, pending_favs, map_size, unique_crashes, "
|
||||||
"unique_hangs, max_depth, execs_per_sec\n");
|
"unique_hangs, max_depth, execs_per_sec\n");
|
||||||
|
fflush(afl->fsrv.plot_file);
|
||||||
|
|
||||||
/* ignore errors */
|
/* ignore errors */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,6 @@
|
|||||||
#include "afl-fuzz.h"
|
#include "afl-fuzz.h"
|
||||||
|
|
||||||
void load_custom_mutator(afl_state_t *, const char *);
|
void load_custom_mutator(afl_state_t *, const char *);
|
||||||
#ifdef USE_PYTHON
|
|
||||||
void load_custom_mutator_py(afl_state_t *, char *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void setup_custom_mutator(afl_state_t *afl) {
|
void setup_custom_mutator(afl_state_t *afl) {
|
||||||
|
|
||||||
@ -239,7 +236,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
write_to_testcase(afl, retbuf, retlen);
|
write_to_testcase(afl, retbuf, retlen);
|
||||||
|
|
||||||
fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
++afl->trim_execs;
|
++afl->trim_execs;
|
||||||
|
|
||||||
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
|
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
/* MOpt */
|
/* MOpt */
|
||||||
|
|
||||||
int select_algorithm(afl_state_t *afl) {
|
static int select_algorithm(afl_state_t *afl) {
|
||||||
|
|
||||||
int i_puppet, j_puppet;
|
int i_puppet, j_puppet;
|
||||||
|
|
||||||
@ -2366,7 +2366,7 @@ abandon_entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* MOpt mode */
|
/* MOpt mode */
|
||||||
u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
||||||
|
|
||||||
if (!MOpt_globals.is_pilot_mode) {
|
if (!MOpt_globals.is_pilot_mode) {
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
|
|||||||
(void **)&((py_mutator_t *)py_mutator)->name##_buf, \
|
(void **)&((py_mutator_t *)py_mutator)->name##_buf, \
|
||||||
&((py_mutator_t *)py_mutator)->name##_size
|
&((py_mutator_t *)py_mutator)->name##_size
|
||||||
|
|
||||||
size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
|
static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
|
||||||
u8 *add_buf, size_t add_buf_size, size_t max_size) {
|
u8 *add_buf, size_t add_buf_size, size_t max_size) {
|
||||||
|
|
||||||
size_t mutated_size;
|
size_t mutated_size;
|
||||||
PyObject *py_args, *py_value;
|
PyObject *py_args, *py_value;
|
||||||
|
@ -249,7 +249,6 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
if (!q->trace_mini) {
|
if (!q->trace_mini) {
|
||||||
|
|
||||||
u32 len = (afl->fsrv.map_size >> 3);
|
u32 len = (afl->fsrv.map_size >> 3);
|
||||||
if (len == 0) len = 1;
|
|
||||||
q->trace_mini = ck_alloc(len);
|
q->trace_mini = ck_alloc(len);
|
||||||
minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits);
|
minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits);
|
||||||
|
|
||||||
@ -272,12 +271,12 @@ void cull_queue(afl_state_t *afl) {
|
|||||||
struct queue_entry *q;
|
struct queue_entry *q;
|
||||||
u32 len = (afl->fsrv.map_size >> 3);
|
u32 len = (afl->fsrv.map_size >> 3);
|
||||||
u32 i;
|
u32 i;
|
||||||
u8 temp_v[MAP_SIZE >> 3];
|
u8 * temp_v;
|
||||||
|
|
||||||
if (len == 0) len = 1;
|
|
||||||
|
|
||||||
if (afl->dumb_mode || !afl->score_changed) return;
|
if (afl->dumb_mode || !afl->score_changed) return;
|
||||||
|
|
||||||
|
temp_v = ck_maybe_grow((void **)&afl->map_tmp_buf, &afl->map_tmp_size, afl->fsrv.map_size >> 3);
|
||||||
|
|
||||||
afl->score_changed = 0;
|
afl->score_changed = 0;
|
||||||
|
|
||||||
memset(temp_v, 255, len);
|
memset(temp_v, 255, len);
|
||||||
|
@ -37,7 +37,7 @@ struct range {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct range *add_range(struct range *ranges, u32 start, u32 end) {
|
static struct range *add_range(struct range *ranges, u32 start, u32 end) {
|
||||||
|
|
||||||
struct range *r = ck_alloc_nozero(sizeof(struct range));
|
struct range *r = ck_alloc_nozero(sizeof(struct range));
|
||||||
r->start = start;
|
r->start = start;
|
||||||
@ -47,7 +47,7 @@ struct range *add_range(struct range *ranges, u32 start, u32 end) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct range *pop_biggest_range(struct range **ranges) {
|
static struct range *pop_biggest_range(struct range **ranges) {
|
||||||
|
|
||||||
struct range *r = *ranges;
|
struct range *r = *ranges;
|
||||||
struct range *prev = NULL;
|
struct range *prev = NULL;
|
||||||
|
@ -33,10 +33,13 @@
|
|||||||
/* Execute target application, monitoring for timeouts. Return status
|
/* Execute target application, monitoring for timeouts. Return status
|
||||||
information. The called program will update afl->fsrv->trace_bits. */
|
information. The called program will update afl->fsrv->trace_bits. */
|
||||||
|
|
||||||
fsrv_run_result_t run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
|
fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv,
|
||||||
u32 timeout) {
|
u32 timeout) {
|
||||||
|
|
||||||
return afl_fsrv_run_target(fsrv, timeout, classify_counts, &afl->stop_soon);
|
fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon);
|
||||||
|
// TODO: Don't classify for faults?
|
||||||
|
classify_counts(fsrv);
|
||||||
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +53,7 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
|
|||||||
s32 doc_fd;
|
s32 doc_fd;
|
||||||
char fn[PATH_MAX];
|
char fn[PATH_MAX];
|
||||||
snprintf(fn, PATH_MAX, "%s/mutations/%09u:%s", afl->out_dir,
|
snprintf(fn, PATH_MAX, "%s/mutations/%09u:%s", afl->out_dir,
|
||||||
afl->document_counter++, describe_op(afl, 0));
|
afl->document_counter++, describe_op(afl, 0));
|
||||||
|
|
||||||
if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
|
if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
|
||||||
|
|
||||||
@ -188,7 +191,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
|
|
||||||
write_to_testcase(afl, use_mem, q->len);
|
write_to_testcase(afl, use_mem, q->len);
|
||||||
|
|
||||||
fault = run_target(afl, &afl->fsrv, use_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
|
||||||
|
|
||||||
/* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
|
/* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
|
||||||
we want to bail out quickly. */
|
we want to bail out quickly. */
|
||||||
@ -406,7 +409,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
|
|
||||||
write_to_testcase(afl, mem, st.st_size);
|
write_to_testcase(afl, mem, st.st_size);
|
||||||
|
|
||||||
fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
if (afl->stop_soon) goto close_sync;
|
if (afl->stop_soon) goto close_sync;
|
||||||
|
|
||||||
@ -493,7 +496,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail);
|
write_with_gap(afl, in_buf, q->len, remove_pos, trim_avail);
|
||||||
|
|
||||||
fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
++afl->trim_execs;
|
++afl->trim_execs;
|
||||||
|
|
||||||
if (afl->stop_soon || fault == FSRV_RUN_ERROR) goto abort_trimming;
|
if (afl->stop_soon || fault == FSRV_RUN_ERROR) goto abort_trimming;
|
||||||
@ -600,7 +603,7 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
write_to_testcase(afl, out_buf, len);
|
write_to_testcase(afl, out_buf, len);
|
||||||
|
|
||||||
fault = run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
if (afl->stop_soon) return 1;
|
if (afl->stop_soon) return 1;
|
||||||
|
|
||||||
|
@ -75,12 +75,14 @@ list_t afl_states = {.element_prealloc_count = 0};
|
|||||||
|
|
||||||
/* Initializes an afl_state_t. */
|
/* Initializes an afl_state_t. */
|
||||||
|
|
||||||
void afl_state_init(afl_state_t *afl) {
|
void afl_state_init(afl_state_t *afl, uint32_t map_size) {
|
||||||
|
|
||||||
/* thanks to this memset, growing vars like out_buf
|
/* thanks to this memset, growing vars like out_buf
|
||||||
and out_size are NULL/0 by default. */
|
and out_size are NULL/0 by default. */
|
||||||
memset(afl, 0, sizeof(afl_state_t));
|
memset(afl, 0, sizeof(afl_state_t));
|
||||||
|
|
||||||
|
if (!map_size) afl->shm.map_size = MAP_SIZE;
|
||||||
|
|
||||||
afl->w_init = 0.9;
|
afl->w_init = 0.9;
|
||||||
afl->w_end = 0.3;
|
afl->w_end = 0.3;
|
||||||
afl->g_max = 5000;
|
afl->g_max = 5000;
|
||||||
@ -97,9 +99,17 @@ void afl_state_init(afl_state_t *afl) {
|
|||||||
afl->cpu_aff = -1; /* Selected CPU core */
|
afl->cpu_aff = -1; /* Selected CPU core */
|
||||||
#endif /* HAVE_AFFINITY */
|
#endif /* HAVE_AFFINITY */
|
||||||
|
|
||||||
afl->fsrv.use_stdin = 1;
|
afl->virgin_bits = ck_alloc(map_size);
|
||||||
|
afl->virgin_tmout = ck_alloc(map_size);
|
||||||
|
afl->virgin_crash = ck_alloc(map_size);
|
||||||
|
afl->var_bytes = ck_alloc(map_size);
|
||||||
|
afl->top_rated = ck_alloc(map_size * sizeof(void *));
|
||||||
|
afl->clean_trace = ck_alloc(map_size);
|
||||||
|
afl->clean_trace_custom = ck_alloc(map_size);
|
||||||
|
afl->first_trace = ck_alloc(map_size);
|
||||||
|
|
||||||
afl->fsrv.map_size = MAP_SIZE;
|
afl->fsrv.use_stdin = 1;
|
||||||
|
afl->fsrv.map_size = map_size;
|
||||||
afl->fsrv.function_opt = (u8 *)afl;
|
afl->fsrv.function_opt = (u8 *)afl;
|
||||||
afl->fsrv.function_ptr = &maybe_add_auto;
|
afl->fsrv.function_ptr = &maybe_add_auto;
|
||||||
|
|
||||||
@ -364,12 +374,21 @@ void afl_state_deinit(afl_state_t *afl) {
|
|||||||
if (afl->pass_stats) ck_free(afl->pass_stats);
|
if (afl->pass_stats) ck_free(afl->pass_stats);
|
||||||
if (afl->orig_cmp_map) ck_free(afl->orig_cmp_map);
|
if (afl->orig_cmp_map) ck_free(afl->orig_cmp_map);
|
||||||
|
|
||||||
free(afl->out_buf);
|
if (afl->out_buf) free(afl->out_buf);
|
||||||
free(afl->out_scratch_buf);
|
if (afl->out_scratch_buf) free(afl->out_scratch_buf);
|
||||||
free(afl->eff_buf);
|
if (afl->eff_buf) free(afl->eff_buf);
|
||||||
free(afl->in_buf);
|
if (afl->in_buf) free(afl->in_buf);
|
||||||
free(afl->in_scratch_buf);
|
if (afl->in_scratch_buf) free(afl->in_scratch_buf);
|
||||||
free(afl->ex_buf);
|
if (afl->ex_buf) free(afl->ex_buf);
|
||||||
|
|
||||||
|
ck_free(afl->virgin_bits);
|
||||||
|
ck_free(afl->virgin_tmout);
|
||||||
|
ck_free(afl->virgin_crash);
|
||||||
|
ck_free(afl->var_bytes);
|
||||||
|
ck_free(afl->top_rated);
|
||||||
|
ck_free(afl->clean_trace);
|
||||||
|
ck_free(afl->clean_trace_custom);
|
||||||
|
ck_free(afl->first_trace);
|
||||||
|
|
||||||
list_remove(&afl_states, afl);
|
list_remove(&afl_states, afl);
|
||||||
|
|
||||||
|
@ -145,14 +145,15 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
|
|
||||||
void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
|
void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
|
||||||
|
|
||||||
if (afl->plot_prev_qp == afl->queued_paths &&
|
if (unlikely(afl->plot_prev_qp == afl->queued_paths &&
|
||||||
afl->plot_prev_pf == afl->pending_favored &&
|
afl->plot_prev_pf == afl->pending_favored &&
|
||||||
afl->plot_prev_pnf == afl->pending_not_fuzzed &&
|
afl->plot_prev_pnf == afl->pending_not_fuzzed &&
|
||||||
afl->plot_prev_ce == afl->current_entry &&
|
afl->plot_prev_ce == afl->current_entry &&
|
||||||
afl->plot_prev_qc == afl->queue_cycle &&
|
afl->plot_prev_qc == afl->queue_cycle &&
|
||||||
afl->plot_prev_uc == afl->unique_crashes &&
|
afl->plot_prev_uc == afl->unique_crashes &&
|
||||||
afl->plot_prev_uh == afl->unique_hangs &&
|
afl->plot_prev_uh == afl->unique_hangs &&
|
||||||
afl->plot_prev_md == afl->max_depth)
|
afl->plot_prev_md == afl->max_depth) ||
|
||||||
|
unlikely(!afl->queue_cycle))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
afl->plot_prev_qp = afl->queued_paths;
|
afl->plot_prev_qp = afl->queued_paths;
|
||||||
@ -388,9 +389,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* Lord, forgive me this. */
|
/* Lord, forgive me this. */
|
||||||
|
|
||||||
SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
|
SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
|
||||||
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
|
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
|
||||||
" overall results " bSTG bH2 bH2 bRT "\n");
|
" overall results " bSTG bH2 bH2 bRT "\n");
|
||||||
|
|
||||||
if (afl->dumb_mode) {
|
if (afl->dumb_mode) {
|
||||||
|
|
||||||
@ -472,9 +473,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
|
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
|
||||||
time_tmp, tmp);
|
time_tmp, tmp);
|
||||||
|
|
||||||
SAYF(bVR bH bSTOP cCYA
|
SAYF(bVR bH bSTOP cCYA
|
||||||
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
|
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
|
||||||
" map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
|
" map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
|
||||||
|
|
||||||
/* This gets funny because we want to print several variable-length variables
|
/* This gets funny because we want to print several variable-length variables
|
||||||
together, but then cram them into a fixed-width field - so we need to
|
together, but then cram them into a fixed-width field - so we need to
|
||||||
@ -504,9 +505,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
|
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
|
||||||
|
|
||||||
SAYF(bVR bH bSTOP cCYA
|
SAYF(bVR bH bSTOP cCYA
|
||||||
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
|
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
|
||||||
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
|
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
|
||||||
|
|
||||||
sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
|
sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
|
||||||
((double)afl->queued_favored) * 100 / afl->queued_paths);
|
((double)afl->queued_favored) * 100 / afl->queued_paths);
|
||||||
@ -580,7 +581,7 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* Aaaalmost there... hold on! */
|
/* Aaaalmost there... hold on! */
|
||||||
|
|
||||||
SAYF(bVR bH cCYA bSTOP
|
SAYF(bVR bH cCYA bSTOP
|
||||||
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
|
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
|
||||||
" path geometry " bSTG bH5 bH2 bVL "\n");
|
" path geometry " bSTG bH5 bH2 bVL "\n");
|
||||||
|
|
||||||
|
@ -150,44 +150,46 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
|||||||
if (more_help > 1)
|
if (more_help > 1)
|
||||||
SAYF(
|
SAYF(
|
||||||
"Environment variables used:\n"
|
"Environment variables used:\n"
|
||||||
"AFL_PATH: path to AFL support binaries\n"
|
|
||||||
"AFL_QUIET: suppress forkserver status messages\n"
|
|
||||||
"AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n"
|
|
||||||
"LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
|
"LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
|
||||||
"AFL_BENCH_JUST_ONE: run the target just once\n"
|
|
||||||
"AFL_DUMB_FORKSRV: use fork server without feedback from target\n"
|
|
||||||
"AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs\n"
|
|
||||||
"AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n"
|
|
||||||
"AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
|
|
||||||
"AFL_DEBUG: extra debugging output for Python mode trimming\n"
|
|
||||||
"AFL_DISABLE_TRIM: disable the trimming of test cases\n"
|
|
||||||
"AFL_NO_UI: switch status screen off\n"
|
|
||||||
"AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n"
|
|
||||||
"AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n"
|
|
||||||
"AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
|
|
||||||
"AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n"
|
|
||||||
"AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n"
|
|
||||||
"AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n"
|
|
||||||
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
|
|
||||||
"AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n"
|
|
||||||
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
|
|
||||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
|
||||||
"AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
|
|
||||||
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
|
|
||||||
"AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n"
|
|
||||||
"AFL_POST_LIBRARY: postprocess generated test cases before use as target input\n"
|
|
||||||
"AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n"
|
|
||||||
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
|
|
||||||
"ASAN_OPTIONS: custom settings for ASAN\n"
|
"ASAN_OPTIONS: custom settings for ASAN\n"
|
||||||
" (must contain abort_on_error=1 and symbolize=0)\n"
|
" (must contain abort_on_error=1 and symbolize=0)\n"
|
||||||
"MSAN_OPTIONS: custom settings for MSAN\n"
|
"MSAN_OPTIONS: custom settings for MSAN\n"
|
||||||
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
|
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
|
||||||
|
"AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n"
|
||||||
|
"AFL_BENCH_JUST_ONE: run the target just once\n"
|
||||||
|
"AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n"
|
||||||
|
"AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs\n"
|
||||||
|
"AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n"
|
||||||
|
"AFL_DEBUG: extra debugging output for Python mode trimming\n"
|
||||||
|
"AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n"
|
||||||
|
"AFL_DISABLE_TRIM: disable the trimming of test cases\n"
|
||||||
|
"AFL_DUMB_FORKSRV: use fork server without feedback from target\n"
|
||||||
|
"AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n"
|
||||||
|
"AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n"
|
||||||
|
"AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n"
|
||||||
|
"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_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
|
||||||
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
||||||
|
" the target was compiled for\n"
|
||||||
|
"AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n"
|
||||||
|
"AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n"
|
||||||
|
"AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n"
|
||||||
|
"AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n"
|
||||||
|
"AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n"
|
||||||
|
"AFL_NO_UI: switch status screen off\n"
|
||||||
|
"AFL_PATH: path to AFL support binaries\n"
|
||||||
|
"AFL_POST_LIBRARY: postprocess generated test cases before use as target input\n"
|
||||||
|
"AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
|
||||||
|
"AFL_QUIET: suppress forkserver status messages\n"
|
||||||
|
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||||
|
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
|
||||||
"AFL_SKIP_BIN_CHECK: skip the check, if the target is an excutable\n"
|
"AFL_SKIP_BIN_CHECK: skip the check, if the target is an excutable\n"
|
||||||
|
"AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
|
||||||
|
"AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n"
|
||||||
|
"AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
|
||||||
//"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n"
|
//"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n"
|
||||||
//"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n"
|
//"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n"
|
||||||
"AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n"
|
|
||||||
"AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n"
|
|
||||||
"AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
@ -231,7 +233,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
s32 opt;
|
s32 opt;
|
||||||
u64 prev_queued = 0;
|
u64 prev_queued = 0;
|
||||||
u32 sync_interval_cnt = 0, seek_to, show_help = 0;
|
u32 sync_interval_cnt = 0, seek_to, show_help = 0, map_size = MAP_SIZE;
|
||||||
u8 * extras_dir = 0;
|
u8 * extras_dir = 0;
|
||||||
u8 mem_limit_given = 0, exit_1 = 0;
|
u8 mem_limit_given = 0, exit_1 = 0;
|
||||||
char **use_argv;
|
char **use_argv;
|
||||||
@ -244,11 +246,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl_state_t *afl = calloc(1, sizeof(afl_state_t));
|
afl_state_t *afl = calloc(1, sizeof(afl_state_t));
|
||||||
if (!afl) { FATAL("Could not create afl state"); }
|
if (!afl) { FATAL("Could not create afl state"); }
|
||||||
|
|
||||||
afl_state_init(afl);
|
if (get_afl_env("AFL_DEBUG")) afl->debug = 1;
|
||||||
|
|
||||||
|
map_size = get_map_size();
|
||||||
|
afl_state_init(afl, map_size);
|
||||||
afl_fsrv_init(&afl->fsrv);
|
afl_fsrv_init(&afl->fsrv);
|
||||||
|
|
||||||
if (get_afl_env("AFL_DEBUG")) afl->debug = 1;
|
|
||||||
read_afl_environment(afl, envp);
|
read_afl_environment(afl, envp);
|
||||||
|
if (afl->shm.map_size) afl->fsrv.map_size = afl->shm.map_size;
|
||||||
exit_1 = !!afl->afl_env.afl_bench_just_one;
|
exit_1 = !!afl->afl_env.afl_bench_just_one;
|
||||||
|
|
||||||
SAYF(cCYA "afl-fuzz" VERSION cRST
|
SAYF(cCYA "afl-fuzz" VERSION cRST
|
||||||
@ -420,6 +425,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
|
if (!optarg) FATAL("Wrong usage of -m");
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none")) {
|
||||||
|
|
||||||
afl->fsrv.mem_limit = 0;
|
afl->fsrv.mem_limit = 0;
|
||||||
@ -474,7 +481,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (afl->in_bitmap) FATAL("Multiple -B options not supported");
|
if (afl->in_bitmap) FATAL("Multiple -B options not supported");
|
||||||
|
|
||||||
afl->in_bitmap = optarg;
|
afl->in_bitmap = optarg;
|
||||||
read_bitmap(afl, afl->in_bitmap);
|
read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C': /* crash mode */
|
case 'C': /* crash mode */
|
||||||
@ -908,13 +915,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
check_crash_handling();
|
check_crash_handling();
|
||||||
check_cpu_governor(afl);
|
check_cpu_governor(afl);
|
||||||
|
|
||||||
afl->fsrv.trace_bits = afl_shm_init(&afl->shm, MAP_SIZE, afl->dumb_mode);
|
afl->fsrv.trace_bits =
|
||||||
|
afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->dumb_mode);
|
||||||
|
|
||||||
setup_post(afl);
|
setup_post(afl);
|
||||||
|
|
||||||
if (!afl->in_bitmap) memset(afl->virgin_bits, 255, MAP_SIZE);
|
if (!afl->in_bitmap) memset(afl->virgin_bits, 255, afl->fsrv.map_size);
|
||||||
memset(afl->virgin_tmout, 255, MAP_SIZE);
|
memset(afl->virgin_tmout, 255, afl->fsrv.map_size);
|
||||||
memset(afl->virgin_crash, 255, MAP_SIZE);
|
memset(afl->virgin_crash, 255, afl->fsrv.map_size);
|
||||||
|
|
||||||
init_count_class16();
|
init_count_class16();
|
||||||
|
|
||||||
|
@ -411,6 +411,15 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 *ptr;
|
||||||
|
if (!be_quiet &&
|
||||||
|
((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE")))) {
|
||||||
|
|
||||||
|
u32 map_size = atoi(ptr);
|
||||||
|
if (map_size != MAP_SIZE) FATAL("AFL_MAP_SIZE is not supported by afl-gcc");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
find_as(argv[0]);
|
find_as(argv[0]);
|
||||||
|
|
||||||
edit_params(argc, argv);
|
edit_params(argc, argv);
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
list_t shm_list = {.element_prealloc_count = 0};
|
static list_t shm_list = {.element_prealloc_count = 0};
|
||||||
|
|
||||||
/* Get rid of shared memory. */
|
/* Get rid of shared memory. */
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ void afl_shm_deinit(sharedmem_t *shm) {
|
|||||||
#ifdef USEMMAP
|
#ifdef USEMMAP
|
||||||
if (shm->map != NULL) {
|
if (shm->map != NULL) {
|
||||||
|
|
||||||
munmap(shm->map, shm->size_alloc);
|
munmap(shm->map, shm->map_size);
|
||||||
shm->map = NULL;
|
shm->map = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ void afl_shm_deinit(sharedmem_t *shm) {
|
|||||||
|
|
||||||
u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
|
u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
|
||||||
|
|
||||||
shm->size_alloc = shm->size_used = map_size;
|
shm->map_size = map_size;
|
||||||
|
|
||||||
shm->map = NULL;
|
shm->map = NULL;
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -63,8 +64,7 @@
|
|||||||
static char *stdin_file; /* stdin file */
|
static char *stdin_file; /* stdin file */
|
||||||
|
|
||||||
static u8 *in_dir = NULL, /* input folder */
|
static u8 *in_dir = NULL, /* input folder */
|
||||||
*out_file = NULL,
|
*out_file = NULL, *at_file = NULL; /* Substitution string for @@ */
|
||||||
*at_file = NULL; /* Substitution string for @@ */
|
|
||||||
|
|
||||||
static u8 *in_data; /* Input data */
|
static u8 *in_data; /* Input data */
|
||||||
|
|
||||||
@ -73,6 +73,8 @@ static u32 total, highest; /* tuple content information */
|
|||||||
static u32 in_len, /* Input data length */
|
static u32 in_len, /* Input data length */
|
||||||
arg_offset; /* Total number of execs */
|
arg_offset; /* Total number of execs */
|
||||||
|
|
||||||
|
static u32 map_size = MAP_SIZE;
|
||||||
|
|
||||||
static u8 quiet_mode, /* Hide non-essential messages? */
|
static u8 quiet_mode, /* Hide non-essential messages? */
|
||||||
edges_only, /* Ignore hit counts? */
|
edges_only, /* Ignore hit counts? */
|
||||||
raw_instr_output, /* Do not apply AFL filters */
|
raw_instr_output, /* Do not apply AFL filters */
|
||||||
@ -113,7 +115,7 @@ static void classify_counts(afl_forkserver_t *fsrv) {
|
|||||||
u8 * mem = fsrv->trace_bits;
|
u8 * mem = fsrv->trace_bits;
|
||||||
const u8 *map = binary_mode ? count_class_binary : count_class_human;
|
const u8 *map = binary_mode ? count_class_binary : count_class_human;
|
||||||
|
|
||||||
u32 i = MAP_SIZE;
|
u32 i = map_size;
|
||||||
|
|
||||||
if (edges_only) {
|
if (edges_only) {
|
||||||
|
|
||||||
@ -176,10 +178,10 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
|
|||||||
|
|
||||||
if (binary_mode) {
|
if (binary_mode) {
|
||||||
|
|
||||||
for (i = 0; i < MAP_SIZE; i++)
|
for (i = 0; i < map_size; i++)
|
||||||
if (fsrv->trace_bits[i]) ret++;
|
if (fsrv->trace_bits[i]) ret++;
|
||||||
|
|
||||||
ck_write(fd, fsrv->trace_bits, MAP_SIZE, outfile);
|
ck_write(fd, fsrv->trace_bits, map_size, outfile);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -188,7 +190,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
|
|||||||
|
|
||||||
if (!f) PFATAL("fdopen() failed");
|
if (!f) PFATAL("fdopen() failed");
|
||||||
|
|
||||||
for (i = 0; i < MAP_SIZE; i++) {
|
for (i = 0; i < map_size; i++) {
|
||||||
|
|
||||||
if (!fsrv->trace_bits[i]) continue;
|
if (!fsrv->trace_bits[i]) continue;
|
||||||
ret++;
|
ret++;
|
||||||
@ -219,18 +221,20 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
|
|||||||
|
|
||||||
/* Execute target application. */
|
/* Execute target application. */
|
||||||
|
|
||||||
void run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
|
static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv,
|
||||||
u32 len) {
|
u8 *mem, u32 len) {
|
||||||
|
|
||||||
afl_fsrv_write_to_testcase(fsrv, mem, len);
|
afl_fsrv_write_to_testcase(fsrv, mem, len);
|
||||||
|
|
||||||
if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, classify_counts,
|
if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon) ==
|
||||||
&stop_soon) == FSRV_RUN_ERROR) {
|
FSRV_RUN_ERROR) {
|
||||||
|
|
||||||
FATAL("Error running target");
|
FATAL("Error running target");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
classify_counts(fsrv);
|
||||||
|
|
||||||
if (stop_soon) {
|
if (stop_soon) {
|
||||||
|
|
||||||
SAYF(cRST cLRD "\n+++ afl-showmap folder mode aborted by user +++\n" cRST);
|
SAYF(cRST cLRD "\n+++ afl-showmap folder mode aborted by user +++\n" cRST);
|
||||||
@ -242,7 +246,7 @@ void run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem,
|
|||||||
|
|
||||||
/* Read initial file. */
|
/* Read initial file. */
|
||||||
|
|
||||||
u32 read_file(u8 *in_file) {
|
static u32 read_file(u8 *in_file) {
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
s32 fd = open(in_file, O_RDONLY);
|
s32 fd = open(in_file, O_RDONLY);
|
||||||
@ -267,7 +271,7 @@ u32 read_file(u8 *in_file) {
|
|||||||
|
|
||||||
/* Execute target application. */
|
/* Execute target application. */
|
||||||
|
|
||||||
static void run_target(afl_forkserver_t *fsrv, char **argv) {
|
static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
|
||||||
|
|
||||||
static struct itimerval it;
|
static struct itimerval it;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
@ -485,11 +489,9 @@ static void usage(u8 *argv0) {
|
|||||||
"\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
|
"\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
|
||||||
|
|
||||||
"Required parameters:\n"
|
"Required parameters:\n"
|
||||||
|
|
||||||
" -o file - file to write the trace data to\n\n"
|
" -o file - file to write the trace data to\n\n"
|
||||||
|
|
||||||
"Execution control settings:\n"
|
"Execution control settings:\n"
|
||||||
|
|
||||||
" -t msec - timeout for each run (none)\n"
|
" -t msec - timeout for each run (none)\n"
|
||||||
" -m megs - memory limit for child process (%d MB)\n"
|
" -m megs - memory limit for child process (%d MB)\n"
|
||||||
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
||||||
@ -497,9 +499,7 @@ static void usage(u8 *argv0) {
|
|||||||
" -W - use qemu-based instrumentation with Wine (Wine mode)\n"
|
" -W - use qemu-based instrumentation with Wine (Wine mode)\n"
|
||||||
" (Not necessary, here for consistency with other afl-* "
|
" (Not necessary, here for consistency with other afl-* "
|
||||||
"tools)\n\n"
|
"tools)\n\n"
|
||||||
|
|
||||||
"Other settings:\n"
|
"Other settings:\n"
|
||||||
|
|
||||||
" -i dir - process all files in this directory, -o must be a "
|
" -i dir - process all files in this directory, -o must be a "
|
||||||
"directory\n"
|
"directory\n"
|
||||||
" and each bitmap will be written there individually.\n"
|
" and each bitmap will be written there individually.\n"
|
||||||
@ -512,75 +512,22 @@ static void usage(u8 *argv0) {
|
|||||||
"For additional help, consult %s/README.md.\n\n"
|
"For additional help, consult %s/README.md.\n\n"
|
||||||
|
|
||||||
"Environment variables used:\n"
|
"Environment variables used:\n"
|
||||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
"LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
|
||||||
"AFL_DEBUG: enable extra developer output\n"
|
|
||||||
"AFL_QUIET: do not print extra informational output"
|
|
||||||
"AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing "
|
"AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing "
|
||||||
"inputs\n"
|
"inputs\n"
|
||||||
"AFL_CMIN_ALLOW_ANY: (cmin_mode) write tuples for crashing inputs also\n"
|
"AFL_CMIN_ALLOW_ANY: (cmin_mode) write tuples for crashing inputs also\n"
|
||||||
"LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n",
|
"AFL_DEBUG: enable extra developer output\n"
|
||||||
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the "
|
||||||
|
"size\n"
|
||||||
|
" the target was compiled for\n"
|
||||||
|
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||||
|
"AFL_QUIET: do not print extra informational output",
|
||||||
argv0, MEM_LIMIT, doc_path);
|
argv0, MEM_LIMIT, doc_path);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find binary. */
|
|
||||||
|
|
||||||
static void find_binary(afl_forkserver_t *fsrv, u8 *fname) {
|
|
||||||
|
|
||||||
u8 * env_path = 0;
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
|
|
||||||
|
|
||||||
fsrv->target_path = ck_strdup(fname);
|
|
||||||
|
|
||||||
if (stat(fsrv->target_path, &st) || !S_ISREG(st.st_mode) ||
|
|
||||||
!(st.st_mode & 0111) || st.st_size < 4)
|
|
||||||
FATAL("Program '%s' not found or not executable", fname);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
while (env_path) {
|
|
||||||
|
|
||||||
u8 *cur_elem, *delim = strchr(env_path, ':');
|
|
||||||
|
|
||||||
if (delim) {
|
|
||||||
|
|
||||||
cur_elem = ck_alloc(delim - env_path + 1);
|
|
||||||
memcpy(cur_elem, env_path, delim - env_path);
|
|
||||||
delim++;
|
|
||||||
|
|
||||||
} else
|
|
||||||
|
|
||||||
cur_elem = ck_strdup(env_path);
|
|
||||||
|
|
||||||
env_path = delim;
|
|
||||||
|
|
||||||
if (cur_elem[0])
|
|
||||||
fsrv->target_path = alloc_printf("%s/%s", cur_elem, fname);
|
|
||||||
else
|
|
||||||
fsrv->target_path = ck_strdup(fname);
|
|
||||||
|
|
||||||
ck_free(cur_elem);
|
|
||||||
|
|
||||||
if (!stat(fsrv->target_path, &st) && S_ISREG(st.st_mode) &&
|
|
||||||
(st.st_mode & 0111) && st.st_size >= 4)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ck_free(fsrv->target_path);
|
|
||||||
fsrv->target_path = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fsrv->target_path)
|
|
||||||
FATAL("Program '%s' not found or not executable", fname);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main entry point */
|
/* Main entry point */
|
||||||
|
|
||||||
int main(int argc, char **argv_orig, char **envp) {
|
int main(int argc, char **argv_orig, char **envp) {
|
||||||
@ -597,6 +544,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl_forkserver_t fsrv_var = {0};
|
afl_forkserver_t fsrv_var = {0};
|
||||||
afl_forkserver_t *fsrv = &fsrv_var;
|
afl_forkserver_t *fsrv = &fsrv_var;
|
||||||
afl_fsrv_init(fsrv);
|
afl_fsrv_init(fsrv);
|
||||||
|
map_size = get_map_size();
|
||||||
|
fsrv->map_size = map_size;
|
||||||
|
|
||||||
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
||||||
|
|
||||||
@ -624,6 +573,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
|
if (!optarg) FATAL("Wrong usage of -m");
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none")) {
|
||||||
|
|
||||||
fsrv->mem_limit = 0;
|
fsrv->mem_limit = 0;
|
||||||
@ -667,6 +618,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (timeout_given) FATAL("Multiple -t options not supported");
|
if (timeout_given) FATAL("Multiple -t options not supported");
|
||||||
timeout_given = 1;
|
timeout_given = 1;
|
||||||
|
|
||||||
|
if (!optarg) FATAL("Wrong usage of -t");
|
||||||
|
|
||||||
if (strcmp(optarg, "none")) {
|
if (strcmp(optarg, "none")) {
|
||||||
|
|
||||||
fsrv->exec_tmout = atoi(optarg);
|
fsrv->exec_tmout = atoi(optarg);
|
||||||
@ -766,12 +719,12 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
check_environment_vars(envp);
|
check_environment_vars(envp);
|
||||||
|
|
||||||
sharedmem_t shm = {0};
|
sharedmem_t shm = {0};
|
||||||
fsrv->trace_bits = afl_shm_init(&shm, MAP_SIZE, 0);
|
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
|
||||||
setup_signal_handlers();
|
setup_signal_handlers();
|
||||||
|
|
||||||
set_up_environment(fsrv);
|
set_up_environment(fsrv);
|
||||||
|
|
||||||
find_binary(fsrv, argv[optind]);
|
fsrv->target_path = find_binary(argv[optind]);
|
||||||
|
|
||||||
if (!quiet_mode) {
|
if (!quiet_mode) {
|
||||||
|
|
||||||
@ -878,12 +831,11 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
|
if (-1 == stat(infile, &statbuf) || !S_ISREG(statbuf.st_mode)) continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
snprintf(outfile, sizeof(outfile), "%s/%s", out_file,
|
snprintf(outfile, sizeof(outfile), "%s/%s", out_file, dir_ent->d_name);
|
||||||
dir_ent->d_name);
|
|
||||||
|
|
||||||
if (read_file(infile)) {
|
if (read_file(infile)) {
|
||||||
|
|
||||||
run_target_forkserver(fsrv, use_argv, in_data, in_len);
|
showmap_run_target_forkserver(fsrv, use_argv, in_data, in_len);
|
||||||
ck_free(in_data);
|
ck_free(in_data);
|
||||||
tcnt = write_results_to_file(fsrv, outfile);
|
tcnt = write_results_to_file(fsrv, outfile);
|
||||||
|
|
||||||
@ -898,11 +850,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
run_target(fsrv, use_argv);
|
showmap_run_target(fsrv, use_argv);
|
||||||
tcnt = write_results_to_file(fsrv, out_file);
|
tcnt = write_results_to_file(fsrv, out_file);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quiet_mode) {
|
if (!quiet_mode) {
|
||||||
@ -931,6 +881,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (stdin_file) ck_free(stdin_file);
|
if (stdin_file) ck_free(stdin_file);
|
||||||
|
|
||||||
argv_cpy_free(argv);
|
argv_cpy_free(argv);
|
||||||
|
if (fsrv->qemu_mode) free(use_argv[2]);
|
||||||
|
|
||||||
exit(ret);
|
exit(ret);
|
||||||
|
|
||||||
|
123
src/afl-tmin.c
123
src/afl-tmin.c
@ -62,8 +62,7 @@
|
|||||||
static u8 *mask_bitmap; /* Mask for trace bits (-B) */
|
static u8 *mask_bitmap; /* Mask for trace bits (-B) */
|
||||||
|
|
||||||
static u8 *in_file, /* Minimizer input test case */
|
static u8 *in_file, /* Minimizer input test case */
|
||||||
*out_file,
|
*out_file, *output_file; /* Minimizer output file */
|
||||||
*output_file; /* Minimizer output file */
|
|
||||||
|
|
||||||
static u8 *in_data; /* Input data for trimming */
|
static u8 *in_data; /* Input data for trimming */
|
||||||
|
|
||||||
@ -71,7 +70,8 @@ static u32 in_len, /* Input data length */
|
|||||||
orig_cksum, /* Original checksum */
|
orig_cksum, /* Original checksum */
|
||||||
missed_hangs, /* Misses due to hangs */
|
missed_hangs, /* Misses due to hangs */
|
||||||
missed_crashes, /* Misses due to crashes */
|
missed_crashes, /* Misses due to crashes */
|
||||||
missed_paths; /* Misses due to exec path diffs */
|
missed_paths, /* Misses due to exec path diffs */
|
||||||
|
map_size = MAP_SIZE;
|
||||||
|
|
||||||
static u8 crash_mode, /* Crash-centric mode? */
|
static u8 crash_mode, /* Crash-centric mode? */
|
||||||
hang_mode, /* Minimize as long as it hangs */
|
hang_mode, /* Minimize as long as it hangs */
|
||||||
@ -106,7 +106,7 @@ static const u8 count_class_lookup[256] = {
|
|||||||
|
|
||||||
static void apply_mask(u32 *mem, u32 *mask) {
|
static void apply_mask(u32 *mem, u32 *mask) {
|
||||||
|
|
||||||
u32 i = (MAP_SIZE >> 2);
|
u32 i = (map_size >> 2);
|
||||||
|
|
||||||
if (!mask) return;
|
if (!mask) return;
|
||||||
|
|
||||||
@ -122,10 +122,8 @@ static void apply_mask(u32 *mem, u32 *mask) {
|
|||||||
|
|
||||||
static void classify_counts(afl_forkserver_t *fsrv) {
|
static void classify_counts(afl_forkserver_t *fsrv) {
|
||||||
|
|
||||||
if (hang_mode) return; /* We only want hangs */
|
|
||||||
|
|
||||||
u8 *mem = fsrv->trace_bits;
|
u8 *mem = fsrv->trace_bits;
|
||||||
u32 i = MAP_SIZE;
|
u32 i = map_size;
|
||||||
|
|
||||||
if (edges_only) {
|
if (edges_only) {
|
||||||
|
|
||||||
@ -147,8 +145,6 @@ static void classify_counts(afl_forkserver_t *fsrv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_mask((u32 *)fsrv->trace_bits, (u32 *)mask_bitmap);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if any bytes are set in the bitmap. */
|
/* See if any bytes are set in the bitmap. */
|
||||||
@ -156,7 +152,7 @@ static void classify_counts(afl_forkserver_t *fsrv) {
|
|||||||
static inline u8 anything_set(afl_forkserver_t *fsrv) {
|
static inline u8 anything_set(afl_forkserver_t *fsrv) {
|
||||||
|
|
||||||
u32 *ptr = (u32 *)fsrv->trace_bits;
|
u32 *ptr = (u32 *)fsrv->trace_bits;
|
||||||
u32 i = (MAP_SIZE >> 2);
|
u32 i = (map_size >> 2);
|
||||||
|
|
||||||
while (i--)
|
while (i--)
|
||||||
if (*(ptr++)) return 1;
|
if (*(ptr++)) return 1;
|
||||||
@ -219,13 +215,13 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
|
|||||||
/* Execute target application. Returns 0 if the changes are a dud, or
|
/* Execute target application. Returns 0 if the changes are a dud, or
|
||||||
1 if they should be kept. */
|
1 if they should be kept. */
|
||||||
|
|
||||||
static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
||||||
u8 first_run) {
|
u8 first_run) {
|
||||||
|
|
||||||
afl_fsrv_write_to_testcase(fsrv, mem, len);
|
afl_fsrv_write_to_testcase(fsrv, mem, len);
|
||||||
|
|
||||||
fsrv_run_result_t ret =
|
fsrv_run_result_t ret =
|
||||||
afl_fsrv_run_target(fsrv, fsrv->exec_tmout, classify_counts, &stop_soon);
|
afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon);
|
||||||
|
|
||||||
if (ret == FSRV_RUN_ERROR) FATAL("Couldn't run child");
|
if (ret == FSRV_RUN_ERROR) FATAL("Couldn't run child");
|
||||||
|
|
||||||
@ -251,6 +247,9 @@ static u8 run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
classify_counts(fsrv);
|
||||||
|
apply_mask((u32 *)fsrv->trace_bits, (u32 *)mask_bitmap);
|
||||||
|
|
||||||
if (ret == FSRV_RUN_TMOUT) {
|
if (ret == FSRV_RUN_TMOUT) {
|
||||||
|
|
||||||
missed_hangs++;
|
missed_hangs++;
|
||||||
@ -338,7 +337,7 @@ static void minimize(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
memset(tmp_buf + set_pos, '0', use_len);
|
memset(tmp_buf + set_pos, '0', use_len);
|
||||||
|
|
||||||
u8 res;
|
u8 res;
|
||||||
res = run_target(fsrv, argv, tmp_buf, in_len, 0);
|
res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
||||||
@ -411,7 +410,7 @@ next_del_blksize:
|
|||||||
/* Tail */
|
/* Tail */
|
||||||
memcpy(tmp_buf + del_pos, in_data + del_pos + del_len, tail_len);
|
memcpy(tmp_buf + del_pos, in_data + del_pos + del_len, tail_len);
|
||||||
|
|
||||||
res = run_target(fsrv, argv, tmp_buf, del_pos + tail_len, 0);
|
res = tmin_run_target(fsrv, argv, tmp_buf, del_pos + tail_len, 0);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
||||||
@ -474,7 +473,7 @@ next_del_blksize:
|
|||||||
for (r = 0; r < in_len; r++)
|
for (r = 0; r < in_len; r++)
|
||||||
if (tmp_buf[r] == i) tmp_buf[r] = '0';
|
if (tmp_buf[r] == i) tmp_buf[r] = '0';
|
||||||
|
|
||||||
res = run_target(fsrv, argv, tmp_buf, in_len, 0);
|
res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
||||||
@ -510,7 +509,7 @@ next_del_blksize:
|
|||||||
if (orig == '0') continue;
|
if (orig == '0') continue;
|
||||||
tmp_buf[i] = '0';
|
tmp_buf[i] = '0';
|
||||||
|
|
||||||
res = run_target(fsrv, argv, tmp_buf, in_len, 0);
|
res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
||||||
@ -742,7 +741,9 @@ static void usage(u8 *argv0) {
|
|||||||
" (must contain abort_on_error=1 and symbolize=0)\n"
|
" (must contain abort_on_error=1 and symbolize=0)\n"
|
||||||
"MSAN_OPTIONS: custom settings for MSAN\n"
|
"MSAN_OPTIONS: custom settings for MSAN\n"
|
||||||
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
|
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
|
||||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
||||||
|
" the target was compiled for\n"
|
||||||
|
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||||
"AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
|
"AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
|
||||||
|
|
||||||
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
|
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
|
||||||
@ -751,76 +752,6 @@ static void usage(u8 *argv0) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find binary. */
|
|
||||||
|
|
||||||
static void find_binary(afl_forkserver_t *fsrv, u8 *fname) {
|
|
||||||
|
|
||||||
u8 * env_path = 0;
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (strchr(fname, '/') || !(env_path = getenv("PATH"))) {
|
|
||||||
|
|
||||||
fsrv->target_path = ck_strdup(fname);
|
|
||||||
|
|
||||||
if (stat(fsrv->target_path, &st) || !S_ISREG(st.st_mode) ||
|
|
||||||
!(st.st_mode & 0111) || st.st_size < 4)
|
|
||||||
FATAL("Program '%s' not found or not executable", fname);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
while (env_path) {
|
|
||||||
|
|
||||||
u8 *cur_elem, *delim = strchr(env_path, ':');
|
|
||||||
|
|
||||||
if (delim) {
|
|
||||||
|
|
||||||
cur_elem = ck_alloc(delim - env_path + 1);
|
|
||||||
memcpy(cur_elem, env_path, delim - env_path);
|
|
||||||
delim++;
|
|
||||||
|
|
||||||
} else
|
|
||||||
|
|
||||||
cur_elem = ck_strdup(env_path);
|
|
||||||
|
|
||||||
env_path = delim;
|
|
||||||
|
|
||||||
if (cur_elem[0])
|
|
||||||
fsrv->target_path = alloc_printf("%s/%s", cur_elem, fname);
|
|
||||||
else
|
|
||||||
fsrv->target_path = ck_strdup(fname);
|
|
||||||
|
|
||||||
ck_free(cur_elem);
|
|
||||||
|
|
||||||
if (!stat(fsrv->target_path, &st) && S_ISREG(st.st_mode) &&
|
|
||||||
(st.st_mode & 0111) && st.st_size >= 4)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ck_free(fsrv->target_path);
|
|
||||||
fsrv->target_path = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fsrv->target_path)
|
|
||||||
FATAL("Program '%s' not found or not executable", fname);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read mask bitmap from file. This is for the -B option. */
|
|
||||||
|
|
||||||
static void read_bitmap(u8 *fname) {
|
|
||||||
|
|
||||||
s32 fd = open(fname, O_RDONLY);
|
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", fname);
|
|
||||||
|
|
||||||
ck_read(fd, mask_bitmap, MAP_SIZE, fname);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main entry point */
|
/* Main entry point */
|
||||||
|
|
||||||
int main(int argc, char **argv_orig, char **envp) {
|
int main(int argc, char **argv_orig, char **envp) {
|
||||||
@ -834,6 +765,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl_forkserver_t fsrv_var = {0};
|
afl_forkserver_t fsrv_var = {0};
|
||||||
afl_forkserver_t *fsrv = &fsrv_var;
|
afl_forkserver_t *fsrv = &fsrv_var;
|
||||||
afl_fsrv_init(fsrv);
|
afl_fsrv_init(fsrv);
|
||||||
|
map_size = get_map_size();
|
||||||
|
fsrv->map_size = map_size;
|
||||||
|
|
||||||
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
||||||
|
|
||||||
@ -883,6 +816,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
|
if (!optarg) FATAL("Wrong usage of -m");
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none")) {
|
||||||
|
|
||||||
fsrv->mem_limit = 0;
|
fsrv->mem_limit = 0;
|
||||||
@ -919,6 +854,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (timeout_given) FATAL("Multiple -t options not supported");
|
if (timeout_given) FATAL("Multiple -t options not supported");
|
||||||
timeout_given = 1;
|
timeout_given = 1;
|
||||||
|
|
||||||
|
if (!optarg) FATAL("Wrong usage of -t");
|
||||||
|
|
||||||
fsrv->exec_tmout = atoi(optarg);
|
fsrv->exec_tmout = atoi(optarg);
|
||||||
|
|
||||||
if (fsrv->exec_tmout < 10 || optarg[0] == '-')
|
if (fsrv->exec_tmout < 10 || optarg[0] == '-')
|
||||||
@ -978,8 +915,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
to be useful. */
|
to be useful. */
|
||||||
|
|
||||||
if (mask_bitmap) FATAL("Multiple -B options not supported");
|
if (mask_bitmap) FATAL("Multiple -B options not supported");
|
||||||
mask_bitmap = ck_alloc(MAP_SIZE);
|
mask_bitmap = ck_alloc(map_size);
|
||||||
read_bitmap(optarg);
|
read_bitmap(optarg, mask_bitmap, map_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
@ -996,14 +933,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
check_environment_vars(envp);
|
check_environment_vars(envp);
|
||||||
|
|
||||||
sharedmem_t shm = {0};
|
sharedmem_t shm = {0};
|
||||||
fsrv->trace_bits = afl_shm_init(&shm, MAP_SIZE, 0);
|
fsrv->trace_bits = afl_shm_init(&shm, map_size, 0);
|
||||||
|
|
||||||
atexit(at_exit_handler);
|
atexit(at_exit_handler);
|
||||||
setup_signal_handlers();
|
setup_signal_handlers();
|
||||||
|
|
||||||
set_up_environment(fsrv);
|
set_up_environment(fsrv);
|
||||||
|
|
||||||
find_binary(fsrv, argv[optind]);
|
fsrv->target_path = find_binary(argv[optind]);
|
||||||
detect_file_args(argv + optind, out_file, &fsrv->use_stdin);
|
detect_file_args(argv + optind, out_file, &fsrv->use_stdin);
|
||||||
|
|
||||||
if (fsrv->qemu_mode) {
|
if (fsrv->qemu_mode) {
|
||||||
@ -1038,7 +975,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
|
ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...",
|
||||||
fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : "");
|
fsrv->mem_limit, fsrv->exec_tmout, edges_only ? ", edges only" : "");
|
||||||
|
|
||||||
run_target(fsrv, use_argv, in_data, in_len, 1);
|
tmin_run_target(fsrv, use_argv, in_data, in_len, 1);
|
||||||
|
|
||||||
if (hang_mode && !fsrv->last_run_timed_out)
|
if (hang_mode && !fsrv->last_run_timed_out)
|
||||||
FATAL(
|
FATAL(
|
||||||
|
76
src/third_party/libradamsa/libradamsa.c
vendored
76
src/third_party/libradamsa/libradamsa.c
vendored
@ -1841,6 +1841,8 @@ static const unsigned char heap[] = {2,3,4,105,111,116,97,2,3,7,112,97,116,116,1
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#include "./radamsa.h"
|
||||||
|
|
||||||
#ifndef EMULTIHOP
|
#ifndef EMULTIHOP
|
||||||
#define EMULTIHOP -1
|
#define EMULTIHOP -1
|
||||||
#endif
|
#endif
|
||||||
@ -2155,17 +2157,17 @@ static word *gc(int size, word *regs) {
|
|||||||
|
|
||||||
/*** OS Interaction and Helpers ***/
|
/*** OS Interaction and Helpers ***/
|
||||||
|
|
||||||
static void signal_handler(int signal) {
|
//static void signal_handler(int signal) {
|
||||||
switch (signal) {
|
// switch (signal) {
|
||||||
case SIGINT:
|
// case SIGINT:
|
||||||
breaked |= 2;
|
// breaked |= 2;
|
||||||
break;
|
// break;
|
||||||
case SIGPIPE:
|
// case SIGPIPE:
|
||||||
break; /* can cause loop when reporting errors */
|
// break; /* can cause loop when reporting errors */
|
||||||
default:
|
// default:
|
||||||
breaked |= 4;
|
// breaked |= 4;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
/* list length, no overflow or valid termination checks */
|
/* list length, no overflow or valid termination checks */
|
||||||
static uint llen(word *ptr) {
|
static uint llen(word *ptr) {
|
||||||
@ -2176,7 +2178,7 @@ static uint llen(word *ptr) {
|
|||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
static void set_signal_handler(void) {
|
static void set_signal_handler(void) {
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
sa.sa_handler = signal_handler;
|
sa.sa_handler = signal_handler;
|
||||||
@ -2185,7 +2187,7 @@ static void set_signal_handler(void) {
|
|||||||
sigaction(SIGINT, &sa, NULL);
|
sigaction(SIGINT, &sa, NULL);
|
||||||
sigaction(SIGPIPE, &sa, NULL);
|
sigaction(SIGPIPE, &sa, NULL);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
static word mkpair(word h, word a, word d) {
|
static word mkpair(word h, word a, word d) {
|
||||||
word *pair;
|
word *pair;
|
||||||
allocate(3, pair);
|
allocate(3, pair);
|
||||||
@ -30683,7 +30685,7 @@ static void heap_metrics(int *rwords, int *rnobjs) {
|
|||||||
get_obj_metrics(rwords, rnobjs);
|
get_obj_metrics(rwords, rnobjs);
|
||||||
hp = hp_start;
|
hp = hp_start;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
static void read_heap(const char *path) {
|
static void read_heap(const char *path) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
off_t pos = 0;
|
off_t pos = 0;
|
||||||
@ -30703,25 +30705,26 @@ static void read_heap(const char *path) {
|
|||||||
} while (n && (pos += n) < st.st_size);
|
} while (n && (pos += n) < st.st_size);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* find a fasl image source to *hp or exit */
|
/* find a fasl image source to *hp or exit */
|
||||||
static void find_heap(int *nargs, char ***argv, int *nobjs, int *nwords) {
|
//static void find_heap(int *nargs, char ***argv, int *nobjs, int *nwords) {
|
||||||
file_heap = NULL;
|
// file_heap = NULL;
|
||||||
if ((word)heap == 0) {
|
// if ((word)heap == 0) {
|
||||||
/* if no preloaded heap, try to load it from first vm arg */
|
/* if no preloaded heap, try to load it from first vm arg */
|
||||||
if (*nargs < 2)
|
// if (*nargs < 2)
|
||||||
exit(1);
|
// exit(1);
|
||||||
read_heap(argv[0][1]);
|
// read_heap(argv[0][1]);
|
||||||
++*argv;
|
// ++*argv;
|
||||||
--*nargs;
|
// --*nargs;
|
||||||
hp = file_heap;
|
// hp = file_heap;
|
||||||
if (*hp == '#')
|
// if (*hp == '#')
|
||||||
while (*hp++ != '\n');
|
// while (*hp++ != '\n');
|
||||||
} else {
|
// } else {
|
||||||
hp = heap; /* builtin heap */
|
// hp = heap; /* builtin heap */
|
||||||
}
|
// }
|
||||||
heap_metrics(nwords, nobjs);
|
// heap_metrics(nwords, nobjs);
|
||||||
}
|
//}
|
||||||
|
|
||||||
static word *decode_fasl(uint nobjs) {
|
static word *decode_fasl(uint nobjs) {
|
||||||
word *ptrs;
|
word *ptrs;
|
||||||
@ -30744,7 +30747,7 @@ static word *load_heap(uint nobjs) {
|
|||||||
free(file_heap);
|
free(file_heap);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
static void setup(int nwords, int nobjs) {
|
static void setup(int nwords, int nobjs) {
|
||||||
tcgetattr(0, &tsettings);
|
tcgetattr(0, &tsettings);
|
||||||
state = IFALSE;
|
state = IFALSE;
|
||||||
@ -30757,7 +30760,7 @@ static void setup(int nwords, int nobjs) {
|
|||||||
memend = memstart + nwords - MEMPAD;
|
memend = memstart + nwords - MEMPAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
int secondary(int nargs, char **argv) {
|
static int secondary(int nargs, char **argv) {
|
||||||
word *prog;
|
word *prog;
|
||||||
int rval, nobjs=0, nwords=0;
|
int rval, nobjs=0, nwords=0;
|
||||||
find_heap(&nargs, &argv, &nobjs, &nwords);
|
find_heap(&nargs, &argv, &nobjs, &nwords);
|
||||||
@ -30772,6 +30775,7 @@ int secondary(int nargs, char **argv) {
|
|||||||
}
|
}
|
||||||
return 127;
|
return 127;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void radamsa_init(void) {
|
void radamsa_init(void) {
|
||||||
int nobjs=0, nwords=0;
|
int nobjs=0, nwords=0;
|
||||||
@ -30787,7 +30791,7 @@ void radamsa_init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* bvec → value library call test with preserved state */
|
/* bvec → value library call test with preserved state */
|
||||||
word library_call(word val) {
|
static word library_call(word val) {
|
||||||
word program_state = state;
|
word program_state = state;
|
||||||
word res;
|
word res;
|
||||||
state = IFALSE;
|
state = IFALSE;
|
||||||
@ -30798,7 +30802,8 @@ word library_call(word val) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t list_length(word lispval) {
|
/*
|
||||||
|
static size_t list_length(word lispval) {
|
||||||
size_t l = 0;
|
size_t l = 0;
|
||||||
while(lispval != INULL) {
|
while(lispval != INULL) {
|
||||||
lispval = G(lispval, 2);
|
lispval = G(lispval, 2);
|
||||||
@ -30806,8 +30811,9 @@ size_t list_length(word lispval) {
|
|||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
size_t copy_list(uint8_t *ptr, word lispval, size_t max) {
|
static size_t copy_list(uint8_t *ptr, word lispval, size_t max) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
while(pairp((word)lispval) && max-- && lispval != INULL) {
|
while(pairp((word)lispval) && max-- && lispval != INULL) {
|
||||||
*ptr++ = 255 & immval(G(lispval, 1)); // *ptr++ = car(list)
|
*ptr++ = 255 & immval(G(lispval, 1)); // *ptr++ = car(list)
|
||||||
|
6
src/third_party/libradamsa/radamsa.h
vendored
6
src/third_party/libradamsa/radamsa.h
vendored
@ -1,13 +1,13 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
extern void radamsa_init(void);
|
void radamsa_init(void);
|
||||||
|
|
||||||
extern size_t radamsa(uint8_t *ptr, size_t len,
|
size_t radamsa(uint8_t *ptr, size_t len,
|
||||||
uint8_t *target, size_t max,
|
uint8_t *target, size_t max,
|
||||||
unsigned int seed);
|
unsigned int seed);
|
||||||
|
|
||||||
extern size_t radamsa_inplace(uint8_t *ptr,
|
size_t radamsa_inplace(uint8_t *ptr,
|
||||||
size_t len,
|
size_t len,
|
||||||
size_t max,
|
size_t max,
|
||||||
unsigned int seed);
|
unsigned int seed);
|
||||||
|
@ -671,7 +671,7 @@ test -e ../afl-qemu-trace && {
|
|||||||
test -e test-instr -a -e test-compcov && {
|
test -e test-instr -a -e test-compcov && {
|
||||||
{
|
{
|
||||||
mkdir -p in
|
mkdir -p in
|
||||||
echo 0 > in/in
|
echo 00000 > in/in
|
||||||
$ECHO "$GREY[*] running afl-fuzz for qemu_mode, this will take approx 10 seconds"
|
$ECHO "$GREY[*] running afl-fuzz for qemu_mode, this will take approx 10 seconds"
|
||||||
{
|
{
|
||||||
../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-instr >>errors 2>&1
|
../afl-fuzz -m ${MEM_LIMIT} -V10 -Q -i in -o out -- ./test-instr >>errors 2>&1
|
||||||
|
@ -27,6 +27,7 @@ extern void mock_assert(const int result, const char* const expression,
|
|||||||
(compile with `--wrap=exit`) */
|
(compile with `--wrap=exit`) */
|
||||||
extern void exit(int status);
|
extern void exit(int status);
|
||||||
extern void __real_exit(int status);
|
extern void __real_exit(int status);
|
||||||
|
void __wrap_exit(int status);
|
||||||
void __wrap_exit(int status) {
|
void __wrap_exit(int status) {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
@ -34,6 +35,7 @@ void __wrap_exit(int status) {
|
|||||||
/* ignore all printfs */
|
/* ignore all printfs */
|
||||||
extern int printf(const char *format, ...);
|
extern int printf(const char *format, ...);
|
||||||
extern int __real_printf(const char *format, ...);
|
extern int __real_printf(const char *format, ...);
|
||||||
|
int __wrap_printf(const char *format, ...);
|
||||||
int __wrap_printf(const char *format, ...) {
|
int __wrap_printf(const char *format, ...) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ extern void mock_assert(const int result, const char* const expression,
|
|||||||
mock_assert((int)(expression), #expression, __FILE__, __LINE__);
|
mock_assert((int)(expression), #expression, __FILE__, __LINE__);
|
||||||
#include "alloc-inl.h"
|
#include "alloc-inl.h"
|
||||||
|
|
||||||
|
void __wrap_exit(int status);
|
||||||
/* remap exit -> assert, then use cmocka's mock_assert
|
/* remap exit -> assert, then use cmocka's mock_assert
|
||||||
(compile with `--wrap=exit`) */
|
(compile with `--wrap=exit`) */
|
||||||
extern void exit(int status);
|
extern void exit(int status);
|
||||||
@ -30,6 +31,7 @@ void __wrap_exit(int status) {
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __wrap_printf(const char *format, ...);
|
||||||
/* ignore all printfs */
|
/* ignore all printfs */
|
||||||
extern int printf(const char *format, ...);
|
extern int printf(const char *format, ...);
|
||||||
extern int __real_printf(const char *format, ...);
|
extern int __real_printf(const char *format, ...);
|
||||||
|
@ -27,6 +27,7 @@ extern void mock_assert(const int result, const char* const expression,
|
|||||||
(compile with `--wrap=exit`) */
|
(compile with `--wrap=exit`) */
|
||||||
extern void exit(int status);
|
extern void exit(int status);
|
||||||
extern void __real_exit(int status);
|
extern void __real_exit(int status);
|
||||||
|
void __wrap_exit(int status);
|
||||||
void __wrap_exit(int status) {
|
void __wrap_exit(int status) {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
@ -34,6 +35,7 @@ void __wrap_exit(int status) {
|
|||||||
/* ignore all printfs */
|
/* ignore all printfs */
|
||||||
extern int printf(const char *format, ...);
|
extern int printf(const char *format, ...);
|
||||||
extern int __real_printf(const char *format, ...);
|
extern int __real_printf(const char *format, ...);
|
||||||
|
int __wrap_printf(const char *format, ...);
|
||||||
int __wrap_printf(const char *format, ...) {
|
int __wrap_printf(const char *format, ...) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user