mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
1
afl-cmin
1
afl-cmin
@ -120,6 +120,7 @@ function usage() {
|
|||||||
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \
|
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \
|
||||||
"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" \
|
"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" \
|
||||||
"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
|
"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
|
||||||
|
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
|
||||||
"AFL_PATH: path for the afl-showmap binary if not found anywhere else\n" \
|
"AFL_PATH: path for the afl-showmap binary if not found anywhere else\n" \
|
||||||
"AFL_SKIP_BIN_CHECK: skip check for target binary\n"
|
"AFL_SKIP_BIN_CHECK: skip check for target binary\n"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -58,6 +58,11 @@ if [ "$PLATFORM" = "OpenBSD" ] ; then
|
|||||||
echo 'System security features cannot be disabled on OpenBSD.'
|
echo 'System security features cannot be disabled on OpenBSD.'
|
||||||
DONE=1
|
DONE=1
|
||||||
fi
|
fi
|
||||||
|
if [ "$PLATFORM" = "DragonFly" ] ; then
|
||||||
|
echo
|
||||||
|
echo 'System security features cannot be disabled on DragonFly.'
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
if [ "$PLATFORM" = "NetBSD" ] ; then
|
if [ "$PLATFORM" = "NetBSD" ] ; then
|
||||||
{
|
{
|
||||||
#echo It is recommended to enable unprivileged users to set cpu affinity
|
#echo It is recommended to enable unprivileged users to set cpu affinity
|
||||||
@ -79,5 +84,14 @@ if [ "$PLATFORM" = "Darwin" ] ; then
|
|||||||
fi
|
fi
|
||||||
DONE=1
|
DONE=1
|
||||||
fi
|
fi
|
||||||
|
if [ "$PLATFORM" = "Haiku" ] ; then
|
||||||
|
SETTINGS=~/config/settings/system/debug_server/settings
|
||||||
|
[ -r ${SETTINGS} ] && grep -qE "default_action\s+kill" ${SETTINGS} && { echo "Nothing to do"; } || { \
|
||||||
|
echo We change the debug_server default_action from user to silenty kill; \
|
||||||
|
[ ! -r ${SETTINGS} ] && echo "default_action kill" >${SETTINGS} || { mv ${SETTINGS} s.tmp; sed -e "s/default_action\s\s*user/default_action kill/" s.tmp > ${SETTINGS}; rm s.tmp; }; \
|
||||||
|
echo Settings applied.; \
|
||||||
|
}
|
||||||
|
DONE=1
|
||||||
|
fi
|
||||||
test -z "$DONE" && echo Error: Unknown platform: $PLATFORM
|
test -z "$DONE" && echo Error: Unknown platform: $PLATFORM
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -995,7 +995,7 @@ void mangle_mangleContent(run_t *run, int speed_factor) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t changesCnt = run->global->mutate.mutationsPerRun;
|
uint64_t changesCnt;
|
||||||
|
|
||||||
if (speed_factor < 5) {
|
if (speed_factor < 5) {
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NumFunctions || FocusFuncIdx == SIZE_MAX || Files.size() <= 1)
|
if (FocusFuncIdx == SIZE_MAX || Files.size() <= 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Read traces.
|
// Read traces.
|
||||||
@ -259,8 +259,8 @@ bool DataFlowTrace::Init(const std::string &DirPath, std::string *FocusFunction,
|
|||||||
if (!CorporaHashes.count(Name)) continue; // not in the corpus.
|
if (!CorporaHashes.count(Name)) continue; // not in the corpus.
|
||||||
NumTraceFiles++;
|
NumTraceFiles++;
|
||||||
// Printf("=== %s\n", Name.c_str());
|
// Printf("=== %s\n", Name.c_str());
|
||||||
std::ifstream IF(SF.File);
|
std::ifstream IF2(SF.File);
|
||||||
while (std::getline(IF, L, '\n')) {
|
while (std::getline(IF2, L, '\n')) {
|
||||||
|
|
||||||
size_t FunctionNum = 0;
|
size_t FunctionNum = 0;
|
||||||
std::string DFTString;
|
std::string DFTString;
|
||||||
@ -314,8 +314,8 @@ int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,
|
|||||||
// we then request tags in [0,Size/2) and [Size/2, Size), and so on.
|
// we then request tags in [0,Size/2) and [Size/2, Size), and so on.
|
||||||
// Function number => DFT.
|
// Function number => DFT.
|
||||||
auto OutPath = DirPlusFile(DirPath, Hash(FileToVector(F.File)));
|
auto OutPath = DirPlusFile(DirPath, Hash(FileToVector(F.File)));
|
||||||
std::unordered_map<size_t, Vector<uint8_t>> DFTMap;
|
// std::unordered_map<size_t, Vector<uint8_t>> DFTMap;
|
||||||
std::unordered_set<std::string> Cov;
|
// std::unordered_set<std::string> Cov;
|
||||||
Command Cmd;
|
Command Cmd;
|
||||||
Cmd.addArgument(DFTBinary);
|
Cmd.addArgument(DFTBinary);
|
||||||
Cmd.addArgument(F.File);
|
Cmd.addArgument(F.File);
|
||||||
|
@ -46,7 +46,7 @@ template<typename T>
|
|||||||
fuzzer_allocator() = default;
|
fuzzer_allocator() = default;
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
fuzzer_allocator(const fuzzer_allocator<U>&) {}
|
explicit fuzzer_allocator(const fuzzer_allocator<U>&) {}
|
||||||
|
|
||||||
template<class Other>
|
template<class Other>
|
||||||
struct rebind { typedef fuzzer_allocator<Other> other; };
|
struct rebind { typedef fuzzer_allocator<Other> other; };
|
||||||
|
@ -49,7 +49,7 @@ typedef FixedWord<64> Word;
|
|||||||
class DictionaryEntry {
|
class DictionaryEntry {
|
||||||
public:
|
public:
|
||||||
DictionaryEntry() {}
|
DictionaryEntry() {}
|
||||||
DictionaryEntry(Word W) : W(W) {}
|
explicit DictionaryEntry(Word W) : W(W) {}
|
||||||
DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
|
DictionaryEntry(Word W, size_t PositionHint) : W(W), PositionHint(PositionHint) {}
|
||||||
const Word &GetW() const { return W; }
|
const Word &GetW() const { return W; }
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ class Dictionary {
|
|||||||
assert(Idx < Size);
|
assert(Idx < Size);
|
||||||
return DE[Idx];
|
return DE[Idx];
|
||||||
}
|
}
|
||||||
void push_back(DictionaryEntry DE) {
|
void push_back(const DictionaryEntry &DE) {
|
||||||
if (Size < kMaxDictSize)
|
if (Size < kMaxDictSize)
|
||||||
this->DE[Size++] = DE;
|
this->DE[Size++] = DE;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
namespace fuzzer {
|
namespace fuzzer {
|
||||||
class Random : public std::minstd_rand {
|
class Random : public std::minstd_rand {
|
||||||
public:
|
public:
|
||||||
Random(unsigned int seed) : std::minstd_rand(seed) {}
|
explicit Random(unsigned int seed) : std::minstd_rand(seed) {}
|
||||||
result_type operator()() { return this->std::minstd_rand::operator()(); }
|
result_type operator()() { return this->std::minstd_rand::operator()(); }
|
||||||
size_t Rand() { return this->operator()(); }
|
size_t Rand() { return this->operator()(); }
|
||||||
size_t RandBool() { return Rand() % 2; }
|
size_t RandBool() { return Rand() % 2; }
|
||||||
|
@ -145,10 +145,10 @@ private:
|
|||||||
};
|
};
|
||||||
Region *Regions;
|
Region *Regions;
|
||||||
size_t NumRegions;
|
size_t NumRegions;
|
||||||
uint8_t *Start() { return Regions[0].Start; }
|
uint8_t *Start() const { return Regions[0].Start; }
|
||||||
uint8_t *Stop() { return Regions[NumRegions - 1].Stop; }
|
uint8_t *Stop() const { return Regions[NumRegions - 1].Stop; }
|
||||||
size_t Size() { return Stop() - Start(); }
|
size_t Size() const { return Stop() - Start(); }
|
||||||
size_t Idx(uint8_t *P) {
|
size_t Idx(uint8_t *P) const {
|
||||||
assert(P >= Start() && P < Stop());
|
assert(P >= Start() && P < Stop());
|
||||||
return P - Start();
|
return P - Start();
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,11 @@ Want to stay in the loop on major new features? Join our mailing list by
|
|||||||
sending a mail to <afl-users+subscribe@googlegroups.com>.
|
sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||||
|
|
||||||
|
|
||||||
### Version ++3.01a (release)
|
### Version ++3.01a (dev)
|
||||||
- Mac OS ARM64 support
|
- Mac OS ARM64 support
|
||||||
|
- New selective instrumentation option with __AFL_COVERAGE_... commands
|
||||||
|
to be placed in the source code.
|
||||||
|
Check out instrumentation/README.instrument_list.md
|
||||||
- afl-fuzz
|
- afl-fuzz
|
||||||
- fix crash for very, very fast targets+systems (thanks to mhlakhani
|
- fix crash for very, very fast targets+systems (thanks to mhlakhani
|
||||||
for reporting)
|
for reporting)
|
||||||
@ -20,6 +23,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
- allow instrumenting LLVMFuzzerTestOneInput
|
- allow instrumenting LLVMFuzzerTestOneInput
|
||||||
- fixed endless loop for allow/blocklist lines starting with a
|
- fixed endless loop for allow/blocklist lines starting with a
|
||||||
comment (thanks to Zherya for reporting)
|
comment (thanks to Zherya for reporting)
|
||||||
|
- cmplog/redqueen now also tracks floats/doubles
|
||||||
- added AFL_LLVM_INSTRUMENT option NATIVE for native clang pc-guard
|
- added AFL_LLVM_INSTRUMENT option NATIVE for native clang pc-guard
|
||||||
support (less performant than our own), GCC for old afl-gcc and
|
support (less performant than our own), GCC for old afl-gcc and
|
||||||
CLANG for old afl-clang
|
CLANG for old afl-clang
|
||||||
@ -28,7 +32,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
already building with all cores, the gcc plugin needs only one.
|
already building with all cores, the gcc plugin needs only one.
|
||||||
- added dummy Makefile to instrumentation/
|
- added dummy Makefile to instrumentation/
|
||||||
- Updated utils/afl_frida to be 5% faster
|
- Updated utils/afl_frida to be 5% faster
|
||||||
|
- Added AFL_KILL_SIGNAL env variable for custom targets (thanks @v-p-b)
|
||||||
|
|
||||||
### Version ++3.00c (release)
|
### Version ++3.00c (release)
|
||||||
- llvm_mode/ and gcc_plugin/ moved to instrumentation/
|
- llvm_mode/ and gcc_plugin/ moved to instrumentation/
|
||||||
|
@ -350,6 +350,10 @@ checks or alter some of the more exotic semantics of the tool:
|
|||||||
- Note that `AFL_POST_LIBRARY` is deprecated, use `AFL_CUSTOM_MUTATOR_LIBRARY`
|
- Note that `AFL_POST_LIBRARY` is deprecated, use `AFL_CUSTOM_MUTATOR_LIBRARY`
|
||||||
instead (see below).
|
instead (see below).
|
||||||
|
|
||||||
|
- `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on timeout.
|
||||||
|
Unless you implement your own targets or instrumentation, you likely don't have to set it.
|
||||||
|
By default, on timeout and on exit, `SIGKILL` (`AFL_KILL_SIGNAL=9`) will be delivered to the child.
|
||||||
|
|
||||||
- Setting `AFL_CUSTOM_MUTATOR_LIBRARY` to a shared library with
|
- Setting `AFL_CUSTOM_MUTATOR_LIBRARY` to a shared library with
|
||||||
afl_custom_fuzz() creates additional mutations through this library.
|
afl_custom_fuzz() creates additional mutations through this library.
|
||||||
If afl-fuzz is compiled with Python (which is autodetected during builing
|
If afl-fuzz is compiled with Python (which is autodetected during builing
|
||||||
|
@ -381,7 +381,7 @@ typedef struct afl_env_vars {
|
|||||||
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload,
|
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload,
|
||||||
*afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
|
*afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
|
||||||
*afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
|
*afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
|
||||||
*afl_testcache_entries;
|
*afl_testcache_entries, *afl_kill_signal;
|
||||||
|
|
||||||
} afl_env_vars_t;
|
} afl_env_vars_t;
|
||||||
|
|
||||||
@ -573,7 +573,7 @@ typedef struct afl_state {
|
|||||||
|
|
||||||
u8 stage_name_buf[STAGE_BUF_SIZE]; /* reused stagename buf with len 64 */
|
u8 stage_name_buf[STAGE_BUF_SIZE]; /* reused stagename buf with len 64 */
|
||||||
|
|
||||||
s32 stage_cur, stage_max; /* Stage progression */
|
u32 stage_cur, stage_max; /* Stage progression */
|
||||||
s32 splicing_with; /* Splicing with which test case? */
|
s32 splicing_with; /* Splicing with which test case? */
|
||||||
|
|
||||||
u32 main_node_id, main_node_max; /* Main instance job splitting */
|
u32 main_node_id, main_node_max; /* Main instance job splitting */
|
||||||
@ -648,7 +648,7 @@ typedef struct afl_state {
|
|||||||
double last_avg_execs_saved;
|
double last_avg_execs_saved;
|
||||||
|
|
||||||
/* foreign sync */
|
/* foreign sync */
|
||||||
#define FOREIGN_SYNCS_MAX 32
|
#define FOREIGN_SYNCS_MAX 32U
|
||||||
u8 foreign_sync_cnt;
|
u8 foreign_sync_cnt;
|
||||||
struct foreign_sync foreign_syncs[FOREIGN_SYNCS_MAX];
|
struct foreign_sync foreign_syncs[FOREIGN_SYNCS_MAX];
|
||||||
|
|
||||||
|
@ -56,6 +56,11 @@ extern u8 *doc_path; /* path to documentation dir */
|
|||||||
|
|
||||||
u8 *find_binary(u8 *fname);
|
u8 *find_binary(u8 *fname);
|
||||||
|
|
||||||
|
/* Parses the kill signal environment variable, FATALs on error.
|
||||||
|
If the env is not set, sets the env to default_signal for the signal handlers
|
||||||
|
and returns the default_signal. */
|
||||||
|
int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal);
|
||||||
|
|
||||||
/* Read a bitmap from file fname to memory
|
/* Read a bitmap from file fname to memory
|
||||||
This is for the -B option again. */
|
This is for the -B option again. */
|
||||||
|
|
||||||
|
@ -80,11 +80,11 @@
|
|||||||
/* Default timeout for fuzzed code (milliseconds). This is the upper bound,
|
/* Default timeout for fuzzed code (milliseconds). This is the upper bound,
|
||||||
also used for detecting hangs; the actual value is auto-scaled: */
|
also used for detecting hangs; the actual value is auto-scaled: */
|
||||||
|
|
||||||
#define EXEC_TIMEOUT 1000
|
#define EXEC_TIMEOUT 1000U
|
||||||
|
|
||||||
/* Timeout rounding factor when auto-scaling (milliseconds): */
|
/* Timeout rounding factor when auto-scaling (milliseconds): */
|
||||||
|
|
||||||
#define EXEC_TM_ROUND 20
|
#define EXEC_TM_ROUND 20U
|
||||||
|
|
||||||
/* 64bit arch MACRO */
|
/* 64bit arch MACRO */
|
||||||
#if (defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__))
|
#if (defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__))
|
||||||
@ -93,48 +93,48 @@
|
|||||||
|
|
||||||
/* Default memory limit for child process (MB) 0 = disabled : */
|
/* Default memory limit for child process (MB) 0 = disabled : */
|
||||||
|
|
||||||
#define MEM_LIMIT 0
|
#define MEM_LIMIT 0U
|
||||||
|
|
||||||
/* Default memory limit when running in QEMU mode (MB) 0 = disabled : */
|
/* Default memory limit when running in QEMU mode (MB) 0 = disabled : */
|
||||||
|
|
||||||
#define MEM_LIMIT_QEMU 0
|
#define MEM_LIMIT_QEMU 0U
|
||||||
|
|
||||||
/* Default memory limit when running in Unicorn mode (MB) 0 = disabled : */
|
/* Default memory limit when running in Unicorn mode (MB) 0 = disabled : */
|
||||||
|
|
||||||
#define MEM_LIMIT_UNICORN 0
|
#define MEM_LIMIT_UNICORN 0U
|
||||||
|
|
||||||
/* Number of calibration cycles per every new test case (and for test
|
/* Number of calibration cycles per every new test case (and for test
|
||||||
cases that show variable behavior): */
|
cases that show variable behavior): */
|
||||||
|
|
||||||
#define CAL_CYCLES 8
|
#define CAL_CYCLES 8U
|
||||||
#define CAL_CYCLES_LONG 40
|
#define CAL_CYCLES_LONG 40U
|
||||||
|
|
||||||
/* Number of subsequent timeouts before abandoning an input file: */
|
/* Number of subsequent timeouts before abandoning an input file: */
|
||||||
|
|
||||||
#define TMOUT_LIMIT 250
|
#define TMOUT_LIMIT 250U
|
||||||
|
|
||||||
/* Maximum number of unique hangs or crashes to record: */
|
/* Maximum number of unique hangs or crashes to record: */
|
||||||
|
|
||||||
#define KEEP_UNIQUE_HANG 500
|
#define KEEP_UNIQUE_HANG 500U
|
||||||
#define KEEP_UNIQUE_CRASH 5000
|
#define KEEP_UNIQUE_CRASH 5000U
|
||||||
|
|
||||||
/* Baseline number of random tweaks during a single 'havoc' stage: */
|
/* Baseline number of random tweaks during a single 'havoc' stage: */
|
||||||
|
|
||||||
#define HAVOC_CYCLES 256
|
#define HAVOC_CYCLES 256U
|
||||||
#define HAVOC_CYCLES_INIT 1024
|
#define HAVOC_CYCLES_INIT 1024U
|
||||||
|
|
||||||
/* Maximum multiplier for the above (should be a power of two, beware
|
/* Maximum multiplier for the above (should be a power of two, beware
|
||||||
of 32-bit int overflows): */
|
of 32-bit int overflows): */
|
||||||
|
|
||||||
#define HAVOC_MAX_MULT 64
|
#define HAVOC_MAX_MULT 64U
|
||||||
#define HAVOC_MAX_MULT_MOPT 64
|
#define HAVOC_MAX_MULT_MOPT 64U
|
||||||
|
|
||||||
/* Absolute minimum number of havoc cycles (after all adjustments): */
|
/* Absolute minimum number of havoc cycles (after all adjustments): */
|
||||||
|
|
||||||
#define HAVOC_MIN 12
|
#define HAVOC_MIN 12U
|
||||||
|
|
||||||
/* Power Schedule Divisor */
|
/* Power Schedule Divisor */
|
||||||
#define POWER_BETA 1
|
#define POWER_BETA 1U
|
||||||
#define MAX_FACTOR (POWER_BETA * 32)
|
#define MAX_FACTOR (POWER_BETA * 32)
|
||||||
|
|
||||||
/* Maximum stacking for havoc-stage tweaks. The actual value is calculated
|
/* Maximum stacking for havoc-stage tweaks. The actual value is calculated
|
||||||
@ -146,19 +146,19 @@
|
|||||||
In other words, the default (n = 4) produces 2, 4, 8, 16
|
In other words, the default (n = 4) produces 2, 4, 8, 16
|
||||||
stacked tweaks: */
|
stacked tweaks: */
|
||||||
|
|
||||||
#define HAVOC_STACK_POW2 4
|
#define HAVOC_STACK_POW2 4U
|
||||||
|
|
||||||
/* Caps on block sizes for cloning and deletion operations. Each of these
|
/* Caps on block sizes for cloning and deletion operations. Each of these
|
||||||
ranges has a 33% probability of getting picked, except for the first
|
ranges has a 33% probability of getting picked, except for the first
|
||||||
two cycles where smaller blocks are favored: */
|
two cycles where smaller blocks are favored: */
|
||||||
|
|
||||||
#define HAVOC_BLK_SMALL 32
|
#define HAVOC_BLK_SMALL 32U
|
||||||
#define HAVOC_BLK_MEDIUM 128
|
#define HAVOC_BLK_MEDIUM 128U
|
||||||
#define HAVOC_BLK_LARGE 1500
|
#define HAVOC_BLK_LARGE 1500U
|
||||||
|
|
||||||
/* Extra-large blocks, selected very rarely (<5% of the time): */
|
/* Extra-large blocks, selected very rarely (<5% of the time): */
|
||||||
|
|
||||||
#define HAVOC_BLK_XL 32768
|
#define HAVOC_BLK_XL 32768U
|
||||||
|
|
||||||
/* Probabilities of skipping non-favored entries in the queue, expressed as
|
/* Probabilities of skipping non-favored entries in the queue, expressed as
|
||||||
percentages: */
|
percentages: */
|
||||||
@ -186,13 +186,15 @@
|
|||||||
#define TRIM_START_STEPS 16
|
#define TRIM_START_STEPS 16
|
||||||
#define TRIM_END_STEPS 1024
|
#define TRIM_END_STEPS 1024
|
||||||
|
|
||||||
/* Maximum size of input file, in bytes (keep under 100MB): */
|
/* Maximum size of input file, in bytes (keep under 100MB, default 1MB):
|
||||||
|
(note that if this value is changed, several areas in afl-cc.c, afl-fuzz.c
|
||||||
|
and afl-fuzz-state.c have to be changed as well! */
|
||||||
|
|
||||||
#define MAX_FILE (1 * 1024 * 1024)
|
#define MAX_FILE (1 * 1024 * 1024U)
|
||||||
|
|
||||||
/* The same, for the test case minimizer: */
|
/* The same, for the test case minimizer: */
|
||||||
|
|
||||||
#define TMIN_MAX_FILE (10 * 1024 * 1024)
|
#define TMIN_MAX_FILE (10 * 1024 * 1024U)
|
||||||
|
|
||||||
/* Block normalization steps for afl-tmin: */
|
/* Block normalization steps for afl-tmin: */
|
||||||
|
|
||||||
@ -380,7 +382,7 @@
|
|||||||
after changing this - otherwise, SEGVs may ensue. */
|
after changing this - otherwise, SEGVs may ensue. */
|
||||||
|
|
||||||
#define MAP_SIZE_POW2 16
|
#define MAP_SIZE_POW2 16
|
||||||
#define MAP_SIZE (1 << MAP_SIZE_POW2)
|
#define MAP_SIZE (1U << MAP_SIZE_POW2)
|
||||||
|
|
||||||
/* Maximum allocator request size (keep well under INT_MAX): */
|
/* Maximum allocator request size (keep well under INT_MAX): */
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ static inline const char *colorfilter(const char *x) {
|
|||||||
\
|
\
|
||||||
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
|
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
|
||||||
"\n[-] PROGRAM ABORT : " cRST x); \
|
"\n[-] PROGRAM ABORT : " cRST x); \
|
||||||
SAYF(cLRD "\n Location : " cRST "%s(), %s:%u\n\n", __func__, \
|
SAYF(cLRD "\n Location : " cRST "%s(), %s:%d\n\n", __func__, \
|
||||||
__FILE__, __LINE__); \
|
__FILE__, __LINE__); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
\
|
\
|
||||||
@ -308,7 +308,7 @@ static inline const char *colorfilter(const char *x) {
|
|||||||
\
|
\
|
||||||
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
|
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
|
||||||
"\n[-] PROGRAM ABORT : " cRST x); \
|
"\n[-] PROGRAM ABORT : " cRST x); \
|
||||||
SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n\n", __func__, \
|
SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%d\n\n", __func__, \
|
||||||
__FILE__, __LINE__); \
|
__FILE__, __LINE__); \
|
||||||
abort(); \
|
abort(); \
|
||||||
\
|
\
|
||||||
@ -322,7 +322,7 @@ static inline const char *colorfilter(const char *x) {
|
|||||||
fflush(stdout); \
|
fflush(stdout); \
|
||||||
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
|
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD \
|
||||||
"\n[-] SYSTEM ERROR : " cRST x); \
|
"\n[-] SYSTEM ERROR : " cRST x); \
|
||||||
SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%u\n", __func__, \
|
SAYF(cLRD "\n Stop location : " cRST "%s(), %s:%d\n", __func__, \
|
||||||
__FILE__, __LINE__); \
|
__FILE__, __LINE__); \
|
||||||
SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \
|
SAYF(cLRD " OS message : " cRST "%s\n", strerror(errno)); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
|
@ -61,6 +61,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_IMPORT_FIRST",
|
"AFL_IMPORT_FIRST",
|
||||||
"AFL_INST_LIBS",
|
"AFL_INST_LIBS",
|
||||||
"AFL_INST_RATIO",
|
"AFL_INST_RATIO",
|
||||||
|
"AFL_KILL_SIGNAL",
|
||||||
"AFL_KEEP_TRACES",
|
"AFL_KEEP_TRACES",
|
||||||
"AFL_KEEP_ASSEMBLY",
|
"AFL_KEEP_ASSEMBLY",
|
||||||
"AFL_LD_HARD_FAIL",
|
"AFL_LD_HARD_FAIL",
|
||||||
|
@ -99,6 +99,8 @@ typedef struct afl_forkserver {
|
|||||||
|
|
||||||
void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len);
|
void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len);
|
||||||
|
|
||||||
|
u8 kill_signal;
|
||||||
|
|
||||||
} afl_forkserver_t;
|
} afl_forkserver_t;
|
||||||
|
|
||||||
typedef enum fsrv_run_result {
|
typedef enum fsrv_run_result {
|
||||||
|
@ -50,7 +50,7 @@ typedef uint32_t u32;
|
|||||||
#define FS_OPT_SHDMEM_FUZZ 0x01000000
|
#define FS_OPT_SHDMEM_FUZZ 0x01000000
|
||||||
#define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000
|
#define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000
|
||||||
// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22
|
// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22
|
||||||
#define FS_OPT_MAX_MAPSIZE ((0x00fffffe >> 1) + 1)
|
#define FS_OPT_MAX_MAPSIZE ((0x00fffffeU >> 1) + 1)
|
||||||
#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 > FS_OPT_MAX_MAPSIZE ? 0 : ((x - 1) << 1))
|
(x <= 1 || x > FS_OPT_MAX_MAPSIZE ? 0 : ((x - 1) << 1))
|
||||||
|
@ -200,7 +200,7 @@ struct InsTrim : public ModulePass {
|
|||||||
LoadInst * PrevCtx = NULL; // for CTX sensitive coverage
|
LoadInst * PrevCtx = NULL; // for CTX sensitive coverage
|
||||||
|
|
||||||
if (ctx_str)
|
if (ctx_str)
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__HAIKU__)
|
||||||
AFLContext = new GlobalVariable(
|
AFLContext = new GlobalVariable(
|
||||||
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx");
|
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx");
|
||||||
#else
|
#else
|
||||||
@ -211,7 +211,7 @@ struct InsTrim : public ModulePass {
|
|||||||
|
|
||||||
#ifdef AFL_HAVE_VECTOR_INTRINSICS
|
#ifdef AFL_HAVE_VECTOR_INTRINSICS
|
||||||
if (ngram_size)
|
if (ngram_size)
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__HAIKU__)
|
||||||
AFLPrevLoc = new GlobalVariable(
|
AFLPrevLoc = new GlobalVariable(
|
||||||
M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
|
M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
|
||||||
/* Initializer */ nullptr, "__afl_prev_loc");
|
/* Initializer */ nullptr, "__afl_prev_loc");
|
||||||
@ -224,7 +224,7 @@ struct InsTrim : public ModulePass {
|
|||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__HAIKU__)
|
||||||
AFLPrevLoc = new GlobalVariable(
|
AFLPrevLoc = new GlobalVariable(
|
||||||
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc");
|
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc");
|
||||||
#else
|
#else
|
||||||
@ -407,10 +407,10 @@ struct InsTrim : public ModulePass {
|
|||||||
// does the function have calls? and is any of the calls larger than
|
// does the function have calls? and is any of the calls larger than
|
||||||
// one basic block?
|
// one basic block?
|
||||||
has_calls = 0;
|
has_calls = 0;
|
||||||
for (auto &BB : F) {
|
for (auto &BB2 : F) {
|
||||||
|
|
||||||
if (has_calls) break;
|
if (has_calls) break;
|
||||||
for (auto &IN : BB) {
|
for (auto &IN : BB2) {
|
||||||
|
|
||||||
CallInst *callInst = nullptr;
|
CallInst *callInst = nullptr;
|
||||||
if ((callInst = dyn_cast<CallInst>(&IN))) {
|
if ((callInst = dyn_cast<CallInst>(&IN))) {
|
||||||
@ -454,7 +454,7 @@ struct InsTrim : public ModulePass {
|
|||||||
|
|
||||||
auto *PN = PHINode::Create(Int32Ty, 0, "", &*BB.begin());
|
auto *PN = PHINode::Create(Int32Ty, 0, "", &*BB.begin());
|
||||||
DenseMap<BasicBlock *, unsigned> PredMap;
|
DenseMap<BasicBlock *, unsigned> PredMap;
|
||||||
for (auto PI = pred_begin(&BB), PE = pred_end(&BB); PI != PE; ++PI) {
|
for (PI = pred_begin(&BB), PE = pred_end(&BB); PI != PE; ++PI) {
|
||||||
|
|
||||||
BasicBlock *PBB = *PI;
|
BasicBlock *PBB = *PI;
|
||||||
auto It = PredMap.insert({PBB, genLabel()});
|
auto It = PredMap.insert({PBB, genLabel()});
|
||||||
@ -568,7 +568,7 @@ struct InsTrim : public ModulePass {
|
|||||||
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
|
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
|
||||||
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
|
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
|
||||||
|
|
||||||
OKF("Instrumented %u locations (%llu, %llu) (%s mode)\n", total_instr,
|
OKF("Instrumented %d locations (%llu, %llu) (%s mode)\n", total_instr,
|
||||||
total_rs, total_hs, modeline);
|
total_rs, total_hs, modeline);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -332,11 +332,11 @@ bool Indistinguish(uint32_t node1, uint32_t node2) {
|
|||||||
|
|
||||||
void MakeUniq(uint32_t now) {
|
void MakeUniq(uint32_t now) {
|
||||||
|
|
||||||
bool StopFlag = false;
|
|
||||||
if (Marked.find(now) == Marked.end()) {
|
if (Marked.find(now) == Marked.end()) {
|
||||||
|
|
||||||
for (uint32_t pred1 : t_Pred[now]) {
|
for (uint32_t pred1 : t_Pred[now]) {
|
||||||
|
|
||||||
|
bool StopFlag = false;
|
||||||
for (uint32_t pred2 : t_Pred[now]) {
|
for (uint32_t pred2 : t_Pred[now]) {
|
||||||
|
|
||||||
if (pred1 == pred2) continue;
|
if (pred1 == pred2) continue;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
# Using afl++ with partial instrumentation
|
# Using afl++ with partial instrumentation
|
||||||
|
|
||||||
This file describes how to selectively instrument only source files
|
This file describes two different mechanisms to selectively instrument
|
||||||
or functions that are of interest to you using the LLVM and GCC_PLUGIN
|
only specific parts in the target.
|
||||||
instrumentation provided by afl++.
|
|
||||||
|
Both mechanisms work for LLVM and GCC_PLUGIN, but not for afl-clang/afl-gcc.
|
||||||
|
|
||||||
## 1) Description and purpose
|
## 1) Description and purpose
|
||||||
|
|
||||||
@ -12,28 +13,42 @@ the program, leaving the rest uninstrumented. This helps to focus the fuzzer
|
|||||||
on the important parts of the program, avoiding undesired noise and
|
on the important parts of the program, avoiding undesired noise and
|
||||||
disturbance by uninteresting code being exercised.
|
disturbance by uninteresting code being exercised.
|
||||||
|
|
||||||
For this purpose, a "partial instrumentation" support en par with llvm sancov
|
For this purpose, "partial instrumentation" support is provided by afl++ that
|
||||||
is provided by afl++ that allows to specify on a source file and function
|
allows to specify what should be instrumented and what not.
|
||||||
level which function should be compiled with or without instrumentation.
|
|
||||||
|
|
||||||
Note: When using PCGUARD mode - and llvm 12+ - you can use this instead:
|
Both mechanisms can be used together.
|
||||||
https://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation
|
|
||||||
|
|
||||||
The llvm sancov list format is fully supported by afl++, however afl++ has
|
## 2) Selective instrumentation with __AFL_COVERAGE_... directives
|
||||||
more flexibility.
|
|
||||||
|
|
||||||
## 2a) Building the LLVM module
|
In this mechanism the selective instrumentation is done in the source code.
|
||||||
|
|
||||||
The new code is part of the existing afl++ LLVM module in the instrumentation/
|
After the includes a special define has to be made, eg.:
|
||||||
subdirectory. There is nothing specifically to do for the build :)
|
|
||||||
|
|
||||||
## 2b) Building the GCC module
|
```
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
// ...
|
||||||
|
|
||||||
|
__AFL_COVERAGE(); // <- required for this feature to work
|
||||||
|
```
|
||||||
|
|
||||||
The new code is part of the existing afl++ GCC_PLUGIN module in the
|
If you want to disable the coverage at startup until you specify coverage
|
||||||
instrumentation/ subdirectory. There is nothing specifically to do for
|
should be started, then add `__AFL_COVERAGE_START_OFF();` at that position.
|
||||||
the build :)
|
|
||||||
|
|
||||||
## 3) How to use the partial instrumentation mode
|
From here on out you have the following macros available that you can use
|
||||||
|
in any function where you want:
|
||||||
|
|
||||||
|
* `__AFL_COVERAGE_ON();` - enable coverage from this point onwards
|
||||||
|
* `__AFL_COVERAGE_OFF();` - disable coverage from this point onwards
|
||||||
|
* `__AFL_COVERAGE_DISCARD();` - reset all coverage gathered until this point
|
||||||
|
* `__AFL_COVERAGE_ABORT();` - mark this test case as unimportant. Whatever happens, afl-fuzz will ignore it.
|
||||||
|
|
||||||
|
## 3) Selective instrumenation with AFL_LLVM_ALLOWLIST/AFL_LLVM_DENYLIST
|
||||||
|
|
||||||
|
This feature is equivalent to llvm 12 sancov feature and allows to specify
|
||||||
|
on a filename and/or function name level to instrument these or skip them.
|
||||||
|
|
||||||
|
### 3a) How to use the partial instrumentation mode
|
||||||
|
|
||||||
In order to build with partial instrumentation, you need to build with
|
In order to build with partial instrumentation, you need to build with
|
||||||
afl-clang-fast/afl-clang-fast++ or afl-clang-lto/afl-clang-lto++.
|
afl-clang-fast/afl-clang-fast++ or afl-clang-lto/afl-clang-lto++.
|
||||||
@ -90,7 +105,7 @@ fun: MallocFoo
|
|||||||
```
|
```
|
||||||
Note that whitespace is ignored and comments (`# foo`) are supported.
|
Note that whitespace is ignored and comments (`# foo`) are supported.
|
||||||
|
|
||||||
## 4) UNIX-style pattern matching
|
### 3b) UNIX-style pattern matching
|
||||||
|
|
||||||
You can add UNIX-style pattern matching in the "instrument file list" entries.
|
You can add UNIX-style pattern matching in the "instrument file list" entries.
|
||||||
See `man fnmatch` for the syntax. We do not set any of the `fnmatch` flags.
|
See `man fnmatch` for the syntax. We do not set any of the `fnmatch` flags.
|
||||||
|
@ -1403,24 +1403,17 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
|
|||||||
|
|
||||||
BasicBlock::iterator IP = BB.getFirstInsertionPt();
|
BasicBlock::iterator IP = BB.getFirstInsertionPt();
|
||||||
bool IsEntryBB = &BB == &F.getEntryBlock();
|
bool IsEntryBB = &BB == &F.getEntryBlock();
|
||||||
DebugLoc EntryLoc;
|
|
||||||
if (IsEntryBB) {
|
if (IsEntryBB) {
|
||||||
|
|
||||||
if (auto SP = F.getSubprogram())
|
|
||||||
EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP);
|
|
||||||
// Keep static allocas and llvm.localescape calls in the entry block. Even
|
// Keep static allocas and llvm.localescape calls in the entry block. Even
|
||||||
// if we aren't splitting the block, it's nice for allocas to be before
|
// if we aren't splitting the block, it's nice for allocas to be before
|
||||||
// calls.
|
// calls.
|
||||||
IP = PrepareToSplitEntryBlock(BB, IP);
|
IP = PrepareToSplitEntryBlock(BB, IP);
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
EntryLoc = IP->getDebugLoc();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IRBuilder<> IRB(&*IP);
|
IRBuilder<> IRB(&*IP);
|
||||||
IRB.SetCurrentDebugLocation(EntryLoc);
|
|
||||||
if (Options.TracePC) {
|
if (Options.TracePC) {
|
||||||
|
|
||||||
IRB.CreateCall(SanCovTracePC)
|
IRB.CreateCall(SanCovTracePC)
|
||||||
|
@ -1163,24 +1163,18 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
|
|||||||
|
|
||||||
BasicBlock::iterator IP = BB.getFirstInsertionPt();
|
BasicBlock::iterator IP = BB.getFirstInsertionPt();
|
||||||
bool IsEntryBB = &BB == &F.getEntryBlock();
|
bool IsEntryBB = &BB == &F.getEntryBlock();
|
||||||
DebugLoc EntryLoc;
|
|
||||||
if (IsEntryBB) {
|
if (IsEntryBB) {
|
||||||
|
|
||||||
if (auto SP = F.getSubprogram())
|
|
||||||
EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP);
|
|
||||||
// Keep static allocas and llvm.localescape calls in the entry block. Even
|
// Keep static allocas and llvm.localescape calls in the entry block. Even
|
||||||
// if we aren't splitting the block, it's nice for allocas to be before
|
// if we aren't splitting the block, it's nice for allocas to be before
|
||||||
// calls.
|
// calls.
|
||||||
IP = PrepareToSplitEntryBlock(BB, IP);
|
IP = PrepareToSplitEntryBlock(BB, IP);
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
EntryLoc = IP->getDebugLoc();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IRBuilder<> IRB(&*IP);
|
IRBuilder<> IRB(&*IP);
|
||||||
IRB.SetCurrentDebugLocation(EntryLoc);
|
|
||||||
if (Options.TracePC) {
|
if (Options.TracePC) {
|
||||||
|
|
||||||
IRB.CreateCall(SanCovTracePC);
|
IRB.CreateCall(SanCovTracePC);
|
||||||
|
@ -76,7 +76,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
u8 __afl_area_initial[MAP_INITIAL_SIZE];
|
u8 __afl_area_initial[MAP_INITIAL_SIZE];
|
||||||
|
u8 * __afl_area_ptr_dummy = __afl_area_initial;
|
||||||
u8 * __afl_area_ptr = __afl_area_initial;
|
u8 * __afl_area_ptr = __afl_area_initial;
|
||||||
|
u8 * __afl_area_ptr_backup = __afl_area_initial;
|
||||||
u8 * __afl_dictionary;
|
u8 * __afl_dictionary;
|
||||||
u8 * __afl_fuzz_ptr;
|
u8 * __afl_fuzz_ptr;
|
||||||
u32 __afl_fuzz_len_dummy;
|
u32 __afl_fuzz_len_dummy;
|
||||||
@ -87,7 +89,12 @@ u32 __afl_map_size = MAP_SIZE;
|
|||||||
u32 __afl_dictionary_len;
|
u32 __afl_dictionary_len;
|
||||||
u64 __afl_map_addr;
|
u64 __afl_map_addr;
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
// for the __AFL_COVERAGE_ON/__AFL_COVERAGE_OFF features to work:
|
||||||
|
int __afl_selective_coverage __attribute__((weak));
|
||||||
|
int __afl_selective_coverage_start_off __attribute__((weak));
|
||||||
|
int __afl_selective_coverage_temp = 1;
|
||||||
|
|
||||||
|
#if defined(__ANDROID__) || defined(__HAIKU__)
|
||||||
PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX];
|
PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX];
|
||||||
u32 __afl_prev_ctx;
|
u32 __afl_prev_ctx;
|
||||||
u32 __afl_cmp_counter;
|
u32 __afl_cmp_counter;
|
||||||
@ -100,6 +107,7 @@ __thread u32 __afl_cmp_counter;
|
|||||||
int __afl_sharedmem_fuzzing __attribute__((weak));
|
int __afl_sharedmem_fuzzing __attribute__((weak));
|
||||||
|
|
||||||
struct cmp_map *__afl_cmp_map;
|
struct cmp_map *__afl_cmp_map;
|
||||||
|
struct cmp_map *__afl_cmp_map_backup;
|
||||||
|
|
||||||
/* Child pid? */
|
/* Child pid? */
|
||||||
|
|
||||||
@ -230,7 +238,7 @@ static void __afl_map_shm_fuzz() {
|
|||||||
static void __afl_map_shm(void) {
|
static void __afl_map_shm(void) {
|
||||||
|
|
||||||
// if we are not running in afl ensure the map exists
|
// if we are not running in afl ensure the map exists
|
||||||
if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_initial; }
|
if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_ptr_dummy; }
|
||||||
|
|
||||||
char *id_str = getenv(SHM_ENV_VAR);
|
char *id_str = getenv(SHM_ENV_VAR);
|
||||||
|
|
||||||
@ -295,11 +303,17 @@ static void __afl_map_shm(void) {
|
|||||||
|
|
||||||
if (__afl_area_ptr && __afl_area_ptr != __afl_area_initial) {
|
if (__afl_area_ptr && __afl_area_ptr != __afl_area_initial) {
|
||||||
|
|
||||||
if (__afl_map_addr)
|
if (__afl_map_addr) {
|
||||||
|
|
||||||
munmap((void *)__afl_map_addr, __afl_final_loc);
|
munmap((void *)__afl_map_addr, __afl_final_loc);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
free(__afl_area_ptr);
|
free(__afl_area_ptr);
|
||||||
__afl_area_ptr = __afl_area_initial;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__afl_area_ptr = __afl_area_ptr_dummy;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,9 +410,42 @@ static void __afl_map_shm(void) {
|
|||||||
|
|
||||||
free(__afl_area_ptr);
|
free(__afl_area_ptr);
|
||||||
__afl_area_ptr = NULL;
|
__afl_area_ptr = NULL;
|
||||||
if (__afl_final_loc > MAP_INITIAL_SIZE)
|
|
||||||
|
if (__afl_final_loc > MAP_INITIAL_SIZE) {
|
||||||
|
|
||||||
__afl_area_ptr = malloc(__afl_final_loc);
|
__afl_area_ptr = malloc(__afl_final_loc);
|
||||||
if (!__afl_area_ptr) __afl_area_ptr = __afl_area_initial;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!__afl_area_ptr) { __afl_area_ptr = __afl_area_ptr_dummy; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__afl_area_ptr_backup = __afl_area_ptr;
|
||||||
|
|
||||||
|
if (__afl_selective_coverage) {
|
||||||
|
|
||||||
|
if (__afl_map_size > MAP_INITIAL_SIZE) {
|
||||||
|
|
||||||
|
__afl_area_ptr_dummy = malloc(__afl_map_size);
|
||||||
|
|
||||||
|
if (__afl_area_ptr_dummy) {
|
||||||
|
|
||||||
|
if (__afl_selective_coverage_start_off) {
|
||||||
|
|
||||||
|
__afl_area_ptr = __afl_area_ptr_dummy;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: __afl_selective_coverage failed!\n");
|
||||||
|
__afl_selective_coverage = 0;
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,6 +496,8 @@ static void __afl_map_shm(void) {
|
|||||||
__afl_cmp_map = shmat(shm_id, NULL, 0);
|
__afl_cmp_map = shmat(shm_id, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
__afl_cmp_map_backup = __afl_cmp_map;
|
||||||
|
|
||||||
if (!__afl_cmp_map || __afl_cmp_map == (void *)-1) {
|
if (!__afl_cmp_map || __afl_cmp_map == (void *)-1) {
|
||||||
|
|
||||||
perror("shmat for cmplog");
|
perror("shmat for cmplog");
|
||||||
@ -683,7 +732,7 @@ static void __afl_start_forkserver(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
u8 tmp[4] = {0, 0, 0, 0};
|
u8 tmp[4] = {0, 0, 0, 0};
|
||||||
u32 status = 0;
|
u32 status_for_fsrv = 0;
|
||||||
u32 already_read_first = 0;
|
u32 already_read_first = 0;
|
||||||
u32 was_killed;
|
u32 was_killed;
|
||||||
|
|
||||||
@ -691,17 +740,26 @@ static void __afl_start_forkserver(void) {
|
|||||||
|
|
||||||
void (*old_sigchld_handler)(int) = 0; // = signal(SIGCHLD, SIG_DFL);
|
void (*old_sigchld_handler)(int) = 0; // = signal(SIGCHLD, SIG_DFL);
|
||||||
|
|
||||||
if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
|
if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) {
|
||||||
status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
|
|
||||||
if (__afl_dictionary_len && __afl_dictionary) status |= FS_OPT_AUTODICT;
|
status_for_fsrv |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
|
||||||
if (__afl_sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
|
|
||||||
if (status) status |= (FS_OPT_ENABLED);
|
}
|
||||||
memcpy(tmp, &status, 4);
|
|
||||||
|
if (__afl_dictionary_len && __afl_dictionary) {
|
||||||
|
|
||||||
|
status_for_fsrv |= FS_OPT_AUTODICT;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__afl_sharedmem_fuzzing != 0) { status_for_fsrv |= FS_OPT_SHDMEM_FUZZ; }
|
||||||
|
if (status_for_fsrv) { status_for_fsrv |= (FS_OPT_ENABLED); }
|
||||||
|
memcpy(tmp, &status_for_fsrv, 4);
|
||||||
|
|
||||||
/* Phone home and tell the parent that we're OK. If parent isn't there,
|
/* Phone home and tell the parent that we're OK. If parent isn't there,
|
||||||
assume we're not running in forkserver mode and just execute program. */
|
assume we're not running in forkserver mode and just execute program. */
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
|
if (write(FORKSRV_FD + 1, tmp, 4) != 4) { return; }
|
||||||
|
|
||||||
if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) {
|
if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) {
|
||||||
|
|
||||||
@ -726,7 +784,6 @@ static void __afl_start_forkserver(void) {
|
|||||||
|
|
||||||
// great lets pass the dictionary through the forkserver FD
|
// great lets pass the dictionary through the forkserver FD
|
||||||
u32 len = __afl_dictionary_len, offset = 0;
|
u32 len = __afl_dictionary_len, offset = 0;
|
||||||
s32 ret;
|
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, &len, 4) != 4) {
|
if (write(FORKSRV_FD + 1, &len, 4) != 4) {
|
||||||
|
|
||||||
@ -738,6 +795,7 @@ static void __afl_start_forkserver(void) {
|
|||||||
|
|
||||||
while (len != 0) {
|
while (len != 0) {
|
||||||
|
|
||||||
|
s32 ret;
|
||||||
ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len);
|
ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len);
|
||||||
|
|
||||||
if (ret < 1) {
|
if (ret < 1) {
|
||||||
@ -894,6 +952,8 @@ int __afl_persistent_loop(unsigned int max_cnt) {
|
|||||||
|
|
||||||
cycle_cnt = max_cnt;
|
cycle_cnt = max_cnt;
|
||||||
first_pass = 0;
|
first_pass = 0;
|
||||||
|
__afl_selective_coverage_temp = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -906,6 +966,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
|
|||||||
|
|
||||||
__afl_area_ptr[0] = 1;
|
__afl_area_ptr[0] = 1;
|
||||||
memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
|
memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
|
||||||
|
__afl_selective_coverage_temp = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -915,7 +976,7 @@ int __afl_persistent_loop(unsigned int max_cnt) {
|
|||||||
follows the loop is not traced. We do that by pivoting back to the
|
follows the loop is not traced. We do that by pivoting back to the
|
||||||
dummy output region. */
|
dummy output region. */
|
||||||
|
|
||||||
__afl_area_ptr = __afl_area_initial;
|
__afl_area_ptr = __afl_area_ptr_dummy;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -937,7 +998,7 @@ void __afl_manual_init(void) {
|
|||||||
init_done = 1;
|
init_done = 1;
|
||||||
is_persistent = 0;
|
is_persistent = 0;
|
||||||
__afl_sharedmem_fuzzing = 0;
|
__afl_sharedmem_fuzzing = 0;
|
||||||
if (__afl_area_ptr == NULL) __afl_area_ptr = __afl_area_initial;
|
if (__afl_area_ptr == NULL) __afl_area_ptr = __afl_area_ptr_dummy;
|
||||||
|
|
||||||
if (getenv("AFL_DEBUG"))
|
if (getenv("AFL_DEBUG"))
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -998,7 +1059,12 @@ __attribute__((constructor(1))) void __afl_auto_second(void) {
|
|||||||
else
|
else
|
||||||
ptr = (u8 *)malloc(__afl_final_loc);
|
ptr = (u8 *)malloc(__afl_final_loc);
|
||||||
|
|
||||||
if (ptr && (ssize_t)ptr != -1) __afl_area_ptr = ptr;
|
if (ptr && (ssize_t)ptr != -1) {
|
||||||
|
|
||||||
|
__afl_area_ptr = ptr;
|
||||||
|
__afl_area_ptr_backup = __afl_area_ptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1014,7 +1080,12 @@ __attribute__((constructor(0))) void __afl_auto_first(void) {
|
|||||||
|
|
||||||
ptr = (u8 *)malloc(1024000);
|
ptr = (u8 *)malloc(1024000);
|
||||||
|
|
||||||
if (ptr && (ssize_t)ptr != -1) __afl_area_ptr = ptr;
|
if (ptr && (ssize_t)ptr != -1) {
|
||||||
|
|
||||||
|
__afl_area_ptr = ptr;
|
||||||
|
__afl_area_ptr_backup = __afl_area_ptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1304,3 +1375,69 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* COVERAGE manipulation features */
|
||||||
|
|
||||||
|
// this variable is then used in the shm setup to create an additional map
|
||||||
|
// if __afl_map_size > MAP_SIZE or cmplog is used.
|
||||||
|
// Especially with cmplog this would result in a ~260MB mem increase per
|
||||||
|
// target run.
|
||||||
|
|
||||||
|
// disable coverage from this point onwards until turned on again
|
||||||
|
void __afl_coverage_off() {
|
||||||
|
|
||||||
|
if (likely(__afl_selective_coverage)) {
|
||||||
|
|
||||||
|
__afl_area_ptr = __afl_area_ptr_dummy;
|
||||||
|
__afl_cmp_map = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable coverage
|
||||||
|
void __afl_coverage_on() {
|
||||||
|
|
||||||
|
if (likely(__afl_selective_coverage && __afl_selective_coverage_temp)) {
|
||||||
|
|
||||||
|
__afl_area_ptr = __afl_area_ptr_backup;
|
||||||
|
__afl_cmp_map = __afl_cmp_map_backup;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// discard all coverage up to this point
|
||||||
|
void __afl_coverage_discard() {
|
||||||
|
|
||||||
|
memset(__afl_area_ptr_backup, 0, __afl_map_size);
|
||||||
|
__afl_area_ptr_backup[0] = 1;
|
||||||
|
|
||||||
|
if (__afl_cmp_map) { memset(__afl_cmp_map, 0, sizeof(struct cmp_map)); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// discard the testcase
|
||||||
|
void __afl_coverage_abort() {
|
||||||
|
|
||||||
|
__afl_coverage_discard();
|
||||||
|
|
||||||
|
if (likely(is_persistent && __afl_selective_coverage)) {
|
||||||
|
|
||||||
|
__afl_coverage_off();
|
||||||
|
__afl_selective_coverage_temp = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark this area as especially interesting
|
||||||
|
void __afl_coverage_interesting(u8 val, u32 id) {
|
||||||
|
|
||||||
|
__afl_area_ptr[id] = val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ struct afl_pass : gimple_opt_pass {
|
|||||||
const bool neverZero;
|
const bool neverZero;
|
||||||
|
|
||||||
/* Count instrumented blocks. */
|
/* Count instrumented blocks. */
|
||||||
int inst_blocks;
|
unsigned int inst_blocks;
|
||||||
|
|
||||||
virtual unsigned int execute(function *fn) {
|
virtual unsigned int execute(function *fn) {
|
||||||
|
|
||||||
@ -444,8 +444,10 @@ struct afl_pass : gimple_opt_pass {
|
|||||||
DECL_EXTERNAL(decl) = 1;
|
DECL_EXTERNAL(decl) = 1;
|
||||||
DECL_ARTIFICIAL(decl) = 1;
|
DECL_ARTIFICIAL(decl) = 1;
|
||||||
TREE_STATIC(decl) = 1;
|
TREE_STATIC(decl) = 1;
|
||||||
|
#if !defined(__ANDROID__) && !defined(__HAIKU__)
|
||||||
set_decl_tls_model(
|
set_decl_tls_model(
|
||||||
decl, (flag_pic ? TLS_MODEL_INITIAL_EXEC : TLS_MODEL_LOCAL_EXEC));
|
decl, (flag_pic ? TLS_MODEL_INITIAL_EXEC : TLS_MODEL_LOCAL_EXEC));
|
||||||
|
#endif
|
||||||
return decl;
|
return decl;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -920,8 +922,9 @@ int plugin_init(struct plugin_name_args * info,
|
|||||||
struct plugin_gcc_version *version) {
|
struct plugin_gcc_version *version) {
|
||||||
|
|
||||||
if (!plugin_default_version_check(version, &gcc_version))
|
if (!plugin_default_version_check(version, &gcc_version))
|
||||||
FATAL(G_("GCC and plugin have incompatible versions, expected GCC %d.%d"),
|
FATAL(G_("GCC and plugin have incompatible versions, expected GCC %s, "
|
||||||
GCCPLUGIN_VERSION_MAJOR, GCCPLUGIN_VERSION_MINOR);
|
"is %s"),
|
||||||
|
gcc_version.basever, version->basever);
|
||||||
|
|
||||||
/* Show a banner. */
|
/* Show a banner. */
|
||||||
bool quiet = false;
|
bool quiet = false;
|
||||||
@ -931,7 +934,7 @@ int plugin_init(struct plugin_name_args * info,
|
|||||||
quiet = true;
|
quiet = true;
|
||||||
|
|
||||||
/* Decide instrumentation ratio. */
|
/* Decide instrumentation ratio. */
|
||||||
int inst_ratio = 100;
|
unsigned int inst_ratio = 100U;
|
||||||
if (char *inst_ratio_str = getenv("AFL_INST_RATIO"))
|
if (char *inst_ratio_str = getenv("AFL_INST_RATIO"))
|
||||||
if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || !inst_ratio ||
|
if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || !inst_ratio ||
|
||||||
inst_ratio > 100)
|
inst_ratio > 100)
|
||||||
|
@ -355,7 +355,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
|||||||
*Str2P = callInst->getArgOperand(1);
|
*Str2P = callInst->getArgOperand(1);
|
||||||
std::string Str1, Str2;
|
std::string Str1, Str2;
|
||||||
StringRef TmpStr;
|
StringRef TmpStr;
|
||||||
bool HasStr1 = getConstantStringInfo(Str1P, TmpStr);
|
bool HasStr1;
|
||||||
|
getConstantStringInfo(Str1P, TmpStr);
|
||||||
if (TmpStr.empty()) {
|
if (TmpStr.empty()) {
|
||||||
|
|
||||||
HasStr1 = false;
|
HasStr1 = false;
|
||||||
@ -367,7 +368,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasStr2 = getConstantStringInfo(Str2P, TmpStr);
|
bool HasStr2;
|
||||||
|
getConstantStringInfo(Str2P, TmpStr);
|
||||||
if (TmpStr.empty()) {
|
if (TmpStr.empty()) {
|
||||||
|
|
||||||
HasStr2 = false;
|
HasStr2 = false;
|
||||||
|
@ -70,7 +70,7 @@ class AFLLTOPass : public ModulePass {
|
|||||||
if (getenv("AFL_DEBUG")) debug = 1;
|
if (getenv("AFL_DEBUG")) debug = 1;
|
||||||
if ((ptr = getenv("AFL_LLVM_LTO_STARTID")) != NULL)
|
if ((ptr = getenv("AFL_LLVM_LTO_STARTID")) != NULL)
|
||||||
if ((afl_global_id = atoi(ptr)) < 0 || afl_global_id >= MAP_SIZE)
|
if ((afl_global_id = atoi(ptr)) < 0 || afl_global_id >= MAP_SIZE)
|
||||||
FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is not between 0 and %d\n",
|
FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is not between 0 and %u\n",
|
||||||
ptr, MAP_SIZE - 1);
|
ptr, MAP_SIZE - 1);
|
||||||
|
|
||||||
skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
|
skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
|
||||||
@ -100,9 +100,9 @@ class AFLLTOPass : public ModulePass {
|
|||||||
|
|
||||||
bool AFLLTOPass::runOnModule(Module &M) {
|
bool AFLLTOPass::runOnModule(Module &M) {
|
||||||
|
|
||||||
LLVMContext & C = M.getContext();
|
LLVMContext & C = M.getContext();
|
||||||
std::vector<std::string> dictionary;
|
std::vector<std::string> dictionary;
|
||||||
std::vector<CallInst *> calls;
|
// std::vector<CallInst *> calls;
|
||||||
DenseMap<Value *, std::string *> valueMap;
|
DenseMap<Value *, std::string *> valueMap;
|
||||||
std::vector<BasicBlock *> BlockList;
|
std::vector<BasicBlock *> BlockList;
|
||||||
char * ptr;
|
char * ptr;
|
||||||
@ -471,7 +471,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
*Str2P = callInst->getArgOperand(1);
|
*Str2P = callInst->getArgOperand(1);
|
||||||
std::string Str1, Str2;
|
std::string Str1, Str2;
|
||||||
StringRef TmpStr;
|
StringRef TmpStr;
|
||||||
bool HasStr1 = getConstantStringInfo(Str1P, TmpStr);
|
bool HasStr1;
|
||||||
|
getConstantStringInfo(Str1P, TmpStr);
|
||||||
if (TmpStr.empty()) {
|
if (TmpStr.empty()) {
|
||||||
|
|
||||||
HasStr1 = false;
|
HasStr1 = false;
|
||||||
@ -483,7 +484,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasStr2 = getConstantStringInfo(Str2P, TmpStr);
|
bool HasStr2;
|
||||||
|
getConstantStringInfo(Str2P, TmpStr);
|
||||||
if (TmpStr.empty()) {
|
if (TmpStr.empty()) {
|
||||||
|
|
||||||
HasStr2 = false;
|
HasStr2 = false;
|
||||||
@ -671,7 +673,6 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
if (!be_quiet) {
|
if (!be_quiet) {
|
||||||
|
|
||||||
std::string outstring;
|
|
||||||
fprintf(stderr, "%s: length %zu/%zu \"", FuncName.c_str(), optLen,
|
fprintf(stderr, "%s: length %zu/%zu \"", FuncName.c_str(), optLen,
|
||||||
thestring.length());
|
thestring.length());
|
||||||
for (uint8_t i = 0; i < thestring.length(); i++) {
|
for (uint8_t i = 0; i < thestring.length(); i++) {
|
||||||
@ -799,7 +800,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
if (documentFile) {
|
if (documentFile) {
|
||||||
|
|
||||||
fprintf(documentFile, "ModuleID=%llu Function=%s edgeID=%u\n",
|
fprintf(documentFile, "ModuleID=%llu Function=%s edgeID=%d\n",
|
||||||
moduleID, F.getName().str().c_str(), afl_global_id);
|
moduleID, F.getName().str().c_str(), afl_global_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -871,10 +872,10 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
while ((map = map >> 1))
|
while ((map = map >> 1))
|
||||||
pow2map++;
|
pow2map++;
|
||||||
WARNF(
|
WARNF(
|
||||||
"We have %u blocks to instrument but the map size is only %u. Either "
|
"We have %d 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 "
|
"edit config.h and set MAP_SIZE_POW2 from %d to %u, then recompile "
|
||||||
"afl-fuzz and llvm_mode and then make this target - or set "
|
"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 "
|
"AFL_MAP_SIZE with at least size %d when running afl-fuzz with this "
|
||||||
"target.",
|
"target.",
|
||||||
afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map, afl_global_id);
|
afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map, afl_global_id);
|
||||||
|
|
||||||
@ -937,8 +938,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
if (dictionary.size()) {
|
if (dictionary.size()) {
|
||||||
|
|
||||||
size_t memlen = 0, count = 0, offset = 0;
|
size_t memlen = 0, count = 0;
|
||||||
char * ptr;
|
|
||||||
|
|
||||||
// sort and unique the dictionary
|
// sort and unique the dictionary
|
||||||
std::sort(dictionary.begin(), dictionary.end());
|
std::sort(dictionary.begin(), dictionary.end());
|
||||||
@ -953,14 +953,14 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!be_quiet)
|
if (!be_quiet)
|
||||||
printf("AUTODICTIONARY: %lu string%s found\n", count,
|
printf("AUTODICTIONARY: %zu string%s found\n", count,
|
||||||
count == 1 ? "" : "s");
|
count == 1 ? "" : "s");
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
|
|
||||||
if ((ptr = (char *)malloc(memlen + count)) == NULL) {
|
if ((ptr = (char *)malloc(memlen + count)) == NULL) {
|
||||||
|
|
||||||
fprintf(stderr, "Error: malloc for %lu bytes failed!\n",
|
fprintf(stderr, "Error: malloc for %zu bytes failed!\n",
|
||||||
memlen + count);
|
memlen + count);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
||||||
@ -968,6 +968,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
|
size_t offset = 0;
|
||||||
for (auto token : dictionary) {
|
for (auto token : dictionary) {
|
||||||
|
|
||||||
if (offset + token.length() < 0xfffff0 && count < MAX_AUTO_EXTRAS) {
|
if (offset + token.length() < 0xfffff0 && count < MAX_AUTO_EXTRAS) {
|
||||||
@ -1031,7 +1032,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
|
|||||||
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
|
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
|
||||||
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
|
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
|
||||||
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
|
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
|
||||||
OKF("Instrumented %u locations with no collisions (on average %llu "
|
OKF("Instrumented %d locations with no collisions (on average %llu "
|
||||||
"collisions would be in afl-gcc/afl-clang-fast) (%s mode).",
|
"collisions would be in afl-gcc/afl-clang-fast) (%s mode).",
|
||||||
inst_blocks, calculateCollisions(inst_blocks), modeline);
|
inst_blocks, calculateCollisions(inst_blocks), modeline);
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
GlobalVariable *AFLContext = NULL;
|
GlobalVariable *AFLContext = NULL;
|
||||||
|
|
||||||
if (ctx_str)
|
if (ctx_str)
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__HAIKU__)
|
||||||
AFLContext = new GlobalVariable(
|
AFLContext = new GlobalVariable(
|
||||||
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx");
|
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx");
|
||||||
#else
|
#else
|
||||||
@ -252,7 +252,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
|
|
||||||
#ifdef AFL_HAVE_VECTOR_INTRINSICS
|
#ifdef AFL_HAVE_VECTOR_INTRINSICS
|
||||||
if (ngram_size)
|
if (ngram_size)
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__HAIKU__)
|
||||||
AFLPrevLoc = new GlobalVariable(
|
AFLPrevLoc = new GlobalVariable(
|
||||||
M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
|
M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage,
|
||||||
/* Initializer */ nullptr, "__afl_prev_loc");
|
/* Initializer */ nullptr, "__afl_prev_loc");
|
||||||
@ -265,7 +265,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) || defined(__HAIKU__)
|
||||||
AFLPrevLoc = new GlobalVariable(
|
AFLPrevLoc = new GlobalVariable(
|
||||||
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc");
|
M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc");
|
||||||
#else
|
#else
|
||||||
@ -327,10 +327,10 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
|
|
||||||
// does the function have calls? and is any of the calls larger than one
|
// does the function have calls? and is any of the calls larger than one
|
||||||
// basic block?
|
// basic block?
|
||||||
for (auto &BB : F) {
|
for (auto &BB_2 : F) {
|
||||||
|
|
||||||
if (has_calls) break;
|
if (has_calls) break;
|
||||||
for (auto &IN : BB) {
|
for (auto &IN : BB_2) {
|
||||||
|
|
||||||
CallInst *callInst = nullptr;
|
CallInst *callInst = nullptr;
|
||||||
if ((callInst = dyn_cast<CallInst>(&IN))) {
|
if ((callInst = dyn_cast<CallInst>(&IN))) {
|
||||||
@ -628,7 +628,7 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
|
getenv("AFL_USE_MSAN") ? ", MSAN" : "",
|
||||||
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
|
getenv("AFL_USE_CFISAN") ? ", CFISAN" : "",
|
||||||
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
|
getenv("AFL_USE_UBSAN") ? ", UBSAN" : "");
|
||||||
OKF("Instrumented %u locations (%s mode, ratio %u%%).", inst_blocks,
|
OKF("Instrumented %d locations (%s mode, ratio %u%%).", inst_blocks,
|
||||||
modeline, inst_ratio);
|
modeline, inst_ratio);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -186,16 +186,19 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
|||||||
selectcmpInst->getPredicate() == CmpInst::ICMP_UGE ||
|
selectcmpInst->getPredicate() == CmpInst::ICMP_UGE ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::ICMP_SGE ||
|
selectcmpInst->getPredicate() == CmpInst::ICMP_SGE ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::ICMP_ULE ||
|
selectcmpInst->getPredicate() == CmpInst::ICMP_ULE ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) {
|
selectcmpInst->getPredicate() == CmpInst::ICMP_SLE ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_OGE ||
|
||||||
auto op0 = selectcmpInst->getOperand(0);
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UGE ||
|
||||||
auto op1 = selectcmpInst->getOperand(1);
|
selectcmpInst->getPredicate() == CmpInst::FCMP_OLE ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_ULE ||
|
||||||
IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
|
selectcmpInst->getPredicate() == CmpInst::FCMP_OGT ||
|
||||||
IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UGT ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_OLT ||
|
||||||
/* this is probably not needed but we do it anyway */
|
selectcmpInst->getPredicate() == CmpInst::FCMP_ULT ||
|
||||||
if (!intTyOp0 || !intTyOp1) { continue; }
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UEQ ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_OEQ ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UNE ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_ONE) {
|
||||||
|
|
||||||
icomps.push_back(selectcmpInst);
|
icomps.push_back(selectcmpInst);
|
||||||
|
|
||||||
@ -221,16 +224,66 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
|||||||
auto op0 = selectcmpInst->getOperand(0);
|
auto op0 = selectcmpInst->getOperand(0);
|
||||||
auto op1 = selectcmpInst->getOperand(1);
|
auto op1 = selectcmpInst->getOperand(1);
|
||||||
|
|
||||||
IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
|
IntegerType * intTyOp0 = NULL;
|
||||||
IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
|
IntegerType * intTyOp1 = NULL;
|
||||||
|
unsigned max_size = 0;
|
||||||
unsigned max_size = intTyOp0->getBitWidth() > intTyOp1->getBitWidth()
|
|
||||||
? intTyOp0->getBitWidth()
|
|
||||||
: intTyOp1->getBitWidth();
|
|
||||||
|
|
||||||
std::vector<Value *> args;
|
std::vector<Value *> args;
|
||||||
args.push_back(op0);
|
|
||||||
args.push_back(op1);
|
if (selectcmpInst->getOpcode() == Instruction::FCmp) {
|
||||||
|
|
||||||
|
auto ty0 = op0->getType();
|
||||||
|
if (ty0->isHalfTy()
|
||||||
|
#if LLVM_VERSION_MAJOR >= 11
|
||||||
|
|| ty0->isBFloatTy()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
max_size = 16;
|
||||||
|
else if (ty0->isFloatTy())
|
||||||
|
max_size = 32;
|
||||||
|
else if (ty0->isDoubleTy())
|
||||||
|
max_size = 64;
|
||||||
|
|
||||||
|
if (max_size) {
|
||||||
|
|
||||||
|
Value *V0 = IRB.CreateBitCast(op0, IntegerType::get(C, max_size));
|
||||||
|
intTyOp0 = dyn_cast<IntegerType>(V0->getType());
|
||||||
|
Value *V1 = IRB.CreateBitCast(op1, IntegerType::get(C, max_size));
|
||||||
|
intTyOp1 = dyn_cast<IntegerType>(V1->getType());
|
||||||
|
|
||||||
|
if (intTyOp0 && intTyOp1) {
|
||||||
|
|
||||||
|
max_size = intTyOp0->getBitWidth() > intTyOp1->getBitWidth()
|
||||||
|
? intTyOp0->getBitWidth()
|
||||||
|
: intTyOp1->getBitWidth();
|
||||||
|
args.push_back(V0);
|
||||||
|
args.push_back(V1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
max_size = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
intTyOp0 = dyn_cast<IntegerType>(op0->getType());
|
||||||
|
intTyOp1 = dyn_cast<IntegerType>(op1->getType());
|
||||||
|
|
||||||
|
if (intTyOp0 && intTyOp1) {
|
||||||
|
|
||||||
|
max_size = intTyOp0->getBitWidth() > intTyOp1->getBitWidth()
|
||||||
|
? intTyOp0->getBitWidth()
|
||||||
|
: intTyOp1->getBitWidth();
|
||||||
|
args.push_back(op0);
|
||||||
|
args.push_back(op1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_size < 8 || max_size > 64 || !intTyOp0 || !intTyOp1) continue;
|
||||||
|
|
||||||
switch (max_size) {
|
switch (max_size) {
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class CompareTransform : public ModulePass {
|
|||||||
const char *getPassName() const override {
|
const char *getPassName() const override {
|
||||||
|
|
||||||
#else
|
#else
|
||||||
StringRef getPassName() const override {
|
StringRef getPassName() const override {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return "transforms compare functions";
|
return "transforms compare functions";
|
||||||
@ -101,21 +101,30 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
IntegerType * Int64Ty = IntegerType::getInt64Ty(C);
|
IntegerType * Int64Ty = IntegerType::getInt64Ty(C);
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR < 9
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
Constant *
|
Function *tolowerFn;
|
||||||
#else
|
#else
|
||||||
FunctionCallee
|
FunctionCallee tolowerFn;
|
||||||
#endif
|
#endif
|
||||||
c = M.getOrInsertFunction("tolower", Int32Ty, Int32Ty
|
{
|
||||||
#if LLVM_VERSION_MAJOR < 5
|
|
||||||
,
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
#if LLVM_VERSION_MAJOR < 9
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
Function *tolowerFn = cast<Function>(c);
|
Constant *
|
||||||
#else
|
#else
|
||||||
FunctionCallee tolowerFn = c;
|
FunctionCallee
|
||||||
#endif
|
#endif
|
||||||
|
c = M.getOrInsertFunction("tolower", Int32Ty, Int32Ty
|
||||||
|
#if LLVM_VERSION_MAJOR < 5
|
||||||
|
,
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
#if LLVM_VERSION_MAJOR < 9
|
||||||
|
tolowerFn = cast<Function>(c);
|
||||||
|
#else
|
||||||
|
tolowerFn = c;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* iterate over all functions, bbs and instruction and add suitable calls to
|
/* iterate over all functions, bbs and instruction and add suitable calls to
|
||||||
* strcmp/memcmp/strncmp/strcasecmp/strncasecmp */
|
* strcmp/memcmp/strncmp/strcasecmp/strncasecmp */
|
||||||
@ -234,7 +243,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
|
|||||||
|
|
||||||
if (!HasStr2) {
|
if (!HasStr2) {
|
||||||
|
|
||||||
auto *Ptr = dyn_cast<ConstantExpr>(Str1P);
|
Ptr = dyn_cast<ConstantExpr>(Str1P);
|
||||||
if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) {
|
if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) {
|
||||||
|
|
||||||
if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
|
if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
|
||||||
|
@ -53,7 +53,7 @@ class SplitComparesTransform : public ModulePass {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
SplitComparesTransform() : ModulePass(ID) {
|
SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) {
|
||||||
|
|
||||||
initInstrumentList();
|
initInstrumentList();
|
||||||
|
|
||||||
@ -555,6 +555,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
|
if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
|
||||||
|
|
||||||
if (selectcmpInst->getPredicate() == CmpInst::FCMP_OEQ ||
|
if (selectcmpInst->getPredicate() == CmpInst::FCMP_OEQ ||
|
||||||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UEQ ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::FCMP_ONE ||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_ONE ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::FCMP_UNE ||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UNE ||
|
||||||
selectcmpInst->getPredicate() == CmpInst::FCMP_UGT ||
|
selectcmpInst->getPredicate() == CmpInst::FCMP_UGT ||
|
||||||
@ -735,6 +736,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
BasicBlock * signequal2_bb = signequal_bb;
|
BasicBlock * signequal2_bb = signequal_bb;
|
||||||
switch (FcmpInst->getPredicate()) {
|
switch (FcmpInst->getPredicate()) {
|
||||||
|
|
||||||
|
case CmpInst::FCMP_UEQ:
|
||||||
case CmpInst::FCMP_OEQ:
|
case CmpInst::FCMP_OEQ:
|
||||||
icmp_exponent_result =
|
icmp_exponent_result =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, m_e0, m_e1);
|
||||||
@ -816,6 +818,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
|
|
||||||
switch (FcmpInst->getPredicate()) {
|
switch (FcmpInst->getPredicate()) {
|
||||||
|
|
||||||
|
case CmpInst::FCMP_UEQ:
|
||||||
case CmpInst::FCMP_OEQ:
|
case CmpInst::FCMP_OEQ:
|
||||||
/* if the exponents are satifying the compare do a fraction cmp in
|
/* if the exponents are satifying the compare do a fraction cmp in
|
||||||
* middle_bb */
|
* middle_bb */
|
||||||
@ -900,11 +903,11 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
|
|
||||||
/* compare the fractions of the operands */
|
/* compare the fractions of the operands */
|
||||||
Instruction *icmp_fraction_result;
|
Instruction *icmp_fraction_result;
|
||||||
Instruction *icmp_fraction_result2;
|
|
||||||
BasicBlock * middle2_bb = middle_bb;
|
BasicBlock * middle2_bb = middle_bb;
|
||||||
PHINode * PN2 = nullptr;
|
PHINode * PN2 = nullptr;
|
||||||
switch (FcmpInst->getPredicate()) {
|
switch (FcmpInst->getPredicate()) {
|
||||||
|
|
||||||
|
case CmpInst::FCMP_UEQ:
|
||||||
case CmpInst::FCMP_OEQ:
|
case CmpInst::FCMP_OEQ:
|
||||||
icmp_fraction_result =
|
icmp_fraction_result =
|
||||||
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1);
|
CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_EQ, t_f0, t_f1);
|
||||||
@ -927,6 +930,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
case CmpInst::FCMP_OLT:
|
case CmpInst::FCMP_OLT:
|
||||||
case CmpInst::FCMP_ULT: {
|
case CmpInst::FCMP_ULT: {
|
||||||
|
|
||||||
|
Instruction *icmp_fraction_result2;
|
||||||
|
|
||||||
middle2_bb = middle_bb->splitBasicBlock(
|
middle2_bb = middle_bb->splitBasicBlock(
|
||||||
BasicBlock::iterator(middle_bb->getTerminator()));
|
BasicBlock::iterator(middle_bb->getTerminator()));
|
||||||
|
|
||||||
@ -980,6 +985,7 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
|
|
||||||
switch (FcmpInst->getPredicate()) {
|
switch (FcmpInst->getPredicate()) {
|
||||||
|
|
||||||
|
case CmpInst::FCMP_UEQ:
|
||||||
case CmpInst::FCMP_OEQ:
|
case CmpInst::FCMP_OEQ:
|
||||||
/* unequal signs cannot be equal values */
|
/* unequal signs cannot be equal values */
|
||||||
/* goto false branch */
|
/* goto false branch */
|
||||||
|
@ -1 +1 @@
|
|||||||
d66c9e2654
|
5400ce883a
|
||||||
|
Submodule qemu_mode/qemuafl updated: 21ff343837...5400ce883a
@ -903,8 +903,8 @@ static void usage(u8 *argv0) {
|
|||||||
"Execution control settings:\n"
|
"Execution control settings:\n"
|
||||||
|
|
||||||
" -f file - input file read by the tested program (stdin)\n"
|
" -f file - input file read by the tested program (stdin)\n"
|
||||||
" -t msec - timeout for each run (%d ms)\n"
|
" -t msec - timeout for each run (%u ms)\n"
|
||||||
" -m megs - memory limit for child process (%d MB)\n"
|
" -m megs - memory limit for child process (%u MB)\n"
|
||||||
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
||||||
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
|
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
|
||||||
" -W - use qemu-based instrumentation with Wine (Wine "
|
" -W - use qemu-based instrumentation with Wine (Wine "
|
||||||
|
125
src/afl-cc.c
125
src/afl-cc.c
@ -120,8 +120,13 @@ char compiler_mode_string[7][12] = {
|
|||||||
|
|
||||||
u8 *getthecwd() {
|
u8 *getthecwd() {
|
||||||
|
|
||||||
static u8 fail[] = "";
|
if (getcwd(cwd, sizeof(cwd)) == NULL) {
|
||||||
if (getcwd(cwd, sizeof(cwd)) == NULL) return fail;
|
|
||||||
|
static u8 fail[] = "";
|
||||||
|
return fail;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return cwd;
|
return cwd;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -654,9 +659,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 idx;
|
|
||||||
if (lto_mode && argc > 1) {
|
if (lto_mode && argc > 1) {
|
||||||
|
|
||||||
|
u32 idx;
|
||||||
for (idx = 1; idx < argc; idx++) {
|
for (idx = 1; idx < argc; idx++) {
|
||||||
|
|
||||||
if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
|
if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
|
||||||
@ -787,8 +792,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USEMMAP) && !defined(__HAIKU__)
|
#if defined(USEMMAP)
|
||||||
|
#if !defined(__HAIKU__)
|
||||||
cc_params[cc_par_cnt++] = "-lrt";
|
cc_params[cc_par_cnt++] = "-lrt";
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1";
|
cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1";
|
||||||
@ -822,6 +829,35 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
"extern unsigned char *__afl_fuzz_ptr;"
|
"extern unsigned char *__afl_fuzz_ptr;"
|
||||||
"unsigned char __afl_fuzz_alt[1048576];"
|
"unsigned char __afl_fuzz_alt[1048576];"
|
||||||
"unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;";
|
"unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt;";
|
||||||
|
|
||||||
|
if (plusplus_mode) {
|
||||||
|
|
||||||
|
cc_params[cc_par_cnt++] =
|
||||||
|
"-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
|
||||||
|
"extern \"C\" void __afl_coverage_discard();"
|
||||||
|
"extern \"C\" void __afl_coverage_abort();"
|
||||||
|
"extern \"C\" void __afl_coverage_on();"
|
||||||
|
"extern \"C\" void __afl_coverage_off();";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cc_params[cc_par_cnt++] =
|
||||||
|
"-D__AFL_COVERAGE()=int __afl_selective_coverage = 1;"
|
||||||
|
"void __afl_coverage_discard();"
|
||||||
|
"void __afl_coverage_abort();"
|
||||||
|
"void __afl_coverage_on();"
|
||||||
|
"void __afl_coverage_off();";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_params[cc_par_cnt++] =
|
||||||
|
"-D__AFL_COVERAGE_START_OFF()=int __afl_selective_coverage_start_off = "
|
||||||
|
"1;";
|
||||||
|
cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ON()=__afl_coverage_on()";
|
||||||
|
cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_OFF()=__afl_coverage_off()";
|
||||||
|
cc_params[cc_par_cnt++] =
|
||||||
|
"-D__AFL_COVERAGE_DISCARD()=__afl_coverage_discard()";
|
||||||
|
cc_params[cc_par_cnt++] = "-D__AFL_COVERAGE_ABORT()=__afl_coverage_abort()";
|
||||||
cc_params[cc_par_cnt++] =
|
cc_params[cc_par_cnt++] =
|
||||||
"-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
|
"-D__AFL_FUZZ_TESTCASE_BUF=(__afl_fuzz_ptr ? __afl_fuzz_ptr : "
|
||||||
"__afl_fuzz_alt_ptr)";
|
"__afl_fuzz_alt_ptr)";
|
||||||
@ -931,8 +967,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
|||||||
alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
|
alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USEMMAP
|
#if defined(USEMMAP)
|
||||||
|
#if !defined(__HAIKU__)
|
||||||
cc_params[cc_par_cnt++] = "-lrt";
|
cc_params[cc_par_cnt++] = "-lrt";
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1208,12 +1246,12 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
if (getenv("AFL_LLVM_INSTRUMENT")) {
|
if (getenv("AFL_LLVM_INSTRUMENT")) {
|
||||||
|
|
||||||
u8 *ptr = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;");
|
u8 *ptr2 = strtok(getenv("AFL_LLVM_INSTRUMENT"), ":,;");
|
||||||
|
|
||||||
while (ptr) {
|
while (ptr2) {
|
||||||
|
|
||||||
if (strncasecmp(ptr, "afl", strlen("afl")) == 0 ||
|
if (strncasecmp(ptr2, "afl", strlen("afl")) == 0 ||
|
||||||
strncasecmp(ptr, "classic", strlen("classic")) == 0) {
|
strncasecmp(ptr2, "classic", strlen("classic")) == 0) {
|
||||||
|
|
||||||
if (instrument_mode == INSTRUMENT_LTO) {
|
if (instrument_mode == INSTRUMENT_LTO) {
|
||||||
|
|
||||||
@ -1229,8 +1267,8 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncasecmp(ptr, "pc-guard", strlen("pc-guard")) == 0 ||
|
if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 ||
|
||||||
strncasecmp(ptr, "pcguard", strlen("pcguard")) == 0) {
|
strncasecmp(ptr2, "pcguard", strlen("pcguard")) == 0) {
|
||||||
|
|
||||||
if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD)
|
if (!instrument_mode || instrument_mode == INSTRUMENT_PCGUARD)
|
||||||
instrument_mode = INSTRUMENT_PCGUARD;
|
instrument_mode = INSTRUMENT_PCGUARD;
|
||||||
@ -1241,8 +1279,8 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this is a hidden option
|
// this is a hidden option
|
||||||
if (strncasecmp(ptr, "llvmnative", strlen("llvmnative")) == 0 ||
|
if (strncasecmp(ptr2, "llvmnative", strlen("llvmnative")) == 0 ||
|
||||||
strncasecmp(ptr, "llvm-native", strlen("llvm-native")) == 0) {
|
strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0) {
|
||||||
|
|
||||||
if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE)
|
if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE)
|
||||||
instrument_mode = INSTRUMENT_LLVMNATIVE;
|
instrument_mode = INSTRUMENT_LLVMNATIVE;
|
||||||
@ -1252,8 +1290,8 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncasecmp(ptr, "cfg", strlen("cfg")) == 0 ||
|
if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
|
||||||
strncasecmp(ptr, "instrim", strlen("instrim")) == 0) {
|
strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) {
|
||||||
|
|
||||||
if (instrument_mode == INSTRUMENT_LTO) {
|
if (instrument_mode == INSTRUMENT_LTO) {
|
||||||
|
|
||||||
@ -1269,7 +1307,7 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncasecmp(ptr, "lto", strlen("lto")) == 0) {
|
if (strncasecmp(ptr2, "lto", strlen("lto")) == 0) {
|
||||||
|
|
||||||
lto_mode = 1;
|
lto_mode = 1;
|
||||||
if (!instrument_mode || instrument_mode == INSTRUMENT_LTO)
|
if (!instrument_mode || instrument_mode == INSTRUMENT_LTO)
|
||||||
@ -1280,7 +1318,7 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(ptr, "gcc") == 0) {
|
if (strcasecmp(ptr2, "gcc") == 0) {
|
||||||
|
|
||||||
if (!instrument_mode || instrument_mode == INSTRUMENT_GCC)
|
if (!instrument_mode || instrument_mode == INSTRUMENT_GCC)
|
||||||
instrument_mode = INSTRUMENT_GCC;
|
instrument_mode = INSTRUMENT_GCC;
|
||||||
@ -1291,7 +1329,7 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcasecmp(ptr, "clang") == 0) {
|
if (strcasecmp(ptr2, "clang") == 0) {
|
||||||
|
|
||||||
if (!instrument_mode || instrument_mode == INSTRUMENT_CLANG)
|
if (!instrument_mode || instrument_mode == INSTRUMENT_CLANG)
|
||||||
instrument_mode = INSTRUMENT_CLANG;
|
instrument_mode = INSTRUMENT_CLANG;
|
||||||
@ -1302,29 +1340,29 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncasecmp(ptr, "ctx", strlen("ctx")) == 0) {
|
if (strncasecmp(ptr2, "ctx", strlen("ctx")) == 0) {
|
||||||
|
|
||||||
instrument_opt_mode |= INSTRUMENT_OPT_CTX;
|
instrument_opt_mode |= INSTRUMENT_OPT_CTX;
|
||||||
setenv("AFL_LLVM_CTX", "1", 1);
|
setenv("AFL_LLVM_CTX", "1", 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncasecmp(ptr, "ngram", strlen("ngram")) == 0) {
|
if (strncasecmp(ptr2, "ngram", strlen("ngram")) == 0) {
|
||||||
|
|
||||||
ptr += strlen("ngram");
|
ptr2 += strlen("ngram");
|
||||||
while (*ptr && (*ptr < '0' || *ptr > '9'))
|
while (*ptr2 && (*ptr2 < '0' || *ptr2 > '9'))
|
||||||
ptr++;
|
ptr2++;
|
||||||
|
|
||||||
if (!*ptr) {
|
if (!*ptr2) {
|
||||||
|
|
||||||
if ((ptr = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL)
|
if ((ptr2 = getenv("AFL_LLVM_NGRAM_SIZE")) == NULL)
|
||||||
FATAL(
|
FATAL(
|
||||||
"you must set the NGRAM size with (e.g. for value 2) "
|
"you must set the NGRAM size with (e.g. for value 2) "
|
||||||
"AFL_LLVM_INSTRUMENT=ngram-2");
|
"AFL_LLVM_INSTRUMENT=ngram-2");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngram_size = atoi(ptr);
|
ngram_size = atoi(ptr2);
|
||||||
if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX)
|
if (ngram_size < 2 || ngram_size > NGRAM_SIZE_MAX)
|
||||||
FATAL(
|
FATAL(
|
||||||
"NGRAM instrumentation option must be between 2 and "
|
"NGRAM instrumentation option must be between 2 and "
|
||||||
@ -1332,12 +1370,12 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
"(%u)",
|
"(%u)",
|
||||||
NGRAM_SIZE_MAX);
|
NGRAM_SIZE_MAX);
|
||||||
instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM);
|
instrument_opt_mode |= (INSTRUMENT_OPT_NGRAM);
|
||||||
ptr = alloc_printf("%u", ngram_size);
|
ptr2 = alloc_printf("%u", ngram_size);
|
||||||
setenv("AFL_LLVM_NGRAM_SIZE", ptr, 1);
|
setenv("AFL_LLVM_NGRAM_SIZE", ptr2, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = strtok(NULL, ":,;");
|
ptr2 = strtok(NULL, ":,;");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1448,20 +1486,28 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
" The best is LTO but it often needs RANLIB and AR settings outside "
|
" The best is LTO but it often needs RANLIB and AR settings outside "
|
||||||
"of afl-cc.\n\n");
|
"of afl-cc.\n\n");
|
||||||
|
|
||||||
|
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
||||||
|
#define NATIVE_MSG \
|
||||||
|
" NATIVE: use llvm's native PCGUARD instrumentation (less " \
|
||||||
|
"performant)\n"
|
||||||
|
#else
|
||||||
|
#define NATIVE_MSG ""
|
||||||
|
#endif
|
||||||
|
|
||||||
SAYF(
|
SAYF(
|
||||||
"Sub-Modes: (set via env AFL_LLVM_INSTRUMENT, afl-cc selects the best "
|
"Sub-Modes: (set via env AFL_LLVM_INSTRUMENT, afl-cc selects the best "
|
||||||
"available)\n"
|
"available)\n"
|
||||||
" PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n"
|
" PCGUARD: Dominator tree instrumentation (best!) (README.llvm.md)\n"
|
||||||
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
|
||||||
" NATIVE: use llvm's native PCGUARD instrumentation (less "
|
NATIVE_MSG
|
||||||
"performant)\n"
|
|
||||||
#endif
|
|
||||||
" CLASSIC: decision target instrumentation (README.llvm.md)\n"
|
" CLASSIC: decision target instrumentation (README.llvm.md)\n"
|
||||||
" CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n"
|
" CTX: CLASSIC + callee context (instrumentation/README.ctx.md)\n"
|
||||||
" NGRAM-x: CLASSIC + previous path "
|
" NGRAM-x: CLASSIC + previous path "
|
||||||
"((instrumentation/README.ngram.md)\n"
|
"((instrumentation/README.ngram.md)\n"
|
||||||
" INSTRIM: Dominator tree (for LLVM <= 6.0) "
|
" INSTRIM: Dominator tree (for LLVM <= 6.0) "
|
||||||
"(instrumentation/README.instrim.md)\n\n");
|
"(instrumentation/README.instrim.md)\n\n");
|
||||||
|
#undef NATIVE_MSG
|
||||||
|
|
||||||
SAYF(
|
SAYF(
|
||||||
"Features: (see documentation links)\n"
|
"Features: (see documentation links)\n"
|
||||||
@ -1595,12 +1641,17 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
if (have_lto)
|
if (have_lto)
|
||||||
SAYF("afl-cc LTO with ld=%s %s\n", AFL_REAL_LD, AFL_CLANG_FLTO);
|
SAYF("afl-cc LTO with ld=%s %s\n", AFL_REAL_LD, AFL_CLANG_FLTO);
|
||||||
if (have_llvm)
|
if (have_llvm)
|
||||||
SAYF("afl-cc LLVM version %d with the the binary path \"%s\".\n",
|
SAYF("afl-cc LLVM version %d using binary path \"%s\".\n", LLVM_MAJOR,
|
||||||
LLVM_MAJOR, LLVM_BINDIR);
|
LLVM_BINDIR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USEMMAP
|
#if defined(USEMMAP)
|
||||||
|
#if !defined(__HAIKU__)
|
||||||
|
cc_params[cc_par_cnt++] = "-lrt";
|
||||||
SAYF("Compiled with shm_open support (adds -lrt when linking).\n");
|
SAYF("Compiled with shm_open support (adds -lrt when linking).\n");
|
||||||
|
#else
|
||||||
|
SAYF("Compiled with shm_open support.\n");
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
SAYF("Compiled with shmat support.\n");
|
SAYF("Compiled with shmat support.\n");
|
||||||
#endif
|
#endif
|
||||||
@ -1625,7 +1676,7 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
if (!instrument_mode) {
|
if (!instrument_mode) {
|
||||||
|
|
||||||
instrument_mode = INSTRUMENT_CFG;
|
instrument_mode = INSTRUMENT_CFG;
|
||||||
ptr = instrument_mode_string[instrument_mode];
|
// ptr = instrument_mode_string[instrument_mode];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,6 +424,40 @@ u8 *find_binary(u8 *fname) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parses the kill signal environment variable, FATALs on error.
|
||||||
|
If the env is not set, sets the env to default_signal for the signal handlers
|
||||||
|
and returns the default_signal. */
|
||||||
|
int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal) {
|
||||||
|
|
||||||
|
if (afl_kill_signal_env && afl_kill_signal_env[0]) {
|
||||||
|
|
||||||
|
char *endptr;
|
||||||
|
u8 signal_code;
|
||||||
|
signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10);
|
||||||
|
/* Did we manage to parse the full string? */
|
||||||
|
if (*endptr != '\0' || endptr == (char *)afl_kill_signal_env) {
|
||||||
|
|
||||||
|
FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)",
|
||||||
|
afl_kill_signal_env);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return signal_code;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
char *sigstr = alloc_printf("%d", default_signal);
|
||||||
|
if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); }
|
||||||
|
|
||||||
|
/* Set the env for signal handler */
|
||||||
|
setenv("AFL_KILL_SIGNAL", sigstr, 1);
|
||||||
|
free(sigstr);
|
||||||
|
return default_signal;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void check_environment_vars(char **envp) {
|
void check_environment_vars(char **envp) {
|
||||||
|
|
||||||
if (be_quiet) { return; }
|
if (be_quiet) { return; }
|
||||||
@ -696,16 +730,16 @@ u8 *stringify_mem_size(u8 *buf, size_t len, u64 val) {
|
|||||||
|
|
||||||
u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) {
|
u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) {
|
||||||
|
|
||||||
u64 delta;
|
|
||||||
s32 t_d, t_h, t_m, t_s;
|
|
||||||
u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
|
|
||||||
|
|
||||||
if (!event_ms) {
|
if (!event_ms) {
|
||||||
|
|
||||||
snprintf(buf, len, "none seen yet");
|
snprintf(buf, len, "none seen yet");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
u64 delta;
|
||||||
|
s32 t_d, t_h, t_m, t_s;
|
||||||
|
u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
|
||||||
|
|
||||||
delta = cur_ms - event_ms;
|
delta = cur_ms - event_ms;
|
||||||
|
|
||||||
t_d = delta / 1000 / 60 / 60 / 24;
|
t_d = delta / 1000 / 60 / 60 / 24;
|
||||||
@ -858,16 +892,16 @@ u8 *u_stringify_mem_size(u8 *buf, u64 val) {
|
|||||||
|
|
||||||
u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
|
u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
|
||||||
|
|
||||||
u64 delta;
|
|
||||||
s32 t_d, t_h, t_m, t_s;
|
|
||||||
u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
|
|
||||||
|
|
||||||
if (!event_ms) {
|
if (!event_ms) {
|
||||||
|
|
||||||
sprintf(buf, "none seen yet");
|
sprintf(buf, "none seen yet");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
u64 delta;
|
||||||
|
s32 t_d, t_h, t_m, t_s;
|
||||||
|
u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
|
||||||
|
|
||||||
delta = cur_ms - event_ms;
|
delta = cur_ms - event_ms;
|
||||||
|
|
||||||
t_d = delta / 1000 / 60 / 60 / 24;
|
t_d = delta / 1000 / 60 / 60 / 24;
|
||||||
@ -895,8 +929,8 @@ u32 get_map_size(void) {
|
|||||||
map_size = atoi(ptr);
|
map_size = atoi(ptr);
|
||||||
if (map_size < 8 || map_size > (1 << 29)) {
|
if (map_size < 8 || map_size > (1 << 29)) {
|
||||||
|
|
||||||
FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 8,
|
FATAL("illegal AFL_MAP_SIZE %u, must be between %u and %u", map_size, 8U,
|
||||||
1 << 29);
|
1U << 29);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
|||||||
fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT;
|
fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT;
|
||||||
fsrv->mem_limit = MEM_LIMIT;
|
fsrv->mem_limit = MEM_LIMIT;
|
||||||
fsrv->out_file = NULL;
|
fsrv->out_file = NULL;
|
||||||
|
fsrv->kill_signal = SIGKILL;
|
||||||
|
|
||||||
/* exec related stuff */
|
/* exec related stuff */
|
||||||
fsrv->child_pid = -1;
|
fsrv->child_pid = -1;
|
||||||
@ -95,7 +96,6 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
|||||||
fsrv->uses_asan = false;
|
fsrv->uses_asan = false;
|
||||||
|
|
||||||
fsrv->init_child_func = fsrv_exec_child;
|
fsrv->init_child_func = fsrv_exec_child;
|
||||||
|
|
||||||
list_append(&fsrv_list, fsrv);
|
list_append(&fsrv_list, fsrv);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -116,6 +116,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
|
|||||||
fsrv_to->no_unlink = from->no_unlink;
|
fsrv_to->no_unlink = from->no_unlink;
|
||||||
fsrv_to->uses_crash_exitcode = from->uses_crash_exitcode;
|
fsrv_to->uses_crash_exitcode = from->uses_crash_exitcode;
|
||||||
fsrv_to->crash_exitcode = from->crash_exitcode;
|
fsrv_to->crash_exitcode = from->crash_exitcode;
|
||||||
|
fsrv_to->kill_signal = from->kill_signal;
|
||||||
|
|
||||||
// These are forkserver specific.
|
// These are forkserver specific.
|
||||||
fsrv_to->out_dir_fd = -1;
|
fsrv_to->out_dir_fd = -1;
|
||||||
@ -213,7 +214,7 @@ restart_select:
|
|||||||
static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
|
static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
|
||||||
|
|
||||||
unsigned char tmp[4] = {0, 0, 0, 0};
|
unsigned char tmp[4] = {0, 0, 0, 0};
|
||||||
pid_t child_pid = -1;
|
pid_t child_pid;
|
||||||
|
|
||||||
if (!be_quiet) { ACTF("Using Fauxserver:"); }
|
if (!be_quiet) { ACTF("Using Fauxserver:"); }
|
||||||
|
|
||||||
@ -559,12 +560,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
if (!time_ms) {
|
if (!time_ms) {
|
||||||
|
|
||||||
kill(fsrv->fsrv_pid, SIGKILL);
|
kill(fsrv->fsrv_pid, fsrv->kill_signal);
|
||||||
|
|
||||||
} else if (time_ms > fsrv->init_tmout) {
|
} else if (time_ms > fsrv->init_tmout) {
|
||||||
|
|
||||||
fsrv->last_run_timed_out = 1;
|
fsrv->last_run_timed_out = 1;
|
||||||
kill(fsrv->fsrv_pid, SIGKILL);
|
kill(fsrv->fsrv_pid, fsrv->kill_signal);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -944,10 +945,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
|
static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
|
||||||
|
|
||||||
if (fsrv->child_pid > 0) { kill(fsrv->child_pid, SIGKILL); }
|
if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); }
|
||||||
if (fsrv->fsrv_pid > 0) {
|
if (fsrv->fsrv_pid > 0) {
|
||||||
|
|
||||||
kill(fsrv->fsrv_pid, SIGKILL);
|
kill(fsrv->fsrv_pid, fsrv->kill_signal);
|
||||||
if (waitpid(fsrv->fsrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); }
|
if (waitpid(fsrv->fsrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); }
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1091,7 +1092,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
/* If there was no response from forkserver after timeout seconds,
|
/* If there was no response from forkserver after timeout seconds,
|
||||||
we kill the child. The forkserver should inform us afterwards */
|
we kill the child. The forkserver should inform us afterwards */
|
||||||
|
|
||||||
kill(fsrv->child_pid, SIGKILL);
|
kill(fsrv->child_pid, fsrv->kill_signal);
|
||||||
fsrv->last_run_timed_out = 1;
|
fsrv->last_run_timed_out = 1;
|
||||||
if (read(fsrv->fsrv_st_fd, &fsrv->child_status, 4) < 4) { exec_ms = 0; }
|
if (read(fsrv->fsrv_st_fd, &fsrv->child_status, 4) < 4) { exec_ms = 0; }
|
||||||
|
|
||||||
@ -1104,7 +1105,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
"Unable to communicate with fork server. Some possible reasons:\n\n"
|
"Unable to communicate with fork server. Some possible reasons:\n\n"
|
||||||
" - You've run out of memory. Use -m to increase the the memory "
|
" - You've run out of memory. Use -m to increase the the memory "
|
||||||
"limit\n"
|
"limit\n"
|
||||||
" to something higher than %lld.\n"
|
" to something higher than %llu.\n"
|
||||||
" - The binary or one of the libraries it uses manages to "
|
" - The binary or one of the libraries it uses manages to "
|
||||||
"create\n"
|
"create\n"
|
||||||
" threads before the forkserver initializes.\n"
|
" threads before the forkserver initializes.\n"
|
||||||
@ -1137,16 +1138,18 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
|
|
||||||
/* Report outcome to caller. */
|
/* Report outcome to caller. */
|
||||||
|
|
||||||
if (WIFSIGNALED(fsrv->child_status) && !*stop_soon_p) {
|
/* Did we timeout? */
|
||||||
|
if (unlikely(fsrv->last_run_timed_out)) {
|
||||||
|
|
||||||
|
fsrv->last_kill_signal = fsrv->kill_signal;
|
||||||
|
return FSRV_RUN_TMOUT;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we crash? */
|
||||||
|
if (unlikely(WIFSIGNALED(fsrv->child_status) && !*stop_soon_p)) {
|
||||||
|
|
||||||
fsrv->last_kill_signal = WTERMSIG(fsrv->child_status);
|
fsrv->last_kill_signal = WTERMSIG(fsrv->child_status);
|
||||||
|
|
||||||
if (fsrv->last_run_timed_out && fsrv->last_kill_signal == SIGKILL) {
|
|
||||||
|
|
||||||
return FSRV_RUN_TMOUT;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return FSRV_RUN_CRASH;
|
return FSRV_RUN_CRASH;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -703,7 +703,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
if (!classified) {
|
if (!classified) {
|
||||||
|
|
||||||
classify_counts(&afl->fsrv);
|
classify_counts(&afl->fsrv);
|
||||||
classified = 1;
|
// classified = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ static void extras_check_and_sort(afl_state_t *afl, u32 min_len, u32 max_len,
|
|||||||
|
|
||||||
if (afl->extras_cnt > afl->max_det_extras) {
|
if (afl->extras_cnt > afl->max_det_extras) {
|
||||||
|
|
||||||
WARNF("More than %d tokens - will use them probabilistically.",
|
WARNF("More than %u tokens - will use them probabilistically.",
|
||||||
afl->max_det_extras);
|
afl->max_det_extras);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -431,7 +431,6 @@ void dedup_extras(afl_state_t *afl) {
|
|||||||
/* Adds a new extra / dict entry. */
|
/* Adds a new extra / dict entry. */
|
||||||
void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
|
void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
|
||||||
|
|
||||||
u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
|
|
||||||
u32 i, found = 0;
|
u32 i, found = 0;
|
||||||
|
|
||||||
for (i = 0; i < afl->extras_cnt; i++) {
|
for (i = 0; i < afl->extras_cnt; i++) {
|
||||||
@ -451,6 +450,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
|
|||||||
|
|
||||||
if (len > MAX_DICT_FILE) {
|
if (len > MAX_DICT_FILE) {
|
||||||
|
|
||||||
|
u8 val_bufs[2][STRINGIFY_VAL_SIZE_MAX];
|
||||||
WARNF("Extra '%.*s' is too big (%s, limit is %s), skipping file!", (int)len,
|
WARNF("Extra '%.*s' is too big (%s, limit is %s), skipping file!", (int)len,
|
||||||
mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len),
|
mem, stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), len),
|
||||||
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
||||||
@ -481,7 +481,7 @@ void add_extra(afl_state_t *afl, u8 *mem, u32 len) {
|
|||||||
|
|
||||||
if (afl->extras_cnt == afl->max_det_extras + 1) {
|
if (afl->extras_cnt == afl->max_det_extras + 1) {
|
||||||
|
|
||||||
WARNF("More than %d tokens - will use them probabilistically.",
|
WARNF("More than %u tokens - will use them probabilistically.",
|
||||||
afl->max_det_extras);
|
afl->max_det_extras);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -316,16 +316,20 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
|||||||
|
|
||||||
/* Initialize trimming in the custom mutator */
|
/* Initialize trimming in the custom mutator */
|
||||||
afl->stage_cur = 0;
|
afl->stage_cur = 0;
|
||||||
afl->stage_max = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len);
|
s32 retval = mutator->afl_custom_init_trim(mutator->data, in_buf, q->len);
|
||||||
if (unlikely(afl->stage_max) < 0) {
|
if (unlikely(retval) < 0) {
|
||||||
|
|
||||||
FATAL("custom_init_trim error ret: %d", afl->stage_max);
|
FATAL("custom_init_trim error ret: %d", retval);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
afl->stage_max = retval;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->not_on_tty && afl->debug) {
|
if (afl->not_on_tty && afl->debug) {
|
||||||
|
|
||||||
SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max,
|
SAYF("[Custom Trimming] START: Max %u iterations, %u bytes", afl->stage_max,
|
||||||
q->len);
|
q->len);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -343,7 +347,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
|||||||
|
|
||||||
if (unlikely(!retbuf)) {
|
if (unlikely(!retbuf)) {
|
||||||
|
|
||||||
FATAL("custom_trim failed (ret %zd)", retlen);
|
FATAL("custom_trim failed (ret %zu)", retlen);
|
||||||
|
|
||||||
} else if (unlikely(retlen > orig_len)) {
|
} else if (unlikely(retlen > orig_len)) {
|
||||||
|
|
||||||
@ -409,7 +413,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
|||||||
|
|
||||||
if (afl->not_on_tty && afl->debug) {
|
if (afl->not_on_tty && afl->debug) {
|
||||||
|
|
||||||
SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)",
|
SAYF("[Custom Trimming] SUCCESS: %u/%u iterations (now at %u bytes)",
|
||||||
afl->stage_cur, afl->stage_max, q->len);
|
afl->stage_cur, afl->stage_max, q->len);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -417,16 +421,20 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Tell the custom mutator that the trimming was unsuccessful */
|
/* Tell the custom mutator that the trimming was unsuccessful */
|
||||||
afl->stage_cur = mutator->afl_custom_post_trim(mutator->data, 0);
|
s32 retval2 = mutator->afl_custom_post_trim(mutator->data, 0);
|
||||||
if (unlikely(afl->stage_cur < 0)) {
|
if (unlikely(retval2 < 0)) {
|
||||||
|
|
||||||
FATAL("Error ret in custom_post_trim: %d", afl->stage_cur);
|
FATAL("Error ret in custom_post_trim: %d", retval2);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
afl->stage_cur = retval2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->not_on_tty && afl->debug) {
|
if (afl->not_on_tty && afl->debug) {
|
||||||
|
|
||||||
SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur,
|
SAYF("[Custom Trimming] FAILURE: %u/%u iterations", afl->stage_cur,
|
||||||
afl->stage_max);
|
afl->stage_max);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ static void locate_diffs(u8 *ptr1, u8 *ptr2, u32 len, s32 *first, s32 *last) {
|
|||||||
|
|
||||||
u8 fuzz_one_original(afl_state_t *afl) {
|
u8 fuzz_one_original(afl_state_t *afl) {
|
||||||
|
|
||||||
s32 len, temp_len;
|
u32 len, temp_len;
|
||||||
u32 j;
|
u32 j;
|
||||||
u32 i;
|
u32 i;
|
||||||
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
|
u8 *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;
|
||||||
@ -545,7 +545,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
else
|
else
|
||||||
orig_perf = perf_score = calculate_score(afl, afl->queue_cur);
|
orig_perf = perf_score = calculate_score(afl, afl->queue_cur);
|
||||||
|
|
||||||
if (unlikely(perf_score <= 0)) { goto abandon_entry; }
|
if (unlikely(perf_score == 0)) { goto abandon_entry; }
|
||||||
|
|
||||||
if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) {
|
if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) {
|
||||||
|
|
||||||
@ -902,7 +902,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
orig_hit_cnt = new_hit_cnt;
|
orig_hit_cnt = new_hit_cnt;
|
||||||
|
|
||||||
for (i = 0; (s32)i < len - 1; ++i) {
|
for (i = 0; i < len - 1; ++i) {
|
||||||
|
|
||||||
/* Let's consult the effector map... */
|
/* Let's consult the effector map... */
|
||||||
|
|
||||||
@ -945,7 +945,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
|||||||
|
|
||||||
orig_hit_cnt = new_hit_cnt;
|
orig_hit_cnt = new_hit_cnt;
|
||||||
|
|
||||||
for (i = 0; (s32)i < len - 3; ++i) {
|
for (i = 0; i < len - 3; ++i) {
|
||||||
|
|
||||||
/* Let's consult the effector map... */
|
/* Let's consult the effector map... */
|
||||||
if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&
|
if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&
|
||||||
@ -1405,7 +1405,7 @@ skip_arith:
|
|||||||
|
|
||||||
orig_hit_cnt = new_hit_cnt;
|
orig_hit_cnt = new_hit_cnt;
|
||||||
|
|
||||||
for (i = 0; (s32)i < len - 1; ++i) {
|
for (i = 0; i < len - 1; ++i) {
|
||||||
|
|
||||||
u16 orig = *(u16 *)(out_buf + i);
|
u16 orig = *(u16 *)(out_buf + i);
|
||||||
|
|
||||||
@ -1493,7 +1493,7 @@ skip_arith:
|
|||||||
|
|
||||||
orig_hit_cnt = new_hit_cnt;
|
orig_hit_cnt = new_hit_cnt;
|
||||||
|
|
||||||
for (i = 0; (s32)i < len - 3; i++) {
|
for (i = 0; i < len - 3; i++) {
|
||||||
|
|
||||||
u32 orig = *(u32 *)(out_buf + i);
|
u32 orig = *(u32 *)(out_buf + i);
|
||||||
|
|
||||||
@ -1850,7 +1850,7 @@ custom_mutator_stage:
|
|||||||
|
|
||||||
if (unlikely(!mutated_buf)) {
|
if (unlikely(!mutated_buf)) {
|
||||||
|
|
||||||
FATAL("Error in custom_fuzz. Size returned: %zd", mutated_size);
|
FATAL("Error in custom_fuzz. Size returned: %zu", mutated_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2026,7 +2026,7 @@ havoc_stage:
|
|||||||
el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
|
el->data, out_buf, temp_len, &custom_havoc_buf, MAX_FILE);
|
||||||
if (unlikely(!custom_havoc_buf)) {
|
if (unlikely(!custom_havoc_buf)) {
|
||||||
|
|
||||||
FATAL("Error in custom_havoc (return %zd)", new_len);
|
FATAL("Error in custom_havoc (return %zu)", new_len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2458,7 +2458,7 @@ havoc_stage:
|
|||||||
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
|
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
|
||||||
u32 extra_len = afl->a_extras[use_extra].len;
|
u32 extra_len = afl->a_extras[use_extra].len;
|
||||||
|
|
||||||
if ((s32)extra_len > temp_len) { break; }
|
if (extra_len > temp_len) { break; }
|
||||||
|
|
||||||
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
@ -2476,7 +2476,7 @@ havoc_stage:
|
|||||||
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
u32 use_extra = rand_below(afl, afl->extras_cnt);
|
||||||
u32 extra_len = afl->extras[use_extra].len;
|
u32 extra_len = afl->extras[use_extra].len;
|
||||||
|
|
||||||
if ((s32)extra_len > temp_len) { break; }
|
if (extra_len > temp_len) { break; }
|
||||||
|
|
||||||
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
@ -2577,7 +2577,7 @@ havoc_stage:
|
|||||||
u32 copy_from, copy_to, copy_len;
|
u32 copy_from, copy_to, copy_len;
|
||||||
|
|
||||||
copy_len = choose_block_len(afl, new_len - 1);
|
copy_len = choose_block_len(afl, new_len - 1);
|
||||||
if ((s32)copy_len > temp_len) copy_len = temp_len;
|
if (copy_len > temp_len) copy_len = temp_len;
|
||||||
|
|
||||||
copy_from = rand_below(afl, new_len - copy_len + 1);
|
copy_from = rand_below(afl, new_len - copy_len + 1);
|
||||||
copy_to = rand_below(afl, temp_len - copy_len + 1);
|
copy_to = rand_below(afl, temp_len - copy_len + 1);
|
||||||
@ -2952,7 +2952,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
|
|||||||
else
|
else
|
||||||
orig_perf = perf_score = calculate_score(afl, afl->queue_cur);
|
orig_perf = perf_score = calculate_score(afl, afl->queue_cur);
|
||||||
|
|
||||||
if (unlikely(perf_score <= 0)) { goto abandon_entry; }
|
if (unlikely(perf_score == 0)) { goto abandon_entry; }
|
||||||
|
|
||||||
if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) {
|
if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized)) {
|
||||||
|
|
||||||
|
@ -494,11 +494,12 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
|
|
||||||
void destroy_queue(afl_state_t *afl) {
|
void destroy_queue(afl_state_t *afl) {
|
||||||
|
|
||||||
struct queue_entry *q;
|
u32 i;
|
||||||
u32 i;
|
|
||||||
|
|
||||||
for (i = 0; i < afl->queued_paths; i++) {
|
for (i = 0; i < afl->queued_paths; i++) {
|
||||||
|
|
||||||
|
struct queue_entry *q;
|
||||||
|
|
||||||
q = afl->queue_buf[i];
|
q = afl->queue_buf[i];
|
||||||
ck_free(q->fname);
|
ck_free(q->fname);
|
||||||
ck_free(q->trace_mini);
|
ck_free(q->trace_mini);
|
||||||
@ -1001,7 +1002,7 @@ inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q,
|
|||||||
|
|
||||||
if (unlikely(!q->testcase_buf)) {
|
if (unlikely(!q->testcase_buf)) {
|
||||||
|
|
||||||
PFATAL("Unable to malloc '%s' with len %d", q->fname, len);
|
PFATAL("Unable to malloc '%s' with len %u", q->fname, len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,12 +99,12 @@ static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rand_replace(afl_state_t *afl, u8 *buf, u32 len) {
|
static void xor_replace(u8 *buf, u32 len) {
|
||||||
|
|
||||||
u32 i;
|
u32 i;
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
|
|
||||||
buf[i] = rand_below(afl, 256);
|
buf[i] ^= 0xff;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +115,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) {
|
|||||||
struct range *ranges = add_range(NULL, 0, len);
|
struct range *ranges = add_range(NULL, 0, len);
|
||||||
u8 * backup = ck_alloc_nozero(len);
|
u8 * backup = ck_alloc_nozero(len);
|
||||||
|
|
||||||
u8 needs_write = 0;
|
|
||||||
|
|
||||||
u64 orig_hit_cnt, new_hit_cnt;
|
u64 orig_hit_cnt, new_hit_cnt;
|
||||||
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||||
|
|
||||||
@ -136,7 +134,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) {
|
|||||||
/* Range not empty */
|
/* Range not empty */
|
||||||
|
|
||||||
memcpy(backup, buf + rng->start, s);
|
memcpy(backup, buf + rng->start, s);
|
||||||
rand_replace(afl, buf + rng->start, s);
|
xor_replace(buf + rng->start, s);
|
||||||
|
|
||||||
u64 cksum;
|
u64 cksum;
|
||||||
u64 start_us = get_cur_time_us();
|
u64 start_us = get_cur_time_us();
|
||||||
@ -158,10 +156,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) {
|
|||||||
ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end);
|
ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end);
|
||||||
memcpy(buf + rng->start, backup, s);
|
memcpy(buf + rng->start, backup, s);
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
needs_write = 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -191,32 +185,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u64 exec_cksum) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the input with the high entropy
|
|
||||||
|
|
||||||
if (needs_write) {
|
|
||||||
|
|
||||||
s32 fd;
|
|
||||||
|
|
||||||
if (afl->no_unlink) {
|
|
||||||
|
|
||||||
fd = open(afl->queue_cur->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
unlink(afl->queue_cur->fname); /* ignore errors */
|
|
||||||
fd = open(afl->queue_cur->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd < 0) { PFATAL("Unable to create '%s'", afl->queue_cur->fname); }
|
|
||||||
|
|
||||||
ck_write(fd, buf, len, afl->queue_cur->fname);
|
|
||||||
afl->queue_cur->len = len; // no-op, just to be 100% safe
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
checksum_fail:
|
checksum_fail:
|
||||||
@ -232,8 +200,6 @@ checksum_fail:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: clang notices a _potential_ leak of mem pointed to by rng
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -479,6 +445,10 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) {
|
|||||||
|
|
||||||
u32 k;
|
u32 k;
|
||||||
u8 cons_ff = 0, cons_0 = 0;
|
u8 cons_ff = 0, cons_0 = 0;
|
||||||
|
|
||||||
|
if (shape > sizeof(v))
|
||||||
|
FATAL("shape is greater than %zu, please report!", sizeof(v));
|
||||||
|
|
||||||
for (k = 0; k < shape; ++k) {
|
for (k = 0; k < shape; ++k) {
|
||||||
|
|
||||||
if (b[k] == 0) {
|
if (b[k] == 0) {
|
||||||
@ -487,7 +457,7 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) {
|
|||||||
|
|
||||||
} else if (b[k] == 0xff) {
|
} else if (b[k] == 0xff) {
|
||||||
|
|
||||||
++cons_0;
|
++cons_ff;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -701,12 +671,12 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
u8 status = 0;
|
u8 status = 0;
|
||||||
// opt not in the paper
|
// opt not in the paper
|
||||||
u32 fails = 0;
|
// u32 fails = 0;
|
||||||
u8 found_one = 0;
|
u8 found_one = 0;
|
||||||
|
|
||||||
for (i = 0; i < loggeds; ++i) {
|
for (i = 0; i < loggeds; ++i) {
|
||||||
|
|
||||||
fails = 0;
|
u32 fails = 0;
|
||||||
|
|
||||||
struct cmpfn_operands *o =
|
struct cmpfn_operands *o =
|
||||||
&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[i];
|
&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[i];
|
||||||
@ -802,13 +772,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
|||||||
u64 exec_cksum) {
|
u64 exec_cksum) {
|
||||||
|
|
||||||
u8 r = 1;
|
u8 r = 1;
|
||||||
if (afl->orig_cmp_map == NULL) {
|
if (unlikely(!afl->orig_cmp_map)) {
|
||||||
|
|
||||||
afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map));
|
afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->pass_stats == NULL) {
|
if (unlikely(!afl->pass_stats)) {
|
||||||
|
|
||||||
afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W);
|
afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W);
|
||||||
|
|
||||||
@ -888,7 +858,7 @@ exit_its:
|
|||||||
afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt;
|
afl->stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt;
|
||||||
afl->stage_cycles[STAGE_ITS] += afl->fsrv.total_execs - orig_execs;
|
afl->stage_cycles[STAGE_ITS] += afl->fsrv.total_execs - orig_execs;
|
||||||
|
|
||||||
memcpy(orig_buf, buf, len);
|
memcpy(buf, orig_buf, len);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -430,6 +430,13 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
/* OK, let's collect some stats about the performance of this test case.
|
/* OK, let's collect some stats about the performance of this test case.
|
||||||
This is used for fuzzing air time calculations in calculate_score(). */
|
This is used for fuzzing air time calculations in calculate_score(). */
|
||||||
|
|
||||||
|
if (unlikely(!afl->stage_max)) {
|
||||||
|
|
||||||
|
// Pretty sure this cannot happen, yet scan-build complains.
|
||||||
|
FATAL("BUG: stage_max should not be 0 here! Please report this condition.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
q->exec_us = (stop_us - start_us) / afl->stage_max;
|
q->exec_us = (stop_us - start_us) / afl->stage_max;
|
||||||
q->bitmap_size = count_bytes(afl, afl->fsrv.trace_bits);
|
q->bitmap_size = count_bytes(afl, afl->fsrv.trace_bits);
|
||||||
q->handicap = handicap;
|
q->handicap = handicap;
|
||||||
@ -682,7 +689,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
// same time. If so, the first temporary main node running again will demote
|
// same time. If so, the first temporary main node running again will demote
|
||||||
// themselves so this is not an issue
|
// themselves so this is not an issue
|
||||||
|
|
||||||
u8 path[PATH_MAX];
|
// u8 path2[PATH_MAX];
|
||||||
afl->is_main_node = 1;
|
afl->is_main_node = 1;
|
||||||
sprintf(path, "%s/is_main_node", afl->out_dir);
|
sprintf(path, "%s/is_main_node", afl->out_dir);
|
||||||
int fd = open(path, O_CREAT | O_RDWR, 0644);
|
int fd = open(path, O_CREAT | O_RDWR, 0644);
|
||||||
|
@ -418,6 +418,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
(u8 *)get_afl_env(afl_environment_variables[i]);
|
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
} else if (!strncmp(env, "AFL_KILL_SIGNAL",
|
||||||
|
|
||||||
|
afl_environment_variable_len)) {
|
||||||
|
|
||||||
|
afl->afl_env.afl_kill_signal =
|
||||||
|
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -524,8 +531,8 @@ void afl_states_stop(void) {
|
|||||||
|
|
||||||
LIST_FOREACH(&afl_states, afl_state_t, {
|
LIST_FOREACH(&afl_states, afl_state_t, {
|
||||||
|
|
||||||
if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, SIGKILL);
|
if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, el->fsrv.kill_signal);
|
||||||
if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, SIGKILL);
|
if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, el->fsrv.kill_signal);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -31,8 +31,7 @@
|
|||||||
|
|
||||||
void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
|
void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
|
||||||
|
|
||||||
char *val;
|
u8 fn[PATH_MAX];
|
||||||
u8 fn[PATH_MAX];
|
|
||||||
snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir);
|
snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir);
|
||||||
FILE *f = create_ffile(fn);
|
FILE *f = create_ffile(fn);
|
||||||
u32 i;
|
u32 i;
|
||||||
@ -44,6 +43,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
|
|||||||
|
|
||||||
for (i = 0; i < s_afl_env; ++i) {
|
for (i = 0; i < s_afl_env; ++i) {
|
||||||
|
|
||||||
|
char *val;
|
||||||
if ((val = getenv(afl_environment_variables[i])) != NULL) {
|
if ((val = getenv(afl_environment_variables[i])) != NULL) {
|
||||||
|
|
||||||
fprintf(f, "%s=%s\n", afl_environment_variables[i], val);
|
fprintf(f, "%s=%s\n", afl_environment_variables[i], val);
|
||||||
@ -228,7 +228,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
|
|
||||||
if (afl->virgin_bits[i] != 0xff) {
|
if (afl->virgin_bits[i] != 0xff) {
|
||||||
|
|
||||||
fprintf(f, " %d[%02x]", i, afl->virgin_bits[i]);
|
fprintf(f, " %u[%02x]", i, afl->virgin_bits[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
fprintf(f, "var_bytes :");
|
fprintf(f, "var_bytes :");
|
||||||
for (i = 0; i < afl->fsrv.map_size; i++) {
|
for (i = 0; i < afl->fsrv.map_size; i++) {
|
||||||
|
|
||||||
if (afl->var_bytes[i]) { fprintf(f, " %d", i); }
|
if (afl->var_bytes[i]) { fprintf(f, " %u", i); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1163,7 +1163,7 @@ void show_init_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ACTF("-t option specified. We'll use an exec timeout of %d ms.",
|
ACTF("-t option specified. We'll use an exec timeout of %u ms.",
|
||||||
afl->fsrv.exec_tmout);
|
afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -76,8 +76,17 @@ static void at_exit() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid1 > 0) { kill(pid1, SIGKILL); }
|
int kill_signal = SIGKILL;
|
||||||
if (pid2 > 0) { kill(pid2, SIGKILL); }
|
|
||||||
|
/* AFL_KILL_SIGNAL should already be a valid int at this point */
|
||||||
|
if (getenv("AFL_KILL_SIGNAL")) {
|
||||||
|
|
||||||
|
kill_signal = atoi(getenv("AFL_KILL_SIGNAL"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid1 > 0) { kill(pid1, kill_signal); }
|
||||||
|
if (pid2 > 0) { kill(pid2, kill_signal); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +108,8 @@ static void usage(u8 *argv0, int more_help) {
|
|||||||
" lin, quad> -- see docs/power_schedules.md\n"
|
" lin, quad> -- see docs/power_schedules.md\n"
|
||||||
" -f file - location read by the fuzzed program (default: stdin "
|
" -f file - location read by the fuzzed program (default: stdin "
|
||||||
"or @@)\n"
|
"or @@)\n"
|
||||||
" -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
|
" -t msec - timeout for each run (auto-scaled, 50-%u ms)\n"
|
||||||
" -m megs - memory limit for child process (%d MB, 0 = no limit)\n"
|
" -m megs - memory limit for child process (%u MB, 0 = no limit)\n"
|
||||||
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
||||||
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
|
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
|
||||||
" -W - use qemu-based instrumentation with Wine (Wine "
|
" -W - use qemu-based instrumentation with Wine (Wine "
|
||||||
@ -185,10 +194,11 @@ static void usage(u8 *argv0, int more_help) {
|
|||||||
"AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)\n"
|
"AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)\n"
|
||||||
"AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\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_FORCE_UI: force showing the status screen (for virtual consoles)\n"
|
||||||
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
|
|
||||||
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
|
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\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_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_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
|
||||||
|
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
|
||||||
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
||||||
" the target was compiled for\n"
|
" the target was compiled for\n"
|
||||||
"AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n"
|
"AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n"
|
||||||
@ -299,7 +309,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
s32 opt, i, auto_sync = 0 /*, user_set_cache = 0*/;
|
s32 opt, i, auto_sync = 0 /*, user_set_cache = 0*/;
|
||||||
u64 prev_queued = 0;
|
u64 prev_queued = 0;
|
||||||
u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, map_size = MAP_SIZE;
|
u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0,
|
||||||
|
map_size = get_map_size();
|
||||||
u8 *extras_dir[4];
|
u8 *extras_dir[4];
|
||||||
u8 mem_limit_given = 0, exit_1 = 0, debug = 0,
|
u8 mem_limit_given = 0, exit_1 = 0, debug = 0,
|
||||||
extras_dir_cnt = 0 /*, have_p = 0*/;
|
extras_dir_cnt = 0 /*, have_p = 0*/;
|
||||||
@ -326,7 +337,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; }
|
if (get_afl_env("AFL_DEBUG")) { debug = afl->debug = 1; }
|
||||||
|
|
||||||
map_size = get_map_size();
|
// map_size = get_map_size();
|
||||||
afl_state_init(afl, map_size);
|
afl_state_init(afl, map_size);
|
||||||
afl->debug = debug;
|
afl->debug = debug;
|
||||||
afl_fsrv_init(&afl->fsrv);
|
afl_fsrv_init(&afl->fsrv);
|
||||||
@ -976,6 +987,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
afl->fsrv.kill_signal =
|
||||||
|
parse_afl_kill_signal_env(afl->afl_env.afl_kill_signal, SIGKILL);
|
||||||
|
|
||||||
setup_signal_handlers();
|
setup_signal_handlers();
|
||||||
check_asan_opts(afl);
|
check_asan_opts(afl);
|
||||||
|
|
||||||
@ -1534,7 +1548,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (!afl->pending_not_fuzzed) {
|
if (!afl->pending_not_fuzzed) {
|
||||||
|
|
||||||
FATAL("We need at least on valid input seed that does not crash!");
|
FATAL("We need at least one valid input seed that does not crash!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ static void edit_params(int argc, char **argv) {
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
DEBUGF(
|
DEBUGF(
|
||||||
"passthrough=%s instrim=%d, gold_pos=%d, gold_present=%s "
|
"passthrough=%s instrim=%u, gold_pos=%u, gold_present=%s "
|
||||||
"inst_present=%s rt_present=%s rt_lto_present=%s\n",
|
"inst_present=%s rt_present=%s rt_lto_present=%s\n",
|
||||||
passthrough ? "true" : "false", instrim, gold_pos,
|
passthrough ? "true" : "false", instrim, gold_pos,
|
||||||
gold_present ? "true" : "false", inst_present ? "true" : "false",
|
gold_present ? "true" : "false", inst_present ? "true" : "false",
|
||||||
@ -252,11 +252,11 @@ static void edit_params(int argc, char **argv) {
|
|||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
s32 pid, i, status;
|
s32 pid, i, status;
|
||||||
u8 * ptr;
|
// u8 * ptr;
|
||||||
char thecwd[PATH_MAX];
|
char thecwd[PATH_MAX];
|
||||||
|
|
||||||
if ((ptr = getenv("AFL_LD_CALLER")) != NULL) {
|
if (getenv("AFL_LD_CALLER") != NULL) {
|
||||||
|
|
||||||
FATAL("ld loop detected! Set AFL_REAL_LD!\n");
|
FATAL("ld loop detected! Set AFL_REAL_LD!\n");
|
||||||
|
|
||||||
|
@ -662,7 +662,7 @@ static void usage(u8 *argv0) {
|
|||||||
|
|
||||||
"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 (%u MB)\n"
|
||||||
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
||||||
" -U - use Unicorn-based instrumentation (Unicorn mode)\n"
|
" -U - use Unicorn-based instrumentation (Unicorn mode)\n"
|
||||||
" -W - use qemu-based instrumentation with Wine (Wine mode)\n"
|
" -W - use qemu-based instrumentation with Wine (Wine mode)\n"
|
||||||
@ -693,12 +693,13 @@ static void usage(u8 *argv0) {
|
|||||||
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as "
|
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as "
|
||||||
"crash\n"
|
"crash\n"
|
||||||
"AFL_DEBUG: enable extra developer output\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_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during "
|
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during "
|
||||||
"startup (in milliseconds)\n"
|
"startup (in milliseconds)\n"
|
||||||
|
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, "
|
||||||
|
"etc. (default: SIGKILL)\n"
|
||||||
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the "
|
||||||
|
"size 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\n",
|
"AFL_QUIET: do not print extra informational output\n",
|
||||||
argv0, MEM_LIMIT, doc_path);
|
argv0, MEM_LIMIT, doc_path);
|
||||||
|
|
||||||
@ -1014,9 +1015,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
DIR * dir_in, *dir_out = NULL;
|
DIR * dir_in, *dir_out = NULL;
|
||||||
struct dirent *dir_ent;
|
struct dirent *dir_ent;
|
||||||
int done = 0;
|
// int done = 0;
|
||||||
u8 infile[PATH_MAX], outfile[PATH_MAX];
|
u8 infile[PATH_MAX], outfile[PATH_MAX];
|
||||||
u8 wait_for_gdb = 0;
|
u8 wait_for_gdb = 0;
|
||||||
#if !defined(DT_REG)
|
#if !defined(DT_REG)
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
#endif
|
#endif
|
||||||
@ -1090,11 +1091,11 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (get_afl_env("AFL_DEBUG")) {
|
if (get_afl_env("AFL_DEBUG")) {
|
||||||
|
|
||||||
int i = optind;
|
int j = optind;
|
||||||
DEBUGF("%s:", fsrv->target_path);
|
DEBUGF("%s:", fsrv->target_path);
|
||||||
while (argv[i] != NULL) {
|
while (argv[j] != NULL) {
|
||||||
|
|
||||||
SAYF(" \"%s\"", argv[i++]);
|
SAYF(" \"%s\"", argv[j++]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,6 +1116,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fsrv->kill_signal =
|
||||||
|
parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
|
||||||
|
|
||||||
if (getenv("AFL_CRASH_EXITCODE")) {
|
if (getenv("AFL_CRASH_EXITCODE")) {
|
||||||
|
|
||||||
long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10);
|
long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10);
|
||||||
@ -1143,7 +1147,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
|
||||||
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
shm_fuzz = deinit_shmem(fsrv, shm_fuzz);
|
||||||
|
|
||||||
while (done == 0 && (dir_ent = readdir(dir_in))) {
|
while ((dir_ent = readdir(dir_in))) {
|
||||||
|
|
||||||
if (dir_ent->d_name[0] == '.') {
|
if (dir_ent->d_name[0] == '.') {
|
||||||
|
|
||||||
|
@ -835,8 +835,8 @@ static void usage(u8 *argv0) {
|
|||||||
"Execution control settings:\n"
|
"Execution control settings:\n"
|
||||||
|
|
||||||
" -f file - input file read by the tested program (stdin)\n"
|
" -f file - input file read by the tested program (stdin)\n"
|
||||||
" -t msec - timeout for each run (%d ms)\n"
|
" -t msec - timeout for each run (%u ms)\n"
|
||||||
" -m megs - memory limit for child process (%d MB)\n"
|
" -m megs - memory limit for child process (%u MB)\n"
|
||||||
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
" -Q - use binary-only instrumentation (QEMU mode)\n"
|
||||||
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
|
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
|
||||||
" -W - use qemu-based instrumentation with Wine (Wine "
|
" -W - use qemu-based instrumentation with Wine (Wine "
|
||||||
@ -855,6 +855,7 @@ static void usage(u8 *argv0) {
|
|||||||
"Environment variables used:\n"
|
"Environment variables used:\n"
|
||||||
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n"
|
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n"
|
||||||
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
|
"AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n"
|
||||||
|
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
|
||||||
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
||||||
" the target was compiled for\n"
|
" the target was compiled for\n"
|
||||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||||
@ -1134,6 +1135,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fsrv->kill_signal =
|
||||||
|
parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
|
||||||
|
|
||||||
if (getenv("AFL_CRASH_EXITCODE")) {
|
if (getenv("AFL_CRASH_EXITCODE")) {
|
||||||
|
|
||||||
long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10);
|
long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10);
|
||||||
|
@ -106,7 +106,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
} else {
|
} else {
|
||||||
$ECHO "$GRAY[*] no bash available, cannot test afl-cmin.bash"
|
$ECHO "$GREY[*] no bash available, cannot test afl-cmin.bash"
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
../afl-tmin -m ${MEM_LIMIT} -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1
|
../afl-tmin -m ${MEM_LIMIT} -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1
|
||||||
@ -210,7 +210,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
|
|||||||
CNT=`ls in2/* 2>/dev/null | wc -l`
|
CNT=`ls in2/* 2>/dev/null | wc -l`
|
||||||
case "$CNT" in
|
case "$CNT" in
|
||||||
*2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
|
*2) $ECHO "$GREEN[+] afl-cmin correctly minimized the number of testcases" ;;
|
||||||
1) {
|
\ *1|1) { # allow leading whitecase for portability
|
||||||
test -s in2/* && $ECHO "$YELLOW[?] afl-cmin did minimize to one testcase. This can be a bug or due compiler optimization."
|
test -s in2/* && $ECHO "$YELLOW[?] afl-cmin did minimize to one testcase. This can be a bug or due compiler optimization."
|
||||||
test -s in2/* || {
|
test -s in2/* || {
|
||||||
$ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
|
$ECHO "$RED[!] afl-cmin did not correctly minimize the number of testcases ($CNT)"
|
||||||
@ -229,8 +229,8 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
|
|||||||
CNT=`ls in2/* 2>/dev/null | wc -l`
|
CNT=`ls in2/* 2>/dev/null | wc -l`
|
||||||
case "$CNT" in
|
case "$CNT" in
|
||||||
*2) $ECHO "$GREEN[+] afl-cmin.bash correctly minimized the number of testcases" ;;
|
*2) $ECHO "$GREEN[+] afl-cmin.bash correctly minimized the number of testcases" ;;
|
||||||
1) {
|
\ *1|1) { # allow leading whitecase for portability
|
||||||
test -s in2/* && $ECHO "$YELLOW[?] afl-cmin.bash did minimize to one testcase. This can be a bug or due compiler optimization."
|
test -s in2/* && $ECHO "$YELLOW[?] afl-cmin.bash did minimize to one testcase. This can be a bug or due compiler optimization."
|
||||||
test -s in2/* || {
|
test -s in2/* || {
|
||||||
$ECHO "$RED[!] afl-cmin.bash did not correctly minimize the number of testcases ($CNT)"
|
$ECHO "$RED[!] afl-cmin.bash did not correctly minimize the number of testcases ($CNT)"
|
||||||
CODE=1
|
CODE=1
|
||||||
@ -242,7 +242,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
} else {
|
} else {
|
||||||
$ECHO "$GRAY[*] no bash available, cannot test afl-cmin.bash"
|
$ECHO "$GREY[*] no bash available, cannot test afl-cmin.bash"
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
../afl-tmin -m ${MEM_LIMIT} -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1
|
../afl-tmin -m ${MEM_LIMIT} -i in/in2 -o in2/in2 -- ./test-instr.plain > /dev/null 2>&1
|
||||||
|
@ -44,7 +44,7 @@ echo "[*] Performing basic sanity checks..."
|
|||||||
|
|
||||||
PLT=`uname -s`
|
PLT=`uname -s`
|
||||||
|
|
||||||
if [ ! "$PLT" = "Linux" ] && [ ! "$PLT" = "Darwin" ] && [ ! "$PLT" = "FreeBSD" ] && [ ! "$PLT" = "NetBSD" ] && [ ! "$PLT" = "OpenBSD" ]; then
|
if [ ! "$PLT" = "Linux" ] && [ ! "$PLT" = "Darwin" ] && [ ! "$PLT" = "FreeBSD" ] && [ ! "$PLT" = "NetBSD" ] && [ ! "$PLT" = "OpenBSD" ] && [ ! "$PLT" = "DragonFly" ]; then
|
||||||
|
|
||||||
echo "[-] Error: Unicorn instrumentation is unsupported on $PLT."
|
echo "[-] Error: Unicorn instrumentation is unsupported on $PLT."
|
||||||
exit 1
|
exit 1
|
||||||
@ -89,6 +89,12 @@ if [ "$PLT" = "FreeBSD" ]; then
|
|||||||
TARCMD=gtar
|
TARCMD=gtar
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$PLT" = "DragonFly" ]; then
|
||||||
|
MAKECMD=gmake
|
||||||
|
CORES=`sysctl -n hw.ncpu`
|
||||||
|
TARCMD=tar
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$PLT" = "NetBSD" ] || [ "$PLT" = "OpenBSD" ]; then
|
if [ "$PLT" = "NetBSD" ] || [ "$PLT" = "OpenBSD" ]; then
|
||||||
MAKECMD=gmake
|
MAKECMD=gmake
|
||||||
CORES=`sysctl -n hw.ncpu`
|
CORES=`sysctl -n hw.ncpu`
|
||||||
@ -150,6 +156,7 @@ if [ $? -eq 0 ]; then
|
|||||||
echo "[*] initializing unicornafl submodule"
|
echo "[*] initializing unicornafl submodule"
|
||||||
git submodule init || exit 1
|
git submodule init || exit 1
|
||||||
git submodule update ./unicornafl 2>/dev/null # ignore errors
|
git submodule update ./unicornafl 2>/dev/null # ignore errors
|
||||||
|
git submodule sync ./unicornafl 2>/dev/null # ignore errors
|
||||||
else
|
else
|
||||||
echo "[*] cloning unicornafl"
|
echo "[*] cloning unicornafl"
|
||||||
test -d unicornafl || {
|
test -d unicornafl || {
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
//===- afl_driver.cpp - a glue between AFL and libFuzzer --------*- C++ -* ===//
|
//===- afl_driver.cpp - a glue between AFL++ and libFuzzer ------*- C++ -* ===//
|
||||||
//
|
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/* This file allows to fuzz libFuzzer-style target functions
|
/* This file allows to fuzz libFuzzer-style target functions
|
||||||
(LLVMFuzzerTestOneInput) with AFL using AFL's persistent (in-process) mode.
|
(LLVMFuzzerTestOneInput) with AFL++ using persistent in-memory fuzzing.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -25,25 +21,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|||||||
|
|
||||||
EOF
|
EOF
|
||||||
# Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang.
|
# Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang.
|
||||||
clang -g -fsanitize-coverage=trace-pc-guard test_fuzzer.cc -c
|
clang -c aflpp_driver.c
|
||||||
# Build afl-compiler-rt.o.c from the AFL distribution.
|
# Build afl-compiler-rt.o.c from the AFL distribution.
|
||||||
clang -c -w $AFL_HOME/instrumentation/afl-compiler-rt.o.c
|
clang -c $AFL_HOME/instrumentation/afl-compiler-rt.o.c
|
||||||
# Build this file, link it with afl-compiler-rt.o.o and the target code.
|
# Build this file, link it with afl-compiler-rt.o.o and the target code.
|
||||||
clang++ afl_driver.cpp test_fuzzer.o afl-compiler-rt.o.o
|
afl-clang-fast -o test_fuzzer test_fuzzer.cc afl-compiler-rt.o aflpp_driver.o
|
||||||
# Run AFL:
|
# Run AFL:
|
||||||
rm -rf IN OUT; mkdir IN OUT; echo z > IN/z;
|
rm -rf IN OUT; mkdir IN OUT; echo z > IN/z;
|
||||||
$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
|
$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
|
||||||
################################################################################
|
################################################################################
|
||||||
AFL_DRIVER_STDERR_DUPLICATE_FILENAME: Setting this *appends* stderr to the file
|
|
||||||
specified. If the file does not exist, it is created. This is useful for getting
|
|
||||||
stack traces (when using ASAN for example) or original error messages on hard
|
|
||||||
to reproduce bugs. Note that any content written to stderr will be written to
|
|
||||||
this file instead of stderr's usual location.
|
|
||||||
|
|
||||||
AFL_DRIVER_CLOSE_FD_MASK: Similar to libFuzzer's -close_fd_mask behavior option.
|
|
||||||
If 1, close stdout at startup. If 2 close stderr; if 3 close both.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -65,47 +53,6 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both.
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAP_FIXED_NOREPLACE
|
|
||||||
#define MAP_FIXED_NOREPLACE 0x100000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_DUMMY_SIZE 256000
|
|
||||||
|
|
||||||
// Platform detection. Copied from FuzzerInternal.h
|
|
||||||
#ifdef __linux__
|
|
||||||
#define LIBFUZZER_LINUX 1
|
|
||||||
#define LIBFUZZER_APPLE 0
|
|
||||||
#define LIBFUZZER_NETBSD 0
|
|
||||||
#define LIBFUZZER_FREEBSD 0
|
|
||||||
#define LIBFUZZER_OPENBSD 0
|
|
||||||
#elif __APPLE__
|
|
||||||
#define LIBFUZZER_LINUX 0
|
|
||||||
#define LIBFUZZER_APPLE 1
|
|
||||||
#define LIBFUZZER_NETBSD 0
|
|
||||||
#define LIBFUZZER_FREEBSD 0
|
|
||||||
#define LIBFUZZER_OPENBSD 0
|
|
||||||
#elif __NetBSD__
|
|
||||||
#define LIBFUZZER_LINUX 0
|
|
||||||
#define LIBFUZZER_APPLE 0
|
|
||||||
#define LIBFUZZER_NETBSD 1
|
|
||||||
#define LIBFUZZER_FREEBSD 0
|
|
||||||
#define LIBFUZZER_OPENBSD 0
|
|
||||||
#elif __FreeBSD__
|
|
||||||
#define LIBFUZZER_LINUX 0
|
|
||||||
#define LIBFUZZER_APPLE 0
|
|
||||||
#define LIBFUZZER_NETBSD 0
|
|
||||||
#define LIBFUZZER_FREEBSD 1
|
|
||||||
#define LIBFUZZER_OPENBSD 0
|
|
||||||
#elif __OpenBSD__
|
|
||||||
#define LIBFUZZER_LINUX 0
|
|
||||||
#define LIBFUZZER_APPLE 0
|
|
||||||
#define LIBFUZZER_NETBSD 0
|
|
||||||
#define LIBFUZZER_FREEBSD 0
|
|
||||||
#define LIBFUZZER_OPENBSD 1
|
|
||||||
#else
|
|
||||||
#error "Support for your platform has not been implemented"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int __afl_sharedmem_fuzzing = 1;
|
int __afl_sharedmem_fuzzing = 1;
|
||||||
extern unsigned int * __afl_fuzz_len;
|
extern unsigned int * __afl_fuzz_len;
|
||||||
extern unsigned char *__afl_fuzz_ptr;
|
extern unsigned char *__afl_fuzz_ptr;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#define __GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
all:
|
all:
|
||||||
afl-clang-fast -o persistent_demo persistent_demo.c
|
../../afl-clang-fast -o persistent_demo persistent_demo.c
|
||||||
afl-clang-fast -o persistent_demo_new persistent_demo_new.c
|
../../afl-clang-fast -o persistent_demo_new persistent_demo_new.c
|
||||||
AFL_DONT_OPTIMIZE=1 afl-clang-fast -o test-instr test-instr.c
|
AFL_DONT_OPTIMIZE=1 ../../afl-clang-fast -o test-instr test-instr.c
|
||||||
|
|
||||||
document:
|
document:
|
||||||
AFL_DONT_OPTIMIZE=1 afl-clang-fast -D_AFL_DOCUMENT_MUTATIONS -o test-instr test-instr.c
|
AFL_DONT_OPTIMIZE=1 ../../afl-clang-fast -D_AFL_DOCUMENT_MUTATIONS -o test-instr test-instr.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f persistent_demo persistent_demo_new test-instr
|
rm -f persistent_demo persistent_demo_new test-instr
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
int target_func(unsigned char *buf, int size) {
|
int target_func(unsigned char *buf, int size) {
|
||||||
|
|
||||||
printf("buffer:%p, size:%p\n", buf, size);
|
printf("buffer:%p, size:%d\n", buf, size);
|
||||||
switch (buf[0]) {
|
switch (buf[0]) {
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
Reference in New Issue
Block a user