mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-10 09:11:34 +00:00
commit
f0e08e6486
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -3,8 +3,8 @@ name: CI
|
||||
on:
|
||||
push:
|
||||
branches: [ stable, dev ]
|
||||
# pull_request:
|
||||
# branches: [ stable, dev ]
|
||||
pull_request:
|
||||
branches: [ stable, dev ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
4
.github/workflows/codeql-analysis.yml
vendored
4
.github/workflows/codeql-analysis.yml
vendored
@ -3,8 +3,8 @@ name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
branches: [ stable, dev ]
|
||||
# pull_request:
|
||||
# branches: [ stable, dev ]
|
||||
pull_request:
|
||||
branches: [ stable, dev ]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -65,7 +65,6 @@ qemu_mode/qemu-*
|
||||
qemu_mode/qemuafl
|
||||
unicorn_mode/samples/*/\.test-*
|
||||
unicorn_mode/samples/*/output/
|
||||
unicorn_mode/unicornafl
|
||||
test/unittests/unit_maybe_alloc
|
||||
test/unittests/unit_preallocable
|
||||
test/unittests/unit_list
|
||||
|
@ -558,6 +558,7 @@ clean:
|
||||
-$(MAKE) -f GNUmakefile.gcc_plugin clean
|
||||
$(MAKE) -C utils/libdislocator clean
|
||||
$(MAKE) -C utils/libtokencap clean
|
||||
$(MAKE) -C utils/aflpp_driver clean
|
||||
$(MAKE) -C utils/afl_network_proxy clean
|
||||
$(MAKE) -C utils/socket_fuzzing clean
|
||||
$(MAKE) -C utils/argv_fuzzing clean
|
||||
@ -576,7 +577,11 @@ endif
|
||||
deepclean: clean
|
||||
rm -rf unicorn_mode/unicornafl
|
||||
rm -rf qemu_mode/qemuafl
|
||||
ifeq "$(IN_REPO)" "1"
|
||||
# NEVER EVER ACTIVATE THAT!!!!! git reset --hard >/dev/null 2>&1 || true
|
||||
git checkout unicorn_mode/unicornafl
|
||||
git checkout qemu_mode/qemuafl
|
||||
endif
|
||||
|
||||
.PHONY: distrib
|
||||
distrib: all
|
||||
|
@ -507,6 +507,8 @@ install: all
|
||||
@echo .SH LICENSE >> ./$@
|
||||
@echo Apache License Version 2.0, January 2004 >> ./$@
|
||||
@ln -sf afl-cc.8 ./afl-c++.8
|
||||
@ln -sf afl-cc.8 ./afl-clang-fast.8
|
||||
@ln -sf afl-cc.8 ./afl-clang-fast++.8
|
||||
ifneq "$(AFL_CLANG_FLTO)" ""
|
||||
ifeq "$(LLVM_LTO)" "1"
|
||||
@ln -sf afl-cc.8 ./afl-clang-lto.8
|
||||
|
13
README.md
13
README.md
@ -2,9 +2,9 @@
|
||||
|
||||
<img align="right" src="https://raw.githubusercontent.com/andreafioraldi/AFLplusplus-website/master/static/logo_256x256.png" alt="AFL++ Logo">
|
||||
|
||||
Release Version: [3.11c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
||||
Release Version: [3.12c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
||||
|
||||
Github Version: 3.12a
|
||||
Github Version: 3.13a
|
||||
|
||||
Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
|
||||
|
||||
@ -175,7 +175,13 @@ If you want to build afl++ yourself you have many options.
|
||||
The easiest choice is to build and install everything:
|
||||
|
||||
```shell
|
||||
sudo apt install build-essential python3-dev automake flex bison libglib2.0-dev libpixman-1-dev python3-setuptools clang lld llvm llvm-dev libstdc++-dev
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential python3-dev automake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools
|
||||
# try to install llvm 11 and install the distro default if that fails
|
||||
sudo apt-get install -y lld-11 llvm-11 llvm-11-dev clang-11 || sudo apt-get install -y lld llvm llvm-dev clang
|
||||
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-dev
|
||||
git clone https://github.com/AFLplusplus/AFLplusplus && cd AFLplusplus
|
||||
cd AFLplusplus
|
||||
make distrib
|
||||
sudo make install
|
||||
```
|
||||
@ -1178,6 +1184,7 @@ without feedback, bug reports, or patches from:
|
||||
Josephine Calliotte Konrad Welc
|
||||
Thomas Rooijakkers David Carlier
|
||||
Ruben ten Hove Joey Jiao
|
||||
fuzzah
|
||||
```
|
||||
|
||||
Thank you!
|
||||
|
1
TODO.md
1
TODO.md
@ -2,6 +2,7 @@
|
||||
|
||||
## Roadmap 3.00+
|
||||
|
||||
- Update afl->pending_not_fuzzed for MOpt
|
||||
- CPU affinity for many cores? There seems to be an issue > 96 cores
|
||||
- afl-plot to support multiple plot_data
|
||||
- afl_custom_fuzz_splice_optin()
|
||||
|
@ -8,6 +8,29 @@
|
||||
Want to stay in the loop on major new features? Join our mailing list by
|
||||
sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
|
||||
### Version ++3.12c (release)
|
||||
- afl-fuzz:
|
||||
- added AFL_TARGET_ENV variable to pass extra env vars to the target
|
||||
(for things like LD_LIBRARY_PATH)
|
||||
- fix map detection, AFL_MAP_SIZE not needed anymore for most cases
|
||||
- fix counting favorites (just a display thing)
|
||||
- afl-cc:
|
||||
- fix cmplog rtn (rare crash and not being able to gather ptr data)
|
||||
- fix our own PCGUARD implementation to compile with llvm 10.0.1
|
||||
- link runtime not to shared libs
|
||||
- ensure shared libraries are properly built and instrumented
|
||||
- AFL_LLVM_INSTRUMENT_ALLOW/DENY were not implemented for LTO, added
|
||||
- show correct LLVM PCGUARD NATIVE mode when auto switching to it
|
||||
and keep fsanitize-coverage-*list=...
|
||||
Short mnemnonic NATIVE is now also accepted.
|
||||
- qemu_mode (thanks @realmadsci):
|
||||
- move AFL_PRELOAD and AFL_USE_QASAN logic inside afl-qemu-trace
|
||||
- add AFL_QEMU_CUSTOM_BIN
|
||||
- unicorn_mode
|
||||
- accidently removed the subfolder from github, re-added
|
||||
- added DEFAULT_PERMISSION to config.h for all files created, default
|
||||
to 0600
|
||||
|
||||
### Version ++3.11c (release)
|
||||
- afl-fuzz:
|
||||
- better auto detection of map size
|
||||
@ -38,7 +61,6 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
||||
- we no longer perform a "git drop"
|
||||
- afl-cmin: support filenames with spaces
|
||||
|
||||
|
||||
### Version ++3.10c (release)
|
||||
- Mac OS ARM64 support
|
||||
- Android support fixed and updated by Joey Jiaojg - thanks!
|
||||
|
@ -393,6 +393,10 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
|
||||
- In QEMU mode (-Q), `AFL_PATH` will be searched for afl-qemu-trace.
|
||||
|
||||
- In QEMU mode (-Q), setting `AFL_QEMU_CUSTOM_BIN` cause afl-fuzz to skip
|
||||
prepending `afl-qemu-trace` to your command line. Use this if you wish to use a
|
||||
custom afl-qemu-trace or if you need to modify the afl-qemu-trace arguments.
|
||||
|
||||
- Setting `AFL_CYCLE_SCHEDULES` will switch to a different schedule everytime
|
||||
a cycle is finished.
|
||||
|
||||
@ -404,6 +408,12 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
without disrupting the afl-fuzz process itself. This is useful, among other
|
||||
things, for bootstrapping libdislocator.so.
|
||||
|
||||
- Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables
|
||||
for the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz ... `
|
||||
This exists mostly for things like `LD_LIBRARY_PATH` but it would theoretically
|
||||
allow fuzzing of AFL++ itself (with 'target' AFL++ using some AFL_ vars that
|
||||
would disrupt work of 'fuzzer' AFL++).
|
||||
|
||||
- Setting `AFL_NO_UI` inhibits the UI altogether, and just periodically prints
|
||||
some basic stats. This behavior is also automatically triggered when the
|
||||
output from afl-fuzz is redirected to a file or to a pipe.
|
||||
@ -415,7 +425,8 @@ checks or alter some of the more exotic semantics of the tool:
|
||||
no valid terminal was detected (for virtual consoles)
|
||||
|
||||
- If you are Jakub, you may need `AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES`.
|
||||
Others need not apply.
|
||||
Others need not apply, unless they also want to disable the
|
||||
`/proc/sys/kernel/core_pattern` check.
|
||||
|
||||
- Benchmarking only: `AFL_BENCH_JUST_ONE` causes the fuzzer to exit after
|
||||
processing the first queue entry; and `AFL_BENCH_UNTIL_CRASH` causes it to
|
||||
|
@ -5,6 +5,43 @@
|
||||
"__afl_auto_init";
|
||||
"__afl_area_initial";
|
||||
"__afl_prev_loc";
|
||||
"__afl_prev_caller";
|
||||
"__afl_prev_ctx";
|
||||
"__afl_final_loc";
|
||||
"__afl_map_addr";
|
||||
"__afl_dictionary";
|
||||
"__afl_dictionary_len";
|
||||
"__afl_selective_coverage";
|
||||
"__afl_selective_coverage_start_off";
|
||||
"__afl_selective_coverage_temp";
|
||||
"__afl_coverage_discard";
|
||||
"__afl_coverage_skip";
|
||||
"__afl_coverage_on";
|
||||
"__afl_coverage_off";
|
||||
"__afl_coverage_interesting";
|
||||
"__afl_fuzz_len";
|
||||
"__afl_fuzz_ptr";
|
||||
"__sanitizer_cov_trace_pc_guard";
|
||||
"__sanitizer_cov_trace_pc_guard_init";
|
||||
"__cmplog_ins_hook1";
|
||||
"__cmplog_ins_hook2";
|
||||
"__cmplog_ins_hook4";
|
||||
"__cmplog_ins_hookN";
|
||||
"__cmplog_ins_hook16";
|
||||
"__sanitizer_cov_trace_cmp1";
|
||||
"__sanitizer_cov_trace_const_cmp1";
|
||||
"__sanitizer_cov_trace_cmp2";
|
||||
"__sanitizer_cov_trace_const_cmp2";
|
||||
"__sanitizer_cov_trace_cmp4";
|
||||
"__sanitizer_cov_trace_const_cmp4";
|
||||
"__sanitizer_cov_trace_cmp8";
|
||||
"__sanitizer_cov_trace_const_cmp8";
|
||||
"__sanitizer_cov_trace_cmp16";
|
||||
"__sanitizer_cov_trace_const_cmp16";
|
||||
"__sanitizer_cov_trace_switch";
|
||||
"__cmplog_rtn_hook";
|
||||
"__cmplog_rtn_gcc_stdstring_cstring";
|
||||
"__cmplog_rtn_gcc_stdstring_stdstring";
|
||||
"__cmplog_rtn_llvm_stdstring_cstring";
|
||||
"__cmplog_rtn_llvm_stdstring_stdstring";
|
||||
};
|
||||
|
@ -390,7 +390,7 @@ typedef struct afl_env_vars {
|
||||
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload,
|
||||
*afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
|
||||
*afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
|
||||
*afl_testcache_entries, *afl_kill_signal;
|
||||
*afl_testcache_entries, *afl_kill_signal, *afl_target_env;
|
||||
|
||||
} afl_env_vars_t;
|
||||
|
||||
|
@ -48,7 +48,10 @@ void argv_cpy_free(char **argv);
|
||||
char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
|
||||
char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
|
||||
char * get_afl_env(char *env);
|
||||
u8 * get_libqasan_path(u8 *own_loc);
|
||||
|
||||
/* Extract env vars from input string and set them using setenv()
|
||||
For use with AFL_TARGET_ENV, ... */
|
||||
bool extract_and_set_env(u8 *env_str);
|
||||
|
||||
extern u8 be_quiet;
|
||||
extern u8 *doc_path; /* path to documentation dir */
|
||||
@ -58,6 +61,10 @@ extern u8 *doc_path; /* path to documentation dir */
|
||||
|
||||
u8 *find_binary(u8 *fname);
|
||||
|
||||
/* find an afl binary */
|
||||
|
||||
u8 *find_afl_binary(u8 *own_loc, 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. */
|
||||
|
@ -26,7 +26,7 @@
|
||||
/* Version string: */
|
||||
|
||||
// c = release, a = volatile github dev, e = experimental branch
|
||||
#define VERSION "++3.11c"
|
||||
#define VERSION "++3.12c"
|
||||
|
||||
/******************************************************
|
||||
* *
|
||||
@ -34,6 +34,18 @@
|
||||
* *
|
||||
******************************************************/
|
||||
|
||||
/* Default shared memory map size. Most targets just need a coverage map
|
||||
between 20-250kb. Plus there is an auto-detection feature in afl-fuzz.
|
||||
However if a target has problematic constructors and init arrays then
|
||||
this can fail. Hence afl-fuzz deploys a larger default map. The largest
|
||||
map seen so far is the xlsx fuzzer for libreoffice which is 5MB.
|
||||
At runtime this value can be overriden via AFL_MAP_SIZE.
|
||||
Default: 8MB (defined in bytes) */
|
||||
#define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024)
|
||||
|
||||
/* Default file permission umode when creating files (default: 0600) */
|
||||
#define DEFAULT_PERMISSION 0600
|
||||
|
||||
/* CMPLOG/REDQUEEN TUNING
|
||||
*
|
||||
* Here you can modify tuning and solving options for CMPLOG.
|
||||
|
@ -42,6 +42,7 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_DEBUG_CHILD",
|
||||
"AFL_DEBUG_GDB",
|
||||
"AFL_DISABLE_TRIM",
|
||||
"AFL_DISABLE_LLVM_INSTRUMENTATION",
|
||||
"AFL_DONT_OPTIMIZE",
|
||||
"AFL_DRIVER_STDERR_DUPLICATE_FILENAME",
|
||||
"AFL_DUMB_FORKSRV",
|
||||
@ -50,6 +51,7 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_FAST_CAL",
|
||||
"AFL_FORCE_UI",
|
||||
"AFL_FUZZER_ARGS", // oss-fuzz
|
||||
"AFL_GDB",
|
||||
"AFL_GCC_ALLOWLIST",
|
||||
"AFL_GCC_DENYLIST",
|
||||
"AFL_GCC_BLOCKLIST",
|
||||
@ -129,7 +131,9 @@ static char *afl_environment_variables[] = {
|
||||
"AFL_PATH",
|
||||
"AFL_PERFORMANCE_FILE",
|
||||
"AFL_PRELOAD",
|
||||
"AFL_TARGET_ENV",
|
||||
"AFL_PYTHON_MODULE",
|
||||
"AFL_QEMU_CUSTOM_BIN",
|
||||
"AFL_QEMU_COMPCOV",
|
||||
"AFL_QEMU_COMPCOV_DEBUG",
|
||||
"AFL_QEMU_DEBUG_MAPS",
|
||||
|
@ -113,7 +113,7 @@ cmake \
|
||||
-DLLVM_LINK_LLVM_DYLIB="ON" \
|
||||
-DLLVM_TARGETS_TO_BUILD="host" \
|
||||
../llvm/
|
||||
cmake --build . --parallel
|
||||
cmake --build . -j4
|
||||
export PATH="$(pwd)/bin:$PATH"
|
||||
export LLVM_CONFIG="$(pwd)/bin/llvm-config"
|
||||
export LD_LIBRARY_PATH="$(llvm-config --libdir)${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
|
@ -507,6 +507,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
|
||||
Zero = ConstantInt::get(Int8Tyi, 0);
|
||||
One = ConstantInt::get(Int8Tyi, 1);
|
||||
|
||||
initInstrumentList();
|
||||
scanForDangerousFunctions(&M);
|
||||
Mo = &M;
|
||||
|
||||
@ -1229,7 +1230,7 @@ void ModuleSanitizerCoverage::instrumentFunction(
|
||||
|
||||
// afl++ START
|
||||
if (!F.size()) return;
|
||||
if (isIgnoreFunction(&F)) return;
|
||||
if (!isInInstrumentList(&F)) return;
|
||||
// afl++ END
|
||||
|
||||
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
|
||||
@ -1291,10 +1292,17 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
|
||||
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
|
||||
Constant::getNullValue(ArrayTy), "__sancov_gen_");
|
||||
|
||||
#if LLVM_VERSION_MAJOR > 12
|
||||
if (TargetTriple.supportsCOMDAT() &&
|
||||
(TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
|
||||
if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
|
||||
Array->setComdat(Comdat);
|
||||
#else
|
||||
if (TargetTriple.supportsCOMDAT() && !F.isInterposable())
|
||||
if (auto Comdat =
|
||||
GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
|
||||
Array->setComdat(Comdat);
|
||||
#endif
|
||||
Array->setSection(getSectionName(Section));
|
||||
Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
|
||||
GlobalsToAppendToUsed.push_back(Array);
|
||||
|
@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Analysis/EHPersonalities.h"
|
||||
@ -34,11 +35,11 @@
|
||||
#include "llvm/InitializePasses.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/SpecialCaseList.h"
|
||||
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#endif
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include "llvm/Transforms/Utils/ModuleUtils.h"
|
||||
@ -47,65 +48,6 @@
|
||||
#include "debug.h"
|
||||
#include "afl-llvm-common.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// This is the ModuleSanitizerCoverage pass used in the new pass manager. The
|
||||
/// pass instruments functions for coverage, adds initialization calls to the
|
||||
/// module for trace PC guards and 8bit counters if they are requested, and
|
||||
/// appends globals to llvm.compiler.used.
|
||||
class ModuleSanitizerCoveragePass
|
||||
: public PassInfoMixin<ModuleSanitizerCoveragePass> {
|
||||
|
||||
public:
|
||||
explicit ModuleSanitizerCoveragePass(
|
||||
SanitizerCoverageOptions Options = SanitizerCoverageOptions(),
|
||||
const std::vector<std::string> &AllowlistFiles =
|
||||
std::vector<std::string>(),
|
||||
const std::vector<std::string> &BlocklistFiles =
|
||||
std::vector<std::string>())
|
||||
: Options(Options) {
|
||||
|
||||
if (AllowlistFiles.size() > 0)
|
||||
Allowlist = SpecialCaseList::createOrDie(AllowlistFiles
|
||||
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
||||
,
|
||||
*vfs::getRealFileSystem()
|
||||
#endif
|
||||
);
|
||||
if (BlocklistFiles.size() > 0)
|
||||
Blocklist = SpecialCaseList::createOrDie(BlocklistFiles
|
||||
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
||||
,
|
||||
*vfs::getRealFileSystem()
|
||||
#endif
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
static bool isRequired() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
SanitizerCoverageOptions Options;
|
||||
|
||||
std::unique_ptr<SpecialCaseList> Allowlist;
|
||||
std::unique_ptr<SpecialCaseList> Blocklist;
|
||||
|
||||
};
|
||||
|
||||
// Insert SanitizerCoverage instrumentation.
|
||||
ModulePass *createModuleSanitizerCoverageLegacyPassPass(
|
||||
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(),
|
||||
const std::vector<std::string> &AllowlistFiles = std::vector<std::string>(),
|
||||
const std::vector<std::string> &BlocklistFiles =
|
||||
std::vector<std::string>());
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "sancov"
|
||||
@ -156,96 +98,8 @@ static const char *const SanCovLowestStackName = "__sancov_lowest_stack";
|
||||
|
||||
static char *skip_nozero;
|
||||
|
||||
/*
|
||||
static cl::opt<int> ClCoverageLevel(
|
||||
"sanitizer-coverage-level",
|
||||
cl::desc("Sanitizer Coverage. 0: none, 1: entry block, 2: all blocks, "
|
||||
"3: all blocks and critical edges"),
|
||||
cl::Hidden, cl::init(3));
|
||||
|
||||
static cl::opt<bool> ClTracePC("sanitizer-coverage-trace-pc",
|
||||
cl::desc("Experimental pc tracing"), cl::Hidden,
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> ClTracePCGuard("sanitizer-coverage-trace-pc-guard",
|
||||
cl::desc("pc tracing with a guard"),
|
||||
cl::Hidden, cl::init(true));
|
||||
|
||||
// If true, we create a global variable that contains PCs of all instrumented
|
||||
// BBs, put this global into a named section, and pass this section's bounds
|
||||
// to __sanitizer_cov_pcs_init.
|
||||
// This way the coverage instrumentation does not need to acquire the PCs
|
||||
// at run-time. Works with trace-pc-guard, inline-8bit-counters, and
|
||||
// inline-bool-flag.
|
||||
static cl::opt<bool> ClCreatePCTable("sanitizer-coverage-pc-table",
|
||||
cl::desc("create a static PC table"),
|
||||
cl::Hidden, cl::init(false));
|
||||
|
||||
static cl::opt<bool> ClInline8bitCounters(
|
||||
"sanitizer-coverage-inline-8bit-counters",
|
||||
cl::desc("increments 8-bit counter for every edge"), cl::Hidden,
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> ClInlineBoolFlag(
|
||||
"sanitizer-coverage-inline-bool-flag",
|
||||
cl::desc("sets a boolean flag for every edge"), cl::Hidden,
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> ClCMPTracing(
|
||||
"sanitizer-coverage-trace-compares",
|
||||
cl::desc("Tracing of CMP and similar instructions"), cl::Hidden,
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> ClDIVTracing("sanitizer-coverage-trace-divs",
|
||||
cl::desc("Tracing of DIV instructions"),
|
||||
cl::Hidden, cl::init(false));
|
||||
|
||||
static cl::opt<bool> ClGEPTracing("sanitizer-coverage-trace-geps",
|
||||
cl::desc("Tracing of GEP instructions"),
|
||||
cl::Hidden, cl::init(false));
|
||||
|
||||
static cl::opt<bool> ClPruneBlocks(
|
||||
"sanitizer-coverage-prune-blocks",
|
||||
cl::desc("Reduce the number of instrumented blocks"), cl::Hidden,
|
||||
cl::init(true));
|
||||
|
||||
static cl::opt<bool> ClStackDepth("sanitizer-coverage-stack-depth",
|
||||
cl::desc("max stack depth tracing"),
|
||||
cl::Hidden, cl::init(false));
|
||||
*/
|
||||
namespace {
|
||||
|
||||
/*
|
||||
SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
|
||||
|
||||
SanitizerCoverageOptions Res;
|
||||
switch (LegacyCoverageLevel) {
|
||||
|
||||
case 0:
|
||||
Res.CoverageType = SanitizerCoverageOptions::SCK_None;
|
||||
break;
|
||||
case 1:
|
||||
Res.CoverageType = SanitizerCoverageOptions::SCK_Function;
|
||||
break;
|
||||
case 2:
|
||||
Res.CoverageType = SanitizerCoverageOptions::SCK_BB;
|
||||
break;
|
||||
case 3:
|
||||
Res.CoverageType = SanitizerCoverageOptions::SCK_Edge;
|
||||
break;
|
||||
case 4:
|
||||
Res.CoverageType = SanitizerCoverageOptions::SCK_Edge;
|
||||
Res.IndirectCalls = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return Res;
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
|
||||
|
||||
// Sets CoverageType and IndirectCalls.
|
||||
@ -281,12 +135,14 @@ class ModuleSanitizerCoverage {
|
||||
|
||||
public:
|
||||
ModuleSanitizerCoverage(
|
||||
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(),
|
||||
const SpecialCaseList * Allowlist = nullptr,
|
||||
const SpecialCaseList * Blocklist = nullptr)
|
||||
: Options(OverrideFromCL(Options)),
|
||||
Allowlist(Allowlist),
|
||||
Blocklist(Blocklist) {
|
||||
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()
|
||||
#if LLVM_MAJOR > 10
|
||||
,
|
||||
const SpecialCaseList *Allowlist = nullptr,
|
||||
const SpecialCaseList *Blocklist = nullptr
|
||||
#endif
|
||||
)
|
||||
: Options(OverrideFromCL(Options)) {
|
||||
|
||||
}
|
||||
|
||||
@ -356,9 +212,6 @@ class ModuleSanitizerCoverage {
|
||||
|
||||
SanitizerCoverageOptions Options;
|
||||
|
||||
const SpecialCaseList *Allowlist;
|
||||
const SpecialCaseList *Blocklist;
|
||||
|
||||
uint32_t instr = 0;
|
||||
GlobalVariable *AFLMapPtr = NULL;
|
||||
ConstantInt * One = NULL;
|
||||
@ -370,27 +223,17 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
|
||||
|
||||
public:
|
||||
ModuleSanitizerCoverageLegacyPass(
|
||||
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(),
|
||||
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()
|
||||
#if LLVM_VERSION_MAJOR > 10
|
||||
,
|
||||
const std::vector<std::string> &AllowlistFiles =
|
||||
std::vector<std::string>(),
|
||||
const std::vector<std::string> &BlocklistFiles =
|
||||
std::vector<std::string>())
|
||||
std::vector<std::string>()
|
||||
#endif
|
||||
)
|
||||
: ModulePass(ID), Options(Options) {
|
||||
|
||||
if (AllowlistFiles.size() > 0)
|
||||
Allowlist = SpecialCaseList::createOrDie(AllowlistFiles
|
||||
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
||||
,
|
||||
*vfs::getRealFileSystem()
|
||||
#endif
|
||||
);
|
||||
if (BlocklistFiles.size() > 0)
|
||||
Blocklist = SpecialCaseList::createOrDie(BlocklistFiles
|
||||
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
||||
,
|
||||
*vfs::getRealFileSystem()
|
||||
#endif
|
||||
);
|
||||
initializeModuleSanitizerCoverageLegacyPassPass(
|
||||
*PassRegistry::getPassRegistry());
|
||||
|
||||
@ -398,8 +241,12 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
|
||||
ModuleSanitizerCoverage ModuleSancov(Options, Allowlist.get(),
|
||||
Blocklist.get());
|
||||
ModuleSanitizerCoverage ModuleSancov(Options
|
||||
#if LLVM_MAJOR > 10
|
||||
,
|
||||
Allowlist.get(), Blocklist.get()
|
||||
#endif
|
||||
);
|
||||
auto DTCallback = [this](Function &F) -> const DominatorTree * {
|
||||
|
||||
return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
|
||||
@ -444,8 +291,12 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
|
||||
PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M,
|
||||
ModuleAnalysisManager &MAM) {
|
||||
|
||||
ModuleSanitizerCoverage ModuleSancov(Options, Allowlist.get(),
|
||||
Blocklist.get());
|
||||
ModuleSanitizerCoverage ModuleSancov(Options
|
||||
#if LLVM_MAJOR > 10
|
||||
,
|
||||
Allowlist.get(), Blocklist.get()
|
||||
#endif
|
||||
);
|
||||
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
|
||||
auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
|
||||
|
||||
@ -564,12 +415,6 @@ bool ModuleSanitizerCoverage::instrumentModule(
|
||||
}
|
||||
|
||||
if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false;
|
||||
if (Allowlist &&
|
||||
!Allowlist->inSection("coverage", "src", M.getSourceFileName()))
|
||||
return false;
|
||||
if (Blocklist &&
|
||||
Blocklist->inSection("coverage", "src", M.getSourceFileName()))
|
||||
return false;
|
||||
C = &(M.getContext());
|
||||
DL = &M.getDataLayout();
|
||||
CurModule = &M;
|
||||
@ -842,9 +687,6 @@ void ModuleSanitizerCoverage::instrumentFunction(
|
||||
if (F.hasPersonalityFn() &&
|
||||
isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
|
||||
return;
|
||||
if (Allowlist && !Allowlist->inSection("coverage", "fun", F.getName()))
|
||||
return;
|
||||
if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName())) return;
|
||||
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
|
||||
SplitAllCriticalEdges(
|
||||
F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
|
||||
@ -915,10 +757,18 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection(
|
||||
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
|
||||
Constant::getNullValue(ArrayTy), "__sancov_gen_");
|
||||
|
||||
#if LLVM_VERSION_MAJOR > 12
|
||||
if (TargetTriple.supportsCOMDAT() &&
|
||||
(TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
|
||||
if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
|
||||
Array->setComdat(Comdat);
|
||||
#else
|
||||
if (TargetTriple.supportsCOMDAT() && !F.isInterposable())
|
||||
if (auto Comdat =
|
||||
GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
|
||||
Array->setComdat(Comdat);
|
||||
#endif
|
||||
|
||||
Array->setSection(getSectionName(Section));
|
||||
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
||||
Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
|
||||
@ -1354,12 +1204,20 @@ INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov",
|
||||
false)
|
||||
|
||||
ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass(
|
||||
const SanitizerCoverageOptions &Options,
|
||||
const SanitizerCoverageOptions &Options
|
||||
#if LLVM_MAJOR > 10
|
||||
,
|
||||
const std::vector<std::string> &AllowlistFiles,
|
||||
const std::vector<std::string> &BlocklistFiles) {
|
||||
const std::vector<std::string> &BlocklistFiles
|
||||
#endif
|
||||
) {
|
||||
|
||||
return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles,
|
||||
BlocklistFiles);
|
||||
return new ModuleSanitizerCoverageLegacyPass(Options
|
||||
#if LLVM_MAJOR > 10
|
||||
,
|
||||
AllowlistFiles, BlocklistFiles
|
||||
#endif
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ static void __afl_map_shm_fuzz() {
|
||||
int shm_fd = -1;
|
||||
|
||||
/* create the shared memory segment as if it was a file */
|
||||
shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
|
||||
shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
|
||||
if (shm_fd == -1) {
|
||||
|
||||
fprintf(stderr, "shm_open() failed for fuzz\n");
|
||||
@ -353,7 +353,7 @@ static void __afl_map_shm(void) {
|
||||
unsigned char *shm_base = NULL;
|
||||
|
||||
/* create the shared memory segment as if it was a file */
|
||||
shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
|
||||
shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
|
||||
if (shm_fd == -1) {
|
||||
|
||||
fprintf(stderr, "shm_open() failed\n");
|
||||
@ -528,7 +528,7 @@ static void __afl_map_shm(void) {
|
||||
struct cmp_map *shm_base = NULL;
|
||||
|
||||
/* create the shared memory segment as if it was a file */
|
||||
shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
|
||||
shm_fd = shm_open(shm_file_path, O_RDWR, DEFAULT_PERMISSION);
|
||||
if (shm_fd == -1) {
|
||||
|
||||
perror("shm_open() failed\n");
|
||||
@ -729,7 +729,7 @@ static void __afl_start_snapshots(void) {
|
||||
static uint32_t counter = 0;
|
||||
char fn[32];
|
||||
sprintf(fn, "%09u:forkserver", counter);
|
||||
s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
|
||||
if (fd_doc >= 0) {
|
||||
|
||||
if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) {
|
||||
@ -960,7 +960,7 @@ static void __afl_start_forkserver(void) {
|
||||
static uint32_t counter = 0;
|
||||
char fn[32];
|
||||
sprintf(fn, "%09u:forkserver", counter);
|
||||
s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
s32 fd_doc = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
|
||||
if (fd_doc >= 0) {
|
||||
|
||||
if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) {
|
||||
@ -1676,6 +1676,12 @@ void __sanitizer_cov_trace_cmp16(uint128_t arg1, uint128_t arg2) {
|
||||
|
||||
}
|
||||
|
||||
void __sanitizer_cov_trace_const_cmp16(uint128_t arg1, uint128_t arg2) {
|
||||
|
||||
__cmplog_ins_hook16(arg1, arg2, 0);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
|
||||
@ -1730,29 +1736,30 @@ __attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size) {
|
||||
// to avoid to call it on .text addresses
|
||||
static int area_is_valid(void *ptr, size_t len) {
|
||||
|
||||
if (unlikely(__asan_region_is_poisoned(ptr, len))) { return 0; }
|
||||
if (unlikely(!ptr || __asan_region_is_poisoned(ptr, len))) { return 0; }
|
||||
|
||||
long r = syscall(__afl_dummy_fd[1], SYS_write, ptr, len);
|
||||
long r = syscall(SYS_write, __afl_dummy_fd[1], ptr, len);
|
||||
|
||||
if (unlikely(r <= 0 || r > len)) { // fail - maybe hitting asan boundary?
|
||||
if (r <= 0 || r > len) return 0;
|
||||
|
||||
char *p = (char *)ptr;
|
||||
long page_size = sysconf(_SC_PAGE_SIZE);
|
||||
char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size;
|
||||
if (page < p + len) { return 0; } // no isnt, return fail
|
||||
len -= (p + len - page);
|
||||
r = syscall(__afl_dummy_fd[1], SYS_write, p, len);
|
||||
// even if the write succeed this can be a false positive if we cross
|
||||
// a page boundary. who knows why.
|
||||
|
||||
}
|
||||
char *p = (char *)ptr;
|
||||
long page_size = sysconf(_SC_PAGE_SIZE);
|
||||
char *page = (char *)((uintptr_t)p & ~(page_size - 1)) + page_size;
|
||||
|
||||
// partial writes - we return what was written.
|
||||
if (likely(r >= 0 && r <= len)) {
|
||||
if (page > p + len) {
|
||||
|
||||
// no, not crossing a page boundary
|
||||
return (int)r;
|
||||
|
||||
} else {
|
||||
|
||||
return 0;
|
||||
// yes it crosses a boundary, hence we can only return the length of
|
||||
// rest of the first page, we cannot detect if the next page is valid
|
||||
// or not, neither by SYS_write nor msync() :-(
|
||||
return (int)(page - p);
|
||||
|
||||
}
|
||||
|
||||
@ -1773,12 +1780,14 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
|
||||
*/
|
||||
|
||||
if (unlikely(!__afl_cmp_map)) return;
|
||||
// fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
|
||||
int l1, l2;
|
||||
if ((l1 = area_is_valid(ptr1, 32)) <= 0 ||
|
||||
(l2 = area_is_valid(ptr2, 32)) <= 0)
|
||||
return;
|
||||
int len = MIN(l1, l2);
|
||||
|
||||
// fprintf(stderr, "RTN2 %u\n", len);
|
||||
uintptr_t k = (uintptr_t)__builtin_return_address(0);
|
||||
k = (k >> 4) ^ (k << 8);
|
||||
k &= CMP_MAP_W - 1;
|
||||
@ -1809,6 +1818,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
|
||||
ptr1, len);
|
||||
__builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1,
|
||||
ptr2, len);
|
||||
// fprintf(stderr, "RTN3\n");
|
||||
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ bool isIgnoreFunction(const llvm::Function *F) {
|
||||
"asan.",
|
||||
"llvm.",
|
||||
"sancov.",
|
||||
"__ubsan_",
|
||||
"__ubsan",
|
||||
"ign.",
|
||||
"__afl",
|
||||
"_fini",
|
||||
@ -69,13 +69,16 @@ bool isIgnoreFunction(const llvm::Function *F) {
|
||||
"__msan",
|
||||
"__cmplog",
|
||||
"__sancov",
|
||||
"__san",
|
||||
"__cxx_",
|
||||
"__decide_deferred",
|
||||
"_GLOBAL",
|
||||
"_ZZN6__asan",
|
||||
"_ZZN6__lsan",
|
||||
"msan.",
|
||||
"LLVMFuzzerM",
|
||||
"LLVMFuzzerC",
|
||||
"LLVMFuzzerI",
|
||||
"__decide_deferred",
|
||||
"maybe_duplicate_stderr",
|
||||
"discard_output",
|
||||
"close_stdout",
|
||||
@ -91,6 +94,20 @@ bool isIgnoreFunction(const llvm::Function *F) {
|
||||
|
||||
}
|
||||
|
||||
static const char *ignoreSubstringList[] = {
|
||||
|
||||
"__asan", "__msan", "__ubsan", "__lsan",
|
||||
"__san", "__sanitize", "__cxx", "_GLOBAL__",
|
||||
"DebugCounter", "DwarfDebug", "DebugLoc"
|
||||
|
||||
};
|
||||
|
||||
for (auto const &ignoreListFunc : ignoreSubstringList) {
|
||||
|
||||
if (F->getName().contains(ignoreListFunc)) { return true; }
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
d1ca56b84e
|
||||
ddc4a9748d
|
||||
|
@ -51,6 +51,7 @@ ssize_t write(int fd, const void *buf, size_t count) {
|
||||
void *rtv = __builtin_return_address(0);
|
||||
|
||||
QASAN_DEBUG("%14p: write(%d, %p, %zu)\n", rtv, fd, buf, count);
|
||||
QASAN_LOAD(buf, count);
|
||||
ssize_t r = __lq_libc_write(fd, buf, count);
|
||||
QASAN_DEBUG("\t\t = %zd\n", r);
|
||||
|
||||
@ -63,6 +64,7 @@ ssize_t read(int fd, void *buf, size_t count) {
|
||||
void *rtv = __builtin_return_address(0);
|
||||
|
||||
QASAN_DEBUG("%14p: read(%d, %p, %zu)\n", rtv, fd, buf, count);
|
||||
QASAN_STORE(buf, count);
|
||||
ssize_t r = __lq_libc_read(fd, buf, count);
|
||||
QASAN_DEBUG("\t\t = %zd\n", r);
|
||||
|
||||
|
@ -159,6 +159,9 @@ size_t __libqasan_malloc_usable_size(void *ptr) {
|
||||
char *p = ptr;
|
||||
p -= sizeof(struct chunk_begin);
|
||||
|
||||
// Validate that the chunk marker is readable (a crude check
|
||||
// to verify that ptr is a valid malloc region before we dereference it)
|
||||
QASAN_LOAD(p, sizeof(struct chunk_begin) - REDZONE_SIZE);
|
||||
return ((struct chunk_begin *)p)->requested_size;
|
||||
|
||||
}
|
||||
@ -225,6 +228,9 @@ void __libqasan_free(void *ptr) {
|
||||
struct chunk_begin *p = ptr;
|
||||
p -= 1;
|
||||
|
||||
// Validate that the chunk marker is readable (a crude check
|
||||
// to verify that ptr is a valid malloc region before we dereference it)
|
||||
QASAN_LOAD(p, sizeof(struct chunk_begin) - REDZONE_SIZE);
|
||||
size_t n = p->requested_size;
|
||||
|
||||
QASAN_STORE(ptr, n);
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d1ca56b84e78f821406eef28d836918edfc8d610
|
||||
Subproject commit 0fb212daab492411b3e323bc18a3074c1aecfd37
|
@ -212,7 +212,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
|
||||
|
||||
unlink(path); /* Ignore errors */
|
||||
|
||||
ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
ret = open(path, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
|
||||
if (ret < 0) { PFATAL("Unable to create '%s'", path); }
|
||||
|
||||
@ -822,38 +822,7 @@ static void set_up_environment(void) {
|
||||
|
||||
if (qemu_mode) {
|
||||
|
||||
u8 *qemu_preload = getenv("QEMU_SET_ENV");
|
||||
u8 *afl_preload = getenv("AFL_PRELOAD");
|
||||
u8 *buf;
|
||||
|
||||
s32 i, afl_preload_size = strlen(afl_preload);
|
||||
for (i = 0; i < afl_preload_size; ++i) {
|
||||
|
||||
if (afl_preload[i] == ',') {
|
||||
|
||||
PFATAL(
|
||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||
"specified!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (qemu_preload) {
|
||||
|
||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
qemu_preload, afl_preload, afl_preload);
|
||||
|
||||
} else {
|
||||
|
||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
afl_preload, afl_preload);
|
||||
|
||||
}
|
||||
|
||||
setenv("QEMU_SET_ENV", buf, 1);
|
||||
|
||||
ck_free(buf);
|
||||
/* afl-qemu-trace takes care of converting AFL_PRELOAD. */
|
||||
|
||||
} else {
|
||||
|
||||
@ -1079,31 +1048,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (optind == argc || !in_file) { usage(argv[0]); }
|
||||
|
||||
if (qemu_mode && getenv("AFL_USE_QASAN")) {
|
||||
|
||||
u8 *preload = getenv("AFL_PRELOAD");
|
||||
u8 *libqasan = get_libqasan_path(argv_orig[0]);
|
||||
|
||||
if (!preload) {
|
||||
|
||||
setenv("AFL_PRELOAD", libqasan, 0);
|
||||
|
||||
} else {
|
||||
|
||||
u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2);
|
||||
strcpy(result, libqasan);
|
||||
strcat(result, " ");
|
||||
strcat(result, preload);
|
||||
|
||||
setenv("AFL_PRELOAD", result, 1);
|
||||
ck_free(result);
|
||||
|
||||
}
|
||||
|
||||
ck_free(libqasan);
|
||||
|
||||
}
|
||||
|
||||
map_size = get_map_size();
|
||||
|
||||
use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX");
|
||||
|
@ -280,7 +280,7 @@ static void add_instrumentation(void) {
|
||||
|
||||
}
|
||||
|
||||
outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, 0600);
|
||||
outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, DEFAULT_PERMISSION);
|
||||
|
||||
if (outfd < 0) { PFATAL("Unable to write to '%s'", modified_file); }
|
||||
|
||||
|
83
src/afl-cc.c
83
src/afl-cc.c
@ -590,6 +590,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
|
||||
#ifdef __ANDROID__
|
||||
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
||||
instrument_mode != INSTRUMENT_LLVMNATIVE;
|
||||
#else
|
||||
if (have_instr_list) {
|
||||
|
||||
@ -599,6 +600,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
"-fsanitize-coverage-allow/denylist, you can use "
|
||||
"AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n");
|
||||
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
||||
instrument_mode = INSTRUMENT_LLVMNATIVE;
|
||||
|
||||
} else {
|
||||
|
||||
@ -618,6 +620,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
"Using unoptimized trace-pc-guard, upgrade to llvm 10.0.1+ for "
|
||||
"enhanced version.\n");
|
||||
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
|
||||
instrument_mode = INSTRUMENT_LLVMNATIVE;
|
||||
#else
|
||||
FATAL("pcguard instrumentation requires llvm 4.0.1+");
|
||||
#endif
|
||||
@ -682,19 +685,49 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
|
||||
/* Detect stray -v calls from ./configure scripts. */
|
||||
|
||||
u8 skip_next = 0;
|
||||
while (--argc) {
|
||||
|
||||
u8 *cur = *(++argv);
|
||||
|
||||
if (skip_next) {
|
||||
|
||||
skip_next = 0;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (!strncmp(cur, "--afl", 5)) continue;
|
||||
if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
|
||||
if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
|
||||
if (!strncmp(cur, "-fno-unroll", 11)) continue;
|
||||
if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
|
||||
if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined"))
|
||||
if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
|
||||
!strcmp(cur, "--no-undefined")) {
|
||||
|
||||
continue;
|
||||
if (!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) ||
|
||||
!strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) {
|
||||
|
||||
}
|
||||
|
||||
if (!strcmp(cur, "-z")) {
|
||||
|
||||
u8 *param = *(argv + 1);
|
||||
if (!strcmp(param, "defs")) {
|
||||
|
||||
skip_next = 1;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) ||
|
||||
!strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) &&
|
||||
(strncmp(cur, "sanitize-coverage-allow",
|
||||
strlen("sanitize-coverage-allow")) &&
|
||||
strncmp(cur, "sanitize-coverage-deny",
|
||||
strlen("sanitize-coverage-deny")) &&
|
||||
instrument_mode != INSTRUMENT_LLVMNATIVE)) {
|
||||
|
||||
if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
|
||||
continue;
|
||||
@ -962,18 +995,24 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
switch (bit_mode) {
|
||||
|
||||
case 0:
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/afl-compiler-rt.o", obj_path);
|
||||
if (!shared_linking)
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/afl-compiler-rt.o", obj_path);
|
||||
if (lto_mode)
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/afl-llvm-rt-lto.o", obj_path);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
|
||||
if (access(cc_params[cc_par_cnt - 1], R_OK))
|
||||
FATAL("-m32 is not supported by your compiler");
|
||||
if (!shared_linking) {
|
||||
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
|
||||
if (access(cc_params[cc_par_cnt - 1], R_OK))
|
||||
FATAL("-m32 is not supported by your compiler");
|
||||
|
||||
}
|
||||
|
||||
if (lto_mode) {
|
||||
|
||||
cc_params[cc_par_cnt++] =
|
||||
@ -986,10 +1025,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
break;
|
||||
|
||||
case 64:
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
|
||||
if (access(cc_params[cc_par_cnt - 1], R_OK))
|
||||
FATAL("-m64 is not supported by your compiler");
|
||||
if (!shared_linking) {
|
||||
|
||||
cc_params[cc_par_cnt++] =
|
||||
alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
|
||||
if (access(cc_params[cc_par_cnt - 1], R_OK))
|
||||
FATAL("-m64 is not supported by your compiler");
|
||||
|
||||
}
|
||||
|
||||
if (lto_mode) {
|
||||
|
||||
cc_params[cc_par_cnt++] =
|
||||
@ -1009,12 +1053,12 @@ static void edit_params(u32 argc, char **argv, char **envp) {
|
||||
alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
|
||||
#endif
|
||||
|
||||
#if defined(USEMMAP) && !defined(__HAIKU__)
|
||||
cc_params[cc_par_cnt++] = "-lrt";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if defined(USEMMAP) && !defined(__HAIKU__)
|
||||
cc_params[cc_par_cnt++] = "-lrt";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
cc_params[cc_par_cnt] = NULL;
|
||||
@ -1220,6 +1264,7 @@ int main(int argc, char **argv, char **envp) {
|
||||
|
||||
} else if (strcasecmp(ptr, "LLVMNATIVE") == 0 ||
|
||||
|
||||
strcasecmp(ptr, "NATIVE") == 0 ||
|
||||
strcasecmp(ptr, "LLVM-NATIVE") == 0) {
|
||||
|
||||
compiler_mode = LLVM;
|
||||
@ -1632,8 +1677,8 @@ int main(int argc, char **argv, char **envp) {
|
||||
"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 " \
|
||||
#define NATIVE_MSG \
|
||||
" LLVM-NATIVE: use llvm's native PCGUARD instrumentation (less " \
|
||||
"performant)\n"
|
||||
#else
|
||||
#define NATIVE_MSG ""
|
||||
|
391
src/afl-common.c
391
src/afl-common.c
@ -149,9 +149,14 @@ void argv_cpy_free(char **argv) {
|
||||
|
||||
char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
||||
|
||||
if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); }
|
||||
if (unlikely(getenv("AFL_QEMU_CUSTOM_BIN"))) {
|
||||
|
||||
u8 *tmp, *cp = NULL, *rsl, *own_copy;
|
||||
WARNF(
|
||||
"AFL_QEMU_CUSTOM_BIN is enabled. "
|
||||
"You must run your target under afl-qemu-trace on your own!");
|
||||
return argv;
|
||||
|
||||
}
|
||||
|
||||
char **new_argv = ck_alloc(sizeof(char *) * (argc + 4));
|
||||
if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); }
|
||||
@ -164,70 +169,8 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
||||
|
||||
/* Now we need to actually find the QEMU binary to put in argv[0]. */
|
||||
|
||||
tmp = getenv("AFL_PATH");
|
||||
|
||||
if (tmp) {
|
||||
|
||||
cp = alloc_printf("%s/afl-qemu-trace", tmp);
|
||||
|
||||
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
|
||||
|
||||
*target_path_p = new_argv[0] = cp;
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
own_copy = ck_strdup(own_loc);
|
||||
rsl = strrchr(own_copy, '/');
|
||||
|
||||
if (rsl) {
|
||||
|
||||
*rsl = 0;
|
||||
|
||||
cp = alloc_printf("%s/afl-qemu-trace", own_copy);
|
||||
ck_free(own_copy);
|
||||
|
||||
if (!access(cp, X_OK)) {
|
||||
|
||||
*target_path_p = new_argv[0] = cp;
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(own_copy);
|
||||
|
||||
}
|
||||
|
||||
if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) {
|
||||
|
||||
if (cp) { ck_free(cp); }
|
||||
*target_path_p = new_argv[0] = ck_strdup(BIN_PATH "/afl-qemu-trace");
|
||||
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
SAYF("\n" cLRD "[-] " cRST
|
||||
"Oops, unable to find the 'afl-qemu-trace' binary. The binary must be "
|
||||
"built\n"
|
||||
" separately by following the instructions in "
|
||||
"qemu_mode/README.md. "
|
||||
"If you\n"
|
||||
" already have the binary installed, you may need to specify "
|
||||
"AFL_PATH in the\n"
|
||||
" environment.\n\n"
|
||||
|
||||
" Of course, even without QEMU, afl-fuzz can still work with "
|
||||
"binaries that are\n"
|
||||
" instrumented at compile time with afl-gcc. It is also possible to "
|
||||
"use it as a\n"
|
||||
" traditional non-instrumented fuzzer by specifying '-n' in the "
|
||||
"command "
|
||||
"line.\n");
|
||||
|
||||
FATAL("Failed to locate 'afl-qemu-trace'.");
|
||||
*target_path_p = new_argv[0] = find_afl_binary(own_loc, "afl-qemu-trace");
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
@ -235,10 +178,6 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
||||
|
||||
char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
||||
|
||||
if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); }
|
||||
|
||||
u8 *tmp, *cp = NULL, *rsl, *own_copy;
|
||||
|
||||
char **new_argv = ck_alloc(sizeof(char *) * (argc + 3));
|
||||
if (unlikely(!new_argv)) { FATAL("Illegal amount of arguments specified"); }
|
||||
|
||||
@ -249,152 +188,10 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
||||
|
||||
/* Now we need to actually find the QEMU binary to put in argv[0]. */
|
||||
|
||||
tmp = getenv("AFL_PATH");
|
||||
|
||||
if (tmp) {
|
||||
|
||||
cp = alloc_printf("%s/afl-qemu-trace", tmp);
|
||||
|
||||
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
|
||||
|
||||
ck_free(cp);
|
||||
|
||||
cp = alloc_printf("%s/afl-wine-trace", tmp);
|
||||
|
||||
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
|
||||
|
||||
*target_path_p = new_argv[0] = cp;
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
own_copy = ck_strdup(own_loc);
|
||||
rsl = strrchr(own_copy, '/');
|
||||
|
||||
if (rsl) {
|
||||
|
||||
*rsl = 0;
|
||||
|
||||
cp = alloc_printf("%s/afl-qemu-trace", own_copy);
|
||||
|
||||
if (cp && !access(cp, X_OK)) {
|
||||
|
||||
ck_free(cp);
|
||||
|
||||
cp = alloc_printf("%s/afl-wine-trace", own_copy);
|
||||
|
||||
if (!access(cp, X_OK)) {
|
||||
|
||||
*target_path_p = new_argv[0] = cp;
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ck_free(own_copy);
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(own_copy);
|
||||
|
||||
}
|
||||
|
||||
u8 *ncp = BIN_PATH "/afl-qemu-trace";
|
||||
|
||||
if (!access(ncp, X_OK)) {
|
||||
|
||||
ncp = BIN_PATH "/afl-wine-trace";
|
||||
|
||||
if (!access(ncp, X_OK)) {
|
||||
|
||||
*target_path_p = new_argv[0] = ck_strdup(ncp);
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SAYF("\n" cLRD "[-] " cRST
|
||||
"Oops, unable to find the '%s' binary. The binary must be "
|
||||
"built\n"
|
||||
" separately by following the instructions in "
|
||||
"qemu_mode/README.md. "
|
||||
"If you\n"
|
||||
" already have the binary installed, you may need to specify "
|
||||
"AFL_PATH in the\n"
|
||||
" environment.\n\n"
|
||||
|
||||
" Of course, even without QEMU, afl-fuzz can still work with "
|
||||
"binaries that are\n"
|
||||
" instrumented at compile time with afl-gcc. It is also possible to "
|
||||
"use it as a\n"
|
||||
" traditional non-instrumented fuzzer by specifying '-n' in the "
|
||||
"command "
|
||||
"line.\n",
|
||||
ncp);
|
||||
|
||||
FATAL("Failed to locate '%s'.", ncp);
|
||||
|
||||
}
|
||||
|
||||
/* Get libqasan path. */
|
||||
|
||||
u8 *get_libqasan_path(u8 *own_loc) {
|
||||
|
||||
if (!unlikely(own_loc)) { FATAL("BUG: param own_loc is NULL"); }
|
||||
|
||||
u8 *tmp, *cp = NULL, *rsl, *own_copy;
|
||||
|
||||
tmp = getenv("AFL_PATH");
|
||||
|
||||
if (tmp) {
|
||||
|
||||
cp = alloc_printf("%s/libqasan.so", tmp);
|
||||
|
||||
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
|
||||
|
||||
return cp;
|
||||
|
||||
}
|
||||
|
||||
own_copy = ck_strdup(own_loc);
|
||||
rsl = strrchr(own_copy, '/');
|
||||
|
||||
if (rsl) {
|
||||
|
||||
*rsl = 0;
|
||||
|
||||
cp = alloc_printf("%s/libqasan.so", own_copy);
|
||||
ck_free(own_copy);
|
||||
|
||||
if (!access(cp, X_OK)) { return cp; }
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(own_copy);
|
||||
|
||||
}
|
||||
|
||||
if (!access(AFL_PATH "/libqasan.so", X_OK)) {
|
||||
|
||||
if (cp) { ck_free(cp); }
|
||||
|
||||
return ck_strdup(AFL_PATH "/libqasan.so");
|
||||
|
||||
}
|
||||
|
||||
SAYF("\n" cLRD "[-] " cRST
|
||||
"Oops, unable to find the 'libqasan.so' binary. The binary must be "
|
||||
"built\n"
|
||||
" separately by following the instructions in "
|
||||
"qemu_mode/libqasan/README.md. "
|
||||
"If you\n"
|
||||
" already have the binary installed, you may need to specify "
|
||||
"AFL_PATH in the\n"
|
||||
" environment.\n");
|
||||
|
||||
FATAL("Failed to locate 'libqasan.so'.");
|
||||
u8 *tmp = find_afl_binary(own_loc, "afl-qemu-trace");
|
||||
ck_free(tmp);
|
||||
*target_path_p = new_argv[0] = find_afl_binary(own_loc, "afl-wine-trace");
|
||||
return new_argv;
|
||||
|
||||
}
|
||||
|
||||
@ -488,6 +285,70 @@ u8 *find_binary(u8 *fname) {
|
||||
|
||||
}
|
||||
|
||||
u8 *find_afl_binary(u8 *own_loc, u8 *fname) {
|
||||
|
||||
u8 *afl_path = NULL, *target_path, *own_copy;
|
||||
|
||||
if ((afl_path = getenv("AFL_PATH"))) {
|
||||
|
||||
target_path = alloc_printf("%s/%s", afl_path, fname);
|
||||
if (!access(target_path, X_OK)) {
|
||||
|
||||
return target_path;
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(target_path);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (own_loc) {
|
||||
|
||||
own_copy = ck_strdup(own_loc);
|
||||
u8 *rsl = strrchr(own_copy, '/');
|
||||
|
||||
if (rsl) {
|
||||
|
||||
*rsl = 0;
|
||||
|
||||
target_path = alloc_printf("%s/%s", own_copy, fname);
|
||||
ck_free(own_copy);
|
||||
|
||||
if (!access(target_path, X_OK)) {
|
||||
|
||||
return target_path;
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(target_path);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(own_copy);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
target_path = alloc_printf("%s/%s", BIN_PATH, fname);
|
||||
if (!access(target_path, X_OK)) {
|
||||
|
||||
return target_path;
|
||||
|
||||
} else {
|
||||
|
||||
ck_free(target_path);
|
||||
|
||||
}
|
||||
|
||||
return find_binary(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. */
|
||||
@ -757,6 +618,98 @@ char *get_afl_env(char *env) {
|
||||
|
||||
}
|
||||
|
||||
bool extract_and_set_env(u8 *env_str) {
|
||||
|
||||
if (!env_str) { return false; }
|
||||
|
||||
bool ret = false; // return false by default
|
||||
|
||||
u8 *p = ck_strdup(env_str);
|
||||
u8 *end = p + strlen((char *)p);
|
||||
u8 *rest = p;
|
||||
|
||||
u8 closing_sym = ' ';
|
||||
u8 c;
|
||||
|
||||
size_t num_pairs = 0;
|
||||
|
||||
while (rest < end) {
|
||||
|
||||
while (*rest == ' ') {
|
||||
|
||||
rest++;
|
||||
|
||||
}
|
||||
|
||||
if (rest + 1 >= end) break;
|
||||
|
||||
u8 *key = rest;
|
||||
// env variable names may not start with numbers or '='
|
||||
if (*key == '=' || (*key >= '0' && *key <= '9')) { goto free_and_return; }
|
||||
|
||||
while (rest < end && *rest != '=' && *rest != ' ') {
|
||||
|
||||
c = *rest;
|
||||
// lowercase is bad but we may still allow it
|
||||
if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
|
||||
(c < '0' || c > '9') && c != '_') {
|
||||
|
||||
goto free_and_return;
|
||||
|
||||
}
|
||||
|
||||
rest++;
|
||||
|
||||
}
|
||||
|
||||
if (*rest != '=') { goto free_and_return; }
|
||||
|
||||
*rest = '\0'; // done with variable name
|
||||
|
||||
rest += 1;
|
||||
if (rest >= end || *rest == ' ') { goto free_and_return; }
|
||||
|
||||
u8 *val = rest;
|
||||
if (*val == '\'' || *val == '"') {
|
||||
|
||||
closing_sym = *val;
|
||||
val += 1;
|
||||
rest += 1;
|
||||
if (rest >= end) { goto free_and_return; }
|
||||
|
||||
} else {
|
||||
|
||||
closing_sym = ' ';
|
||||
|
||||
}
|
||||
|
||||
while (rest < end && *rest != closing_sym) {
|
||||
|
||||
rest++;
|
||||
|
||||
}
|
||||
|
||||
if (closing_sym != ' ' && *rest != closing_sym) { goto free_and_return; }
|
||||
|
||||
*rest = '\0'; // done with variable value
|
||||
|
||||
rest += 1;
|
||||
if (rest < end && *rest != ' ') { goto free_and_return; }
|
||||
|
||||
num_pairs++;
|
||||
|
||||
setenv(key, val, 1);
|
||||
|
||||
}
|
||||
|
||||
if (num_pairs) { ret = true; }
|
||||
|
||||
free_and_return:
|
||||
ck_free(p);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/* Read mask bitmap from file. This is for the -B option. */
|
||||
|
||||
void read_bitmap(u8 *fname, u8 *map, size_t len) {
|
||||
@ -1123,7 +1076,7 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
|
||||
/* Reads the map size from ENV */
|
||||
u32 get_map_size(void) {
|
||||
|
||||
uint32_t map_size = 8000000; // a very large default map
|
||||
uint32_t map_size = DEFAULT_SHMEM_SIZE;
|
||||
char * ptr;
|
||||
|
||||
if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
|
||||
@ -1151,7 +1104,7 @@ FILE *create_ffile(u8 *fn) {
|
||||
s32 fd;
|
||||
FILE *f;
|
||||
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
|
||||
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||
|
||||
@ -1169,7 +1122,7 @@ s32 create_file(u8 *fn) {
|
||||
|
||||
s32 fd;
|
||||
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
|
||||
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||
|
||||
|
@ -809,7 +809,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
"have a\n"
|
||||
" restrictive memory limit configured, this is expected; please "
|
||||
"read\n"
|
||||
" %s/notes_for_asan.md for help.\n",
|
||||
" %s/notes_for_asan.md for help and run with '-m 0'.\n",
|
||||
doc_path);
|
||||
|
||||
} else if (!fsrv->mem_limit) {
|
||||
@ -817,18 +817,21 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
SAYF("\n" cLRD "[-] " cRST
|
||||
"Whoops, the target binary crashed suddenly, "
|
||||
"before receiving any input\n"
|
||||
" from the fuzzer! There are several probable explanations:\n\n"
|
||||
" from the fuzzer! You can try the following:\n\n"
|
||||
|
||||
" - The target binary requires a large map and crashes before "
|
||||
"reporting.\n"
|
||||
" Set a high value (e.g. AFL_MAP_SIZE=8000000) or use "
|
||||
"AFL_DEBUG=1 to see the\n"
|
||||
" message from the target binary\n\n"
|
||||
" - The target binary crashes because necessary runtime "
|
||||
"conditions it needs\n"
|
||||
" are not met. Try to:\n"
|
||||
" 1. Run again with AFL_DEBUG=1 set and check the output of "
|
||||
"the target\n"
|
||||
" binary for clues.\n"
|
||||
" 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
|
||||
"analyze the\n"
|
||||
" generated core dump.\n\n"
|
||||
|
||||
" - The binary is just buggy and explodes entirely on its own. "
|
||||
"If so, you\n"
|
||||
" need to fix the underlying problem or find a better "
|
||||
"replacement.\n\n"
|
||||
" - Possibly the target requires a huge coverage map and has "
|
||||
"CTORS.\n"
|
||||
" Retry with setting AFL_MAP_SIZE=10000000.\n\n"
|
||||
|
||||
MSG_FORK_ON_APPLE
|
||||
|
||||
@ -844,13 +847,17 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
SAYF("\n" cLRD "[-] " cRST
|
||||
"Whoops, the target binary crashed suddenly, "
|
||||
"before receiving any input\n"
|
||||
" from the fuzzer! There are several probable explanations:\n\n"
|
||||
" from the fuzzer! You can try the following:\n\n"
|
||||
|
||||
" - The target binary requires a large map and crashes before "
|
||||
"reporting.\n"
|
||||
" Set a high value (e.g. AFL_MAP_SIZE=8000000) or use "
|
||||
"AFL_DEBUG=1 to see the\n"
|
||||
" message from the target binary\n\n"
|
||||
" - The target binary crashes because necessary runtime "
|
||||
"conditions it needs\n"
|
||||
" are not met. Try to:\n"
|
||||
" 1. Run again with AFL_DEBUG=1 set and check the output of "
|
||||
"the target\n"
|
||||
" binary for clues.\n"
|
||||
" 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
|
||||
"analyze the\n"
|
||||
" generated core dump.\n\n"
|
||||
|
||||
" - The current memory limit (%s) is too restrictive, causing "
|
||||
"the\n"
|
||||
@ -868,13 +875,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
" estimate the required amount of virtual memory for the "
|
||||
"binary.\n\n"
|
||||
|
||||
" - The binary is just buggy and explodes entirely on its own. "
|
||||
"If so, you\n"
|
||||
" need to fix the underlying problem or find a better "
|
||||
"replacement.\n\n"
|
||||
|
||||
MSG_FORK_ON_APPLE
|
||||
|
||||
" - Possibly the target requires a huge coverage map and has "
|
||||
"CTORS.\n"
|
||||
" Retry with setting AFL_MAP_SIZE=10000000.\n\n"
|
||||
|
||||
" - Less likely, there is a horrible bug in the fuzzer. If other "
|
||||
"options\n"
|
||||
" fail, poke <afl-users@googlegroups.com> for troubleshooting "
|
||||
@ -903,7 +909,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
"with ASAN and\n"
|
||||
" you have a restrictive memory limit configured, this is "
|
||||
"expected; please\n"
|
||||
" read %s/notes_for_asan.md for help.\n",
|
||||
" read %s/notes_for_asan.md for help and run with '-m 0'.\n",
|
||||
doc_path);
|
||||
|
||||
} else if (!fsrv->mem_limit) {
|
||||
@ -911,10 +917,22 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
SAYF("\n" cLRD "[-] " cRST
|
||||
"Hmm, looks like the target binary terminated before we could complete"
|
||||
" a\n"
|
||||
"handshake with the injected code.\n"
|
||||
"Most likely the target has a huge coverage map, retry with setting"
|
||||
" the\n"
|
||||
"environment variable AFL_MAP_SIZE=8000000\n"
|
||||
"handshake with the injected code. You can try the following:\n\n"
|
||||
|
||||
" - The target binary crashes because necessary runtime conditions "
|
||||
"it needs\n"
|
||||
" are not met. Try to:\n"
|
||||
" 1. Run again with AFL_DEBUG=1 set and check the output of the "
|
||||
"target\n"
|
||||
" binary for clues.\n"
|
||||
" 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
|
||||
"analyze the\n"
|
||||
" generated core dump.\n\n"
|
||||
|
||||
" - Possibly the target requires a huge coverage map and has "
|
||||
"CTORS.\n"
|
||||
" Retry with setting AFL_MAP_SIZE=10000000.\n\n"
|
||||
|
||||
"Otherwise there is a horrible bug in the fuzzer.\n"
|
||||
"Poke <afl-users@googlegroups.com> for troubleshooting tips.\n");
|
||||
|
||||
@ -926,14 +944,23 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
"\n" cLRD "[-] " cRST
|
||||
"Hmm, looks like the target binary terminated "
|
||||
"before we could complete a\n"
|
||||
" handshake with the injected code. There are %s probable "
|
||||
"explanations:\n\n"
|
||||
" handshake with the injected code. You can try the following:\n\n"
|
||||
|
||||
"%s"
|
||||
|
||||
" - Most likely the target has a huge coverage map, retry with "
|
||||
"setting the\n"
|
||||
" environment variable AFL_MAP_SIZE=8000000\n\n"
|
||||
" - The target binary crashes because necessary runtime conditions "
|
||||
"it needs\n"
|
||||
" are not met. Try to:\n"
|
||||
" 1. Run again with AFL_DEBUG=1 set and check the output of the "
|
||||
"target\n"
|
||||
" binary for clues.\n"
|
||||
" 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and "
|
||||
"analyze the\n"
|
||||
" generated core dump.\n\n"
|
||||
|
||||
" - Possibly the target requires a huge coverage map and has "
|
||||
"CTORS.\n"
|
||||
" Retry with setting AFL_MAP_SIZE=10000000.\n\n"
|
||||
|
||||
" - The current memory limit (%s) is too restrictive, causing an "
|
||||
"OOM\n"
|
||||
@ -958,7 +985,6 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
||||
"options\n"
|
||||
" fail, poke <afl-users@googlegroups.com> for troubleshooting "
|
||||
"tips.\n",
|
||||
getenv(DEFER_ENV_VAR) ? "three" : "two",
|
||||
getenv(DEFER_ENV_VAR)
|
||||
? " - You are using deferred forkserver, but __AFL_INIT() is "
|
||||
"never\n"
|
||||
@ -1038,12 +1064,14 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
|
||||
|
||||
if (unlikely(fsrv->no_unlink)) {
|
||||
|
||||
fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
DEFAULT_PERMISSION);
|
||||
|
||||
} else {
|
||||
|
||||
unlink(fsrv->out_file); /* Ignore errors. */
|
||||
fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(fsrv->out_file, O_WRONLY | O_CREAT | O_EXCL,
|
||||
DEFAULT_PERMISSION);
|
||||
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ void write_bitmap(afl_state_t *afl) {
|
||||
afl->bitmap_changed = 0;
|
||||
|
||||
snprintf(fname, PATH_MAX, "%s/fuzz_bitmap", afl->out_dir);
|
||||
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
|
||||
|
||||
if (fd < 0) { PFATAL("Unable to open '%s'", fname); }
|
||||
|
||||
@ -407,7 +407,7 @@ static void write_crash_readme(afl_state_t *afl) {
|
||||
|
||||
sprintf(fn, "%s/crashes/README.txt", afl->out_dir);
|
||||
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
|
||||
/* Do not die on errors here - that would be impolite. */
|
||||
|
||||
@ -509,7 +509,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
||||
alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths);
|
||||
|
||||
#endif /* ^!SIMPLE_FILES */
|
||||
fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); }
|
||||
ck_write(fd, mem, len, queue_fn);
|
||||
close(fd);
|
||||
@ -783,7 +783,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
||||
/* If we're here, we apparently want to save the crash or hang
|
||||
test case, too. */
|
||||
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn); }
|
||||
ck_write(fd, mem, len, fn);
|
||||
close(fd);
|
||||
|
@ -731,7 +731,7 @@ void save_auto(afl_state_t *afl) {
|
||||
alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i);
|
||||
s32 fd;
|
||||
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
|
||||
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||
|
||||
|
@ -152,7 +152,8 @@ void bind_to_free_cpu(afl_state_t *afl) {
|
||||
|
||||
do {
|
||||
|
||||
if ((lockfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
|
||||
if ((lockfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL,
|
||||
DEFAULT_PERMISSION)) < 0) {
|
||||
|
||||
if (first) {
|
||||
|
||||
@ -1219,7 +1220,7 @@ static void link_or_copy(u8 *old_path, u8 *new_path) {
|
||||
sfd = open(old_path, O_RDONLY);
|
||||
if (sfd < 0) { PFATAL("Unable to open '%s'", old_path); }
|
||||
|
||||
dfd = open(new_path, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
dfd = open(new_path, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (dfd < 0) { PFATAL("Unable to create '%s'", new_path); }
|
||||
|
||||
tmp = ck_alloc(64 * 1024);
|
||||
@ -1812,9 +1813,13 @@ static void handle_existing_out_dir(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
fn = alloc_printf("%s/plot_data", afl->out_dir);
|
||||
if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; }
|
||||
ck_free(fn);
|
||||
if (!afl->in_place_resume) {
|
||||
|
||||
fn = alloc_printf("%s/plot_data", afl->out_dir);
|
||||
if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; }
|
||||
ck_free(fn);
|
||||
|
||||
}
|
||||
|
||||
fn = alloc_printf("%s/cmdline", afl->out_dir);
|
||||
if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; }
|
||||
@ -2008,17 +2013,35 @@ void setup_dirs_fds(afl_state_t *afl) {
|
||||
/* Gnuplot output file. */
|
||||
|
||||
tmp = alloc_printf("%s/plot_data", afl->out_dir);
|
||||
int fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
|
||||
ck_free(tmp);
|
||||
|
||||
afl->fsrv.plot_file = fdopen(fd, "w");
|
||||
if (!afl->fsrv.plot_file) { PFATAL("fdopen() failed"); }
|
||||
if (!afl->in_place_resume) {
|
||||
|
||||
int fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
|
||||
ck_free(tmp);
|
||||
|
||||
afl->fsrv.plot_file = fdopen(fd, "w");
|
||||
if (!afl->fsrv.plot_file) { PFATAL("fdopen() failed"); }
|
||||
|
||||
fprintf(
|
||||
afl->fsrv.plot_file,
|
||||
"# unix_time, cycles_done, cur_path, paths_total, "
|
||||
"pending_total, pending_favs, map_size, unique_crashes, "
|
||||
"unique_hangs, max_depth, execs_per_sec, total_execs, edges_found\n");
|
||||
|
||||
} else {
|
||||
|
||||
int fd = open(tmp, O_WRONLY | O_CREAT, DEFAULT_PERMISSION);
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
|
||||
ck_free(tmp);
|
||||
|
||||
afl->fsrv.plot_file = fdopen(fd, "w");
|
||||
if (!afl->fsrv.plot_file) { PFATAL("fdopen() failed"); }
|
||||
|
||||
fseek(afl->fsrv.plot_file, 0, SEEK_END);
|
||||
|
||||
}
|
||||
|
||||
fprintf(afl->fsrv.plot_file,
|
||||
"# unix_time, cycles_done, cur_path, paths_total, "
|
||||
"pending_total, pending_favs, map_size, unique_crashes, "
|
||||
"unique_hangs, max_depth, execs_per_sec, total_execs, edges_found\n");
|
||||
fflush(afl->fsrv.plot_file);
|
||||
|
||||
/* ignore errors */
|
||||
@ -2035,7 +2058,7 @@ void setup_cmdline_file(afl_state_t *afl, char **argv) {
|
||||
|
||||
/* Store the command line to reproduce our findings */
|
||||
tmp = alloc_printf("%s/cmdline", afl->out_dir);
|
||||
fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
|
||||
ck_free(tmp);
|
||||
|
||||
@ -2070,7 +2093,8 @@ void setup_stdio_file(afl_state_t *afl) {
|
||||
|
||||
unlink(afl->fsrv.out_file); /* Ignore errors */
|
||||
|
||||
afl->fsrv.out_fd = open(afl->fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
afl->fsrv.out_fd =
|
||||
open(afl->fsrv.out_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
|
||||
if (afl->fsrv.out_fd < 0) {
|
||||
|
||||
@ -2592,6 +2616,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
|
||||
}
|
||||
|
||||
if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode ||
|
||||
(afl->fsrv.qemu_mode && getenv("AFL_QEMU_CUSTOM_BIN")) ||
|
||||
afl->non_instrumented_mode) {
|
||||
|
||||
return;
|
||||
|
@ -465,7 +465,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
||||
|
||||
unlink(q->fname); /* ignore errors */
|
||||
|
||||
fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
|
||||
|
||||
|
@ -5119,14 +5119,23 @@ pacemaker_fuzzing:
|
||||
|
||||
/* Update afl->pending_not_fuzzed count if we made it through the
|
||||
calibration cycle and have not seen this entry before. */
|
||||
/*
|
||||
// TODO FIXME: I think we need this plus need an -L -1 check
|
||||
if (!afl->stop_soon && !afl->queue_cur->cal_failed &&
|
||||
(afl->queue_cur->was_fuzzed == 0 || afl->queue_cur->fuzz_level == 0)
|
||||
&& !afl->queue_cur->disabled) {
|
||||
|
||||
// if (!afl->stop_soon && !afl->queue_cur->cal_failed &&
|
||||
// !afl->queue_cur->was_fuzzed) {
|
||||
if (!afl->queue_cur->was_fuzzed) {
|
||||
|
||||
// afl->queue_cur->was_fuzzed = 1;
|
||||
// --afl->pending_not_fuzzed;
|
||||
// if (afl->queue_cur->favored) --afl->pending_favored;
|
||||
// }
|
||||
--afl->pending_not_fuzzed;
|
||||
afl->queue_cur->was_fuzzed = 1;
|
||||
if (afl->queue_cur->favored) { --afl->pending_favored; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
orig_in = NULL;
|
||||
|
||||
|
@ -249,7 +249,7 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
|
||||
snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir,
|
||||
strrchr(q->fname, '/') + 1);
|
||||
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||
close(fd);
|
||||
|
||||
@ -272,7 +272,7 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
if (symlink(ldest, fn)) {
|
||||
|
||||
s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||
close(fd);
|
||||
|
||||
@ -300,7 +300,7 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
|
||||
|
||||
s32 fd;
|
||||
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||
close(fd);
|
||||
|
||||
@ -680,13 +680,17 @@ void cull_queue(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
afl->top_rated[i]->favored = 1;
|
||||
++afl->queued_favored;
|
||||
if (!afl->top_rated[i]->favored) {
|
||||
|
||||
if (afl->top_rated[i]->fuzz_level == 0 ||
|
||||
!afl->top_rated[i]->was_fuzzed) {
|
||||
afl->top_rated[i]->favored = 1;
|
||||
++afl->queued_favored;
|
||||
|
||||
++afl->pending_favored;
|
||||
if (afl->top_rated[i]->fuzz_level == 0 ||
|
||||
!afl->top_rated[i]->was_fuzzed) {
|
||||
|
||||
++afl->pending_favored;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,8 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
|
||||
afl->document_counter++,
|
||||
describe_op(afl, 0, NAME_MAX - strlen("000000000:")));
|
||||
|
||||
if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) {
|
||||
if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION)) >=
|
||||
0) {
|
||||
|
||||
if (write(doc_fd, mem, len) != len)
|
||||
PFATAL("write to mutation file failed: %s", fn);
|
||||
@ -247,12 +248,14 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at,
|
||||
|
||||
if (unlikely(afl->no_unlink)) {
|
||||
|
||||
fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
DEFAULT_PERMISSION);
|
||||
|
||||
} else {
|
||||
|
||||
unlink(afl->fsrv.out_file); /* Ignore errors. */
|
||||
fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(afl->fsrv.out_file, O_WRONLY | O_CREAT | O_EXCL,
|
||||
DEFAULT_PERMISSION);
|
||||
|
||||
}
|
||||
|
||||
@ -564,7 +567,8 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
/* document the attempt to sync to this instance */
|
||||
|
||||
sprintf(qd_synced_path, "%s/.synced/%s.last", afl->out_dir, sd_ent->d_name);
|
||||
id_fd = open(qd_synced_path, O_RDWR | O_CREAT | O_TRUNC, 0600);
|
||||
id_fd =
|
||||
open(qd_synced_path, O_RDWR | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
|
||||
if (id_fd >= 0) close(id_fd);
|
||||
|
||||
/* Skip anything that doesn't have a queue/ subdirectory. */
|
||||
@ -587,7 +591,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
sprintf(qd_synced_path, "%s/.synced/%s", afl->out_dir, sd_ent->d_name);
|
||||
|
||||
id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600);
|
||||
id_fd = open(qd_synced_path, O_RDWR | O_CREAT, DEFAULT_PERMISSION);
|
||||
|
||||
if (id_fd < 0) { PFATAL("Unable to create '%s'", qd_synced_path); }
|
||||
|
||||
@ -851,7 +855,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
||||
|
||||
if (unlikely(afl->no_unlink)) {
|
||||
|
||||
fd = open(q->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
fd = open(q->fname, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION);
|
||||
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
|
||||
|
||||
@ -866,7 +870,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
||||
} else {
|
||||
|
||||
unlink(q->fname); /* ignore errors */
|
||||
fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
|
||||
|
||||
|
@ -433,6 +433,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
||||
afl->afl_env.afl_kill_signal =
|
||||
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||
|
||||
} else if (!strncmp(env, "AFL_TARGET_ENV",
|
||||
|
||||
afl_environment_variable_len)) {
|
||||
|
||||
afl->afl_env.afl_target_env =
|
||||
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -391,10 +391,11 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
|
||||
fprintf(afl->fsrv.plot_file,
|
||||
"%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, "
|
||||
"%u\n",
|
||||
get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry,
|
||||
afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored,
|
||||
bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth,
|
||||
eps, afl->plot_prev_ed, t_bytes); /* ignore errors */
|
||||
(afl->prev_run_time + get_cur_time() - afl->start_time),
|
||||
afl->queue_cycle - 1, afl->current_entry, afl->queued_paths,
|
||||
afl->pending_not_fuzzed, afl->pending_favored, bitmap_cvg,
|
||||
afl->unique_crashes, afl->unique_hangs, afl->max_depth, eps,
|
||||
afl->plot_prev_ed, t_bytes); /* ignore errors */
|
||||
|
||||
fflush(afl->fsrv.plot_file);
|
||||
|
||||
|
@ -223,6 +223,7 @@ static void usage(u8 *argv0, int more_help) {
|
||||
"AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
|
||||
"AFL_QUIET: suppress forkserver status messages\n"
|
||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||
"AFL_TARGET_ENV: pass extra environment variables to target\n"
|
||||
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
|
||||
"AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable\n"
|
||||
"AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
|
||||
@ -1022,32 +1023,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (afl->fsrv.qemu_mode && getenv("AFL_USE_QASAN")) {
|
||||
|
||||
u8 *preload = getenv("AFL_PRELOAD");
|
||||
u8 *libqasan = get_libqasan_path(argv_orig[0]);
|
||||
|
||||
if (!preload) {
|
||||
|
||||
setenv("AFL_PRELOAD", libqasan, 0);
|
||||
|
||||
} else {
|
||||
|
||||
u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2);
|
||||
strcpy(result, libqasan);
|
||||
strcat(result, " ");
|
||||
strcat(result, preload);
|
||||
|
||||
setenv("AFL_PRELOAD", result, 1);
|
||||
ck_free(result);
|
||||
|
||||
}
|
||||
|
||||
afl->afl_env.afl_preload = (u8 *)getenv("AFL_PRELOAD");
|
||||
ck_free(libqasan);
|
||||
|
||||
}
|
||||
|
||||
if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
|
||||
|
||||
OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
|
||||
@ -1312,38 +1287,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (afl->fsrv.qemu_mode) {
|
||||
|
||||
u8 *qemu_preload = getenv("QEMU_SET_ENV");
|
||||
u8 *afl_preload = getenv("AFL_PRELOAD");
|
||||
u8 *buf;
|
||||
|
||||
s32 j, afl_preload_size = strlen(afl_preload);
|
||||
for (j = 0; j < afl_preload_size; ++j) {
|
||||
|
||||
if (afl_preload[j] == ',') {
|
||||
|
||||
PFATAL(
|
||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||
"specified!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (qemu_preload) {
|
||||
|
||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
qemu_preload, afl_preload, afl_preload);
|
||||
|
||||
} else {
|
||||
|
||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
afl_preload, afl_preload);
|
||||
|
||||
}
|
||||
|
||||
setenv("QEMU_SET_ENV", buf, 1);
|
||||
|
||||
ck_free(buf);
|
||||
/* afl-qemu-trace takes care of converting AFL_PRELOAD. */
|
||||
|
||||
} else {
|
||||
|
||||
@ -1360,6 +1304,13 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (afl->afl_env.afl_target_env &&
|
||||
!extract_and_set_env(afl->afl_env.afl_target_env)) {
|
||||
|
||||
FATAL("Bad value of AFL_TARGET_ENV");
|
||||
|
||||
}
|
||||
|
||||
save_cmdline(afl, argc, argv);
|
||||
|
||||
fix_up_banner(afl, argv[optind]);
|
||||
@ -1584,21 +1535,21 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
if (!afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
|
||||
!afl->unicorn_mode) {
|
||||
|
||||
if (map_size <= 8000000 && !afl->non_instrumented_mode &&
|
||||
if (map_size <= DEFAULT_SHMEM_SIZE && !afl->non_instrumented_mode &&
|
||||
!afl->fsrv.qemu_mode && !afl->unicorn_mode) {
|
||||
|
||||
afl->fsrv.map_size = 8000000; // dummy temporary value
|
||||
setenv("AFL_MAP_SIZE", "8000000", 1);
|
||||
afl->fsrv.map_size = DEFAULT_SHMEM_SIZE; // dummy temporary value
|
||||
char vbuf[16];
|
||||
snprintf(vbuf, sizeof(vbuf), "%u", DEFAULT_SHMEM_SIZE);
|
||||
setenv("AFL_MAP_SIZE", vbuf, 1);
|
||||
|
||||
}
|
||||
|
||||
u32 new_map_size = afl_fsrv_get_mapsize(
|
||||
&afl->fsrv, afl->argv, &afl->stop_soon, afl->afl_env.afl_debug_child);
|
||||
|
||||
// only reinitialize when it makes sense
|
||||
if ((map_size < new_map_size ||
|
||||
(new_map_size != MAP_SIZE && new_map_size < map_size &&
|
||||
map_size - new_map_size > MAP_SIZE))) {
|
||||
// only reinitialize if the map needs to be larger than what we have.
|
||||
if (map_size < new_map_size) {
|
||||
|
||||
OKF("Re-initializing maps to %u bytes", new_map_size);
|
||||
|
||||
@ -1627,8 +1578,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
afl->fsrv.map_size = map_size;
|
||||
|
||||
}
|
||||
|
||||
if (afl->cmplog_binary) {
|
||||
@ -1641,11 +1590,15 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
afl->cmplog_fsrv.cmplog_binary = afl->cmplog_binary;
|
||||
afl->cmplog_fsrv.init_child_func = cmplog_exec_child;
|
||||
|
||||
if (map_size <= 8000000 && !afl->non_instrumented_mode &&
|
||||
!afl->fsrv.qemu_mode && !afl->unicorn_mode) {
|
||||
if ((map_size <= DEFAULT_SHMEM_SIZE ||
|
||||
afl->cmplog_fsrv.map_size < map_size) &&
|
||||
!afl->non_instrumented_mode && !afl->fsrv.qemu_mode &&
|
||||
!afl->unicorn_mode) {
|
||||
|
||||
afl->cmplog_fsrv.map_size = 8000000; // dummy temporary value
|
||||
setenv("AFL_MAP_SIZE", "8000000", 1);
|
||||
afl->cmplog_fsrv.map_size = MAX(map_size, (u32)DEFAULT_SHMEM_SIZE);
|
||||
char vbuf[16];
|
||||
snprintf(vbuf, sizeof(vbuf), "%u", afl->cmplog_fsrv.map_size);
|
||||
setenv("AFL_MAP_SIZE", vbuf, 1);
|
||||
|
||||
}
|
||||
|
||||
@ -1686,10 +1639,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
afl_fsrv_start(&afl->cmplog_fsrv, afl->argv, &afl->stop_soon,
|
||||
afl->afl_env.afl_debug_child);
|
||||
|
||||
} else {
|
||||
|
||||
afl->cmplog_fsrv.map_size = new_map_size;
|
||||
|
||||
}
|
||||
|
||||
OKF("Cmplog forkserver successfully started");
|
||||
|
@ -162,8 +162,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
snprintf(shm->g_shm_file_path, L_tmpnam, "/afl_%d_%ld", getpid(), random());
|
||||
|
||||
/* create the shared memory segment as if it was a file */
|
||||
shm->g_shm_fd =
|
||||
shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
|
||||
shm->g_shm_fd = shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL,
|
||||
DEFAULT_PERMISSION);
|
||||
if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); }
|
||||
|
||||
/* configure the size of the shared memory segment */
|
||||
@ -202,7 +202,8 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
|
||||
/* create the shared memory segment as if it was a file */
|
||||
shm->cmplog_g_shm_fd =
|
||||
shm_open(shm->cmplog_g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
|
||||
shm_open(shm->cmplog_g_shm_file_path, O_CREAT | O_RDWR | O_EXCL,
|
||||
DEFAULT_PERMISSION);
|
||||
if (shm->cmplog_g_shm_fd == -1) { PFATAL("shm_open() failed"); }
|
||||
|
||||
/* configure the size of the shared memory segment */
|
||||
@ -241,13 +242,14 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
||||
#else
|
||||
u8 *shm_str;
|
||||
|
||||
shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600);
|
||||
shm->shm_id =
|
||||
shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | DEFAULT_PERMISSION);
|
||||
if (shm->shm_id < 0) { PFATAL("shmget() failed"); }
|
||||
|
||||
if (shm->cmplog_mode) {
|
||||
|
||||
shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
|
||||
IPC_CREAT | IPC_EXCL | 0600);
|
||||
IPC_CREAT | IPC_EXCL | DEFAULT_PERMISSION);
|
||||
|
||||
if (shm->cmplog_shm_id < 0) {
|
||||
|
||||
|
@ -252,7 +252,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
|
||||
} else {
|
||||
|
||||
unlink(outfile); /* Ignore errors */
|
||||
fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||
fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (fd < 0) { PFATAL("Unable to create '%s'", outfile); }
|
||||
|
||||
}
|
||||
@ -599,38 +599,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
||||
|
||||
if (fsrv->qemu_mode) {
|
||||
|
||||
u8 *qemu_preload = getenv("QEMU_SET_ENV");
|
||||
u8 *afl_preload = getenv("AFL_PRELOAD");
|
||||
u8 *buf;
|
||||
|
||||
s32 i, afl_preload_size = strlen(afl_preload);
|
||||
for (i = 0; i < afl_preload_size; ++i) {
|
||||
|
||||
if (afl_preload[i] == ',') {
|
||||
|
||||
PFATAL(
|
||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||
"specified!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (qemu_preload) {
|
||||
|
||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
qemu_preload, afl_preload, afl_preload);
|
||||
|
||||
} else {
|
||||
|
||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
afl_preload, afl_preload);
|
||||
|
||||
}
|
||||
|
||||
setenv("QEMU_SET_ENV", buf, 1);
|
||||
|
||||
ck_free(buf);
|
||||
/* afl-qemu-trace takes care of converting AFL_PRELOAD. */
|
||||
|
||||
} else {
|
||||
|
||||
@ -946,31 +915,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
if (optind == argc || !out_file) { usage(argv[0]); }
|
||||
|
||||
if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) {
|
||||
|
||||
u8 *preload = getenv("AFL_PRELOAD");
|
||||
u8 *libqasan = get_libqasan_path(argv_orig[0]);
|
||||
|
||||
if (!preload) {
|
||||
|
||||
setenv("AFL_PRELOAD", libqasan, 0);
|
||||
|
||||
} else {
|
||||
|
||||
u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2);
|
||||
strcpy(result, libqasan);
|
||||
strcat(result, " ");
|
||||
strcat(result, preload);
|
||||
|
||||
setenv("AFL_PRELOAD", result, 1);
|
||||
ck_free(result);
|
||||
|
||||
}
|
||||
|
||||
ck_free(libqasan);
|
||||
|
||||
}
|
||||
|
||||
if (in_dir) {
|
||||
|
||||
if (!out_file && !collect_coverage)
|
||||
@ -1175,7 +1119,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
unlink(stdin_file);
|
||||
atexit(at_exit_handler);
|
||||
fsrv->out_file = stdin_file;
|
||||
fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
fsrv->out_fd =
|
||||
open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
|
||||
|
||||
if (arg_offset && use_argv[arg_offset] != stdin_file) {
|
||||
|
@ -244,7 +244,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
|
||||
|
||||
unlink(path); /* Ignore errors */
|
||||
|
||||
ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
ret = open(path, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
|
||||
if (ret < 0) { PFATAL("Unable to create '%s'", path); }
|
||||
|
||||
@ -666,7 +666,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
||||
unlink(out_file);
|
||||
|
||||
fsrv->out_file = out_file;
|
||||
fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
|
||||
|
||||
if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
|
||||
|
||||
@ -753,38 +753,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
||||
|
||||
if (fsrv->qemu_mode) {
|
||||
|
||||
u8 *qemu_preload = getenv("QEMU_SET_ENV");
|
||||
u8 *afl_preload = getenv("AFL_PRELOAD");
|
||||
u8 *buf;
|
||||
|
||||
s32 i, afl_preload_size = strlen(afl_preload);
|
||||
for (i = 0; i < afl_preload_size; ++i) {
|
||||
|
||||
if (afl_preload[i] == ',') {
|
||||
|
||||
PFATAL(
|
||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||
"specified!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (qemu_preload) {
|
||||
|
||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
qemu_preload, afl_preload, afl_preload);
|
||||
|
||||
} else {
|
||||
|
||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
afl_preload, afl_preload);
|
||||
|
||||
}
|
||||
|
||||
setenv("QEMU_SET_ENV", buf, 1);
|
||||
|
||||
ck_free(buf);
|
||||
/* afl-qemu-trace takes care of converting AFL_PRELOAD. */
|
||||
|
||||
} else {
|
||||
|
||||
@ -1079,31 +1048,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
check_environment_vars(envp);
|
||||
setenv("AFL_NO_AUTODICT", "1", 1);
|
||||
|
||||
if (fsrv->qemu_mode && getenv("AFL_USE_QASAN")) {
|
||||
|
||||
u8 *preload = getenv("AFL_PRELOAD");
|
||||
u8 *libqasan = get_libqasan_path(argv_orig[0]);
|
||||
|
||||
if (!preload) {
|
||||
|
||||
setenv("AFL_PRELOAD", libqasan, 0);
|
||||
|
||||
} else {
|
||||
|
||||
u8 *result = ck_alloc(strlen(libqasan) + strlen(preload) + 2);
|
||||
strcpy(result, libqasan);
|
||||
strcat(result, " ");
|
||||
strcat(result, preload);
|
||||
|
||||
setenv("AFL_PRELOAD", result, 1);
|
||||
ck_free(result);
|
||||
|
||||
}
|
||||
|
||||
ck_free(libqasan);
|
||||
|
||||
}
|
||||
|
||||
/* initialize cmplog_mode */
|
||||
shm.cmplog_mode = 0;
|
||||
|
||||
|
@ -18,6 +18,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef TEST_SHARED_OBJECT
|
||||
#define main main_exported
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int fd = 0;
|
||||
|
23
test/test-dlopen.c
Normal file
23
test/test-dlopen.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
if (!getenv("TEST_DLOPEN_TARGET")) return 1;
|
||||
void *lib = dlopen(getenv("TEST_DLOPEN_TARGET"), RTLD_LAZY);
|
||||
if (!lib) {
|
||||
|
||||
perror(dlerror());
|
||||
return 2;
|
||||
|
||||
}
|
||||
|
||||
int (*func)(int, char **) = dlsym(lib, "main_exported");
|
||||
if (!func) return 3;
|
||||
|
||||
return func(argc, argv);
|
||||
|
||||
}
|
||||
|
@ -43,6 +43,48 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
|
||||
$ECHO "$RED[!] llvm_mode failed"
|
||||
CODE=1
|
||||
}
|
||||
../afl-clang-fast -DTEST_SHARED_OBJECT=1 -z defs -fPIC -shared -o test-instr.so ../test-instr.c > /dev/null 2>&1
|
||||
test -e test-instr.so && {
|
||||
$ECHO "$GREEN[+] llvm_mode shared object with -z defs compilation succeeded"
|
||||
../afl-clang-fast -o test-dlopen.plain test-dlopen.c -ldl > /dev/null 2>&1
|
||||
test -e test-dlopen.plain && {
|
||||
$ECHO "$GREEN[+] llvm_mode test-dlopen compilation succeeded"
|
||||
echo 0 | TEST_DLOPEN_TARGET=./test-instr.so AFL_QUIET=1 ./test-dlopen.plain > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
$ECHO "$RED[!] llvm_mode test-dlopen exits with an error"
|
||||
CODE=1
|
||||
fi
|
||||
echo 0 | TEST_DLOPEN_TARGET=./test-instr.so AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o test-dlopen.plain.0 -r -- ./test-dlopen.plain > /dev/null 2>&1
|
||||
TEST_DLOPEN_TARGET=./test-instr.so AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o test-dlopen.plain.1 -r -- ./test-dlopen.plain < /dev/null > /dev/null 2>&1
|
||||
test -e test-dlopen.plain.0 -a -e test-dlopen.plain.1 && {
|
||||
diff test-dlopen.plain.0 test-dlopen.plain.1 > /dev/null 2>&1 && {
|
||||
$ECHO "$RED[!] llvm_mode test-dlopen instrumentation should be different on different input but is not"
|
||||
CODE=1
|
||||
} || {
|
||||
$ECHO "$GREEN[+] llvm_mode test-dlopen instrumentation present and working correctly"
|
||||
TUPLES=`echo 0|TEST_DLOPEN_TARGET=./test-instr.so AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-dlopen.plain 2>&1 | grep Captur | awk '{print$3}'`
|
||||
test "$TUPLES" -gt 3 -a "$TUPLES" -lt 12 && {
|
||||
$ECHO "$GREEN[+] llvm_mode test-dlopen run reported $TUPLES instrumented locations which is fine"
|
||||
} || {
|
||||
$ECHO "$RED[!] llvm_mode test-dlopen instrumentation produces weird numbers: $TUPLES"
|
||||
CODE=1
|
||||
}
|
||||
test "$TUPLES" -lt 3 && SKIP=1
|
||||
true
|
||||
}
|
||||
} || {
|
||||
$ECHO "$RED[!] llvm_mode test-dlopen instrumentation failed"
|
||||
CODE=1
|
||||
}
|
||||
} || {
|
||||
$ECHO "$RED[!] llvm_mode test-dlopen compilation failed"
|
||||
CODE=1
|
||||
}
|
||||
rm -f test-dlopen.plain test-dlopen.plain.0 test-dlopen.plain.1 test-instr.so
|
||||
} || {
|
||||
$ECHO "$RED[!] llvm_mode shared object with -z defs compilation failed"
|
||||
CODE=1
|
||||
}
|
||||
test -e test-compcov.harden && test_compcov_binary_functionality ./test-compcov.harden && {
|
||||
grep -Eq$GREPAOPTION 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden > /dev/null 2>&1 && {
|
||||
$ECHO "$GREEN[+] llvm_mode hardened mode succeeded and is working"
|
||||
|
@ -1,45 +0,0 @@
|
||||
# This is the Dockerfile for testing problems in Travis build
|
||||
# configuration #1.
|
||||
# This needs not to be rebuild everytime, most of the time it needs just to
|
||||
# be build once and then started when debugging issues and execute:
|
||||
# cd /AFLplusplus/
|
||||
# git pull
|
||||
# make distrib
|
||||
#
|
||||
FROM ubuntu:bionic
|
||||
LABEL "about"="travis image 1"
|
||||
RUN apt-get update && apt-get -y install \
|
||||
automake \
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
flex \
|
||||
git \
|
||||
python3.7 python3.7-dev \
|
||||
python3-setuptools \
|
||||
libtool libtool-bin \
|
||||
libglib2.0-dev \
|
||||
python-setuptools \
|
||||
wget \
|
||||
ca-certificates \
|
||||
libpixman-1-dev \
|
||||
gcc-7 gcc-7-plugin-dev libc++-7-dev \
|
||||
findutils \
|
||||
libcmocka-dev \
|
||||
joe nano vim locate \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV AFL_NO_UI=1
|
||||
ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
|
||||
ENV LLVM_CONFIG=llvm-config-6.0
|
||||
|
||||
RUN cd / && \
|
||||
git clone https://github.com/AFLplusplus/AFLplusplus && \
|
||||
cd AFLplusplus && \
|
||||
git checkout dev && \
|
||||
cd qemu_mode && wget http://download.qemu-project.org/qemu-3.1.1.tar.xz && \
|
||||
cd ../unicorn_mode && git submodule init && git submodule update || true && \
|
||||
cd /AFLplusplus && ASAN_BUILD=1 make source-only || true
|
||||
|
||||
WORKDIR /AFLplusplus
|
||||
CMD ["/bin/bash"]
|
@ -1,45 +0,0 @@
|
||||
# This is the Dockerfile for testing problems in Travis build
|
||||
# configuration #1.
|
||||
# This needs not to be rebuild everytime, most of the time it needs just to
|
||||
# be build once and then started when debugging issues and execute:
|
||||
# cd /AFLplusplus/
|
||||
# git pull
|
||||
# make distrib
|
||||
#
|
||||
FROM ubuntu:focal
|
||||
LABEL "about"="travis image 4"
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get -y install \
|
||||
automake \
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
flex \
|
||||
git \
|
||||
python3 python3-dev \
|
||||
python3-setuptools \
|
||||
libtool libtool-bin \
|
||||
libglib2.0-dev \
|
||||
python-setuptools \
|
||||
wget \
|
||||
ca-certificates \
|
||||
libpixman-1-dev \
|
||||
gcc-9 gcc-9-plugin-dev libc++-9-dev \
|
||||
findutils \
|
||||
libcmocka-dev \
|
||||
joe nano vim locate \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV AFL_NO_UI=1
|
||||
ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
|
||||
|
||||
RUN cd / && \
|
||||
git clone https://github.com/AFLplusplus/AFLplusplus && \
|
||||
cd AFLplusplus && \
|
||||
git checkout dev && \
|
||||
cd qemu_mode && wget http://download.qemu-project.org/qemu-3.1.1.tar.xz && \
|
||||
cd ../unicorn_mode && git submodule init && git submodule update || true && \
|
||||
cd /AFLplusplus && ASAN_BUILD=1 make source-only || true
|
||||
|
||||
WORKDIR /AFLplusplus
|
||||
CMD ["/bin/bash"]
|
@ -1,49 +0,0 @@
|
||||
# This is the Dockerfile for testing problems in Travis builds
|
||||
# configuration #3.
|
||||
# This needs not to be rebuild everytime, most of the time it needs just to
|
||||
# be build once and then started when debugging issues and execute:
|
||||
# cd /AFLplusplus/
|
||||
# git pull
|
||||
# make distrib
|
||||
#
|
||||
FROM ubuntu:trusty
|
||||
LABEL "about"="travis image 3"
|
||||
RUN apt-get update && apt-get -y install \
|
||||
automake \
|
||||
bison \
|
||||
build-essential \
|
||||
clang \
|
||||
flex \
|
||||
git \
|
||||
python2.7 python2.7-dev \
|
||||
python3-setuptools \
|
||||
libtool \
|
||||
libglib2.0-dev \
|
||||
python-setuptools \
|
||||
wget \
|
||||
ca-certificates \
|
||||
libpixman-1-dev \
|
||||
gcc-4.8 gcc-4.8-plugin-dev \
|
||||
libc++-dev \
|
||||
findutils \
|
||||
libcmocka-dev \
|
||||
joe nano vim locate \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV TERM linux
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
ENV LLVM_CONFIG=llvm-config-3.4
|
||||
ENV AFL_NO_UI=1
|
||||
ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
|
||||
|
||||
RUN cd / && \
|
||||
git clone https://github.com/AFLplusplus/AFLplusplus && \
|
||||
cd AFLplusplus && \
|
||||
git checkout dev && \
|
||||
cd qemu_mode && wget http://download.qemu-project.org/qemu-3.1.1.tar.xz && \
|
||||
cd ../unicorn_mode && git submodule init && git submodule update || true && \
|
||||
cd /AFLplusplus && ASAN_BUILD=1 make source-only || true
|
||||
|
||||
WORKDIR /AFLplusplus
|
||||
CMD ["/bin/bash"]
|
||||
|
@ -1,46 +0,0 @@
|
||||
# This is the Dockerfile for testing problems in Travis builds
|
||||
# configuration #2.
|
||||
# This needs not to be rebuild everytime, most of the time it needs just to
|
||||
# be build once and then started when debugging issues and execute:
|
||||
# cd /AFLplusplus/
|
||||
# git pull
|
||||
# make distrib
|
||||
#
|
||||
FROM ubuntu:xenial
|
||||
LABEL "about"="travis image 2"
|
||||
RUN apt-get update && apt-get -y install \
|
||||
automake \
|
||||
bison \
|
||||
build-essential \
|
||||
clang-6.0 \
|
||||
flex \
|
||||
git \
|
||||
python3 python3-dev \
|
||||
python3-setuptools \
|
||||
libtool libtool-bin \
|
||||
libglib2.0-dev \
|
||||
python-setuptools \
|
||||
wget \
|
||||
ca-certificates \
|
||||
libpixman-1-dev \
|
||||
gcc-5 gcc-5-plugin-dev \
|
||||
libc++-dev \
|
||||
findutils \
|
||||
libcmocka-dev \
|
||||
joe nano vim locate \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV LLVM_CONFIG=llvm-config-6.0
|
||||
ENV AFL_NO_UI=1
|
||||
ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
|
||||
|
||||
RUN cd / && \
|
||||
git clone https://github.com/AFLplusplus/AFLplusplus && \
|
||||
cd AFLplusplus && \
|
||||
git checkout dev && \
|
||||
cd qemu_mode && wget http://download.qemu-project.org/qemu-3.1.1.tar.xz && \
|
||||
cd ../unicorn_mode && git submodule init && git submodule update || true && \
|
||||
cd /AFLplusplus && ASAN_BUILD=1 make source-only || true
|
||||
|
||||
WORKDIR /AFLplusplus
|
||||
CMD ["/bin/bash"]
|
197
unicorn_mode/helper_scripts/ida_context_loader.py
Normal file
197
unicorn_mode/helper_scripts/ida_context_loader.py
Normal file
@ -0,0 +1,197 @@
|
||||
# Copyright (c) 2021 Brandon Miller (zznop)
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
"""IDA script for loading state that was dumped from a running process using unicorn AFL's GDB
|
||||
plugin (unicorn_dumper_gdb.py). The dumper script can be found in the AFL++ repository at:
|
||||
https://github.com/AFLplusplus/AFLplusplus/blob/stable/unicorn_mode/helper_scripts/unicorn_dumper_gdb.py
|
||||
"""
|
||||
|
||||
import json
|
||||
from pathlib import Path, PurePath
|
||||
import zlib
|
||||
import idaapi
|
||||
import ida_bytes
|
||||
import ida_kernwin
|
||||
import ida_nalt
|
||||
import ida_segment
|
||||
|
||||
|
||||
class ContextLoaderError(Exception):
|
||||
"""Base "catch all" exception for this script
|
||||
"""
|
||||
|
||||
|
||||
class ArchNotSupportedError(ContextLoaderError):
|
||||
"""Exception raised if the input file CPU architecture isn't supported fully
|
||||
"""
|
||||
|
||||
|
||||
def parse_mapping_index(filepath: str):
|
||||
"""Open and unmarshal the _index.json file
|
||||
|
||||
:param filepath: Path to the JSON file
|
||||
:return: Dict representing index file contents
|
||||
"""
|
||||
|
||||
if filepath is None:
|
||||
raise ContextLoaderError('_index.json file was not selected')
|
||||
|
||||
try:
|
||||
with open(filepath, 'rb') as _file:
|
||||
return json.load(_file)
|
||||
except Exception as ex:
|
||||
raise ContextLoaderError('Failed to parse json file {}'.format(filepath)) from ex
|
||||
|
||||
def get_input_name():
|
||||
"""Get the name of the input file
|
||||
|
||||
:retrun: Name of the input file
|
||||
"""
|
||||
|
||||
input_filepath = ida_nalt.get_input_file_path()
|
||||
return Path(input_filepath).name
|
||||
|
||||
def write_segment_bytes(start: int, filepath: str):
|
||||
""""Read data from context file and write it to the IDA segment
|
||||
|
||||
:param start: Start address
|
||||
:param filepath: Path to context file
|
||||
"""
|
||||
|
||||
with open(filepath, 'rb') as _file:
|
||||
data = _file.read()
|
||||
|
||||
decompressed_data = zlib.decompress(data)
|
||||
ida_bytes.put_bytes(start, decompressed_data)
|
||||
|
||||
def create_segment(context_dir: str, segment: dict, is_be: bool):
|
||||
"""Create segment in IDA and map in the data from the file
|
||||
|
||||
:param context_dir: Parent directory of the context files
|
||||
:param segment: Segment information from _index.json
|
||||
:param is_be: True if processor is big endian, otherwise False
|
||||
"""
|
||||
|
||||
input_name = get_input_name()
|
||||
if Path(segment['name']).name != input_name:
|
||||
ida_seg = idaapi.segment_t()
|
||||
ida_seg.start_ea = segment['start']
|
||||
ida_seg.end_ea = segment['end']
|
||||
ida_seg.bitness = 1 if is_be else 0
|
||||
if segment['permissions']['r']:
|
||||
ida_seg.perm |= ida_segment.SEGPERM_READ
|
||||
if segment['permissions']['w']:
|
||||
ida_seg.perm |= ida_segment.SEGPERM_WRITE
|
||||
if segment['permissions']['x']:
|
||||
ida_seg.perm |= ida_segment.SEGPERM_EXEC
|
||||
idaapi.add_segm_ex(ida_seg, Path(segment['name']).name, 'CODE', idaapi.ADDSEG_OR_DIE)
|
||||
else:
|
||||
idaapi.add_segm_ex(ida_seg, Path(segment['name']).name, 'DATA', idaapi.ADDSEG_OR_DIE)
|
||||
|
||||
if segment['content_file']:
|
||||
write_segment_bytes(segment['start'], PurePath(context_dir, segment['content_file']))
|
||||
|
||||
def create_segments(index: dict, context_dir: str):
|
||||
"""Iterate segments in index JSON, create the segment in IDA, and map in the data from the file
|
||||
|
||||
:param index: _index.json JSON data
|
||||
:param context_dir: Parent directory of the context files
|
||||
"""
|
||||
|
||||
info = idaapi.get_inf_structure()
|
||||
is_be = info.is_be()
|
||||
for segment in index['segments']:
|
||||
create_segment(context_dir, segment, is_be)
|
||||
|
||||
def rebase_program(index: dict):
|
||||
"""Rebase the program to the offset specified in the context _index.json
|
||||
|
||||
:param index: _index.json JSON data
|
||||
"""
|
||||
|
||||
input_name = get_input_name()
|
||||
new_base = None
|
||||
for segment in index['segments']:
|
||||
if not segment['name']:
|
||||
continue
|
||||
|
||||
segment_name = Path(segment['name']).name
|
||||
if input_name == segment_name:
|
||||
new_base = segment['start']
|
||||
break
|
||||
|
||||
if not new_base:
|
||||
raise ContextLoaderError('Input file is not in _index.json')
|
||||
|
||||
current_base = idaapi.get_imagebase()
|
||||
ida_segment.rebase_program(new_base-current_base, 8)
|
||||
|
||||
def get_pc_by_arch(index: dict) -> int:
|
||||
"""Queries the input file CPU architecture and attempts to lookup the address of the program
|
||||
counter in the _index.json by register name
|
||||
|
||||
:param index: _index.json JSON data
|
||||
:return: Program counter value or None
|
||||
"""
|
||||
|
||||
progctr = None
|
||||
info = idaapi.get_inf_structure()
|
||||
if info.procname == 'metapc':
|
||||
if info.is_64bit():
|
||||
progctr = index['regs']['rax']
|
||||
elif info.is_32bit():
|
||||
progctr = index['regs']['eax']
|
||||
return progctr
|
||||
|
||||
def write_reg_info(index: dict):
|
||||
"""Write register info as line comment at instruction pointed to by the program counter and
|
||||
change focus to that location
|
||||
|
||||
:param index: _index.json JSON data
|
||||
"""
|
||||
|
||||
cmt = ''
|
||||
for reg, val in index['regs'].items():
|
||||
cmt += f"{reg.ljust(6)} : {hex(val)}\n"
|
||||
|
||||
progctr = get_pc_by_arch(index)
|
||||
if progctr is None:
|
||||
raise ArchNotSupportedError(
|
||||
'Architecture not fully supported, skipping register status comment')
|
||||
ida_bytes.set_cmt(progctr, cmt, 0)
|
||||
ida_kernwin.jumpto(progctr)
|
||||
|
||||
def main(filepath):
|
||||
"""Main - parse _index.json input and map context files into the database
|
||||
|
||||
:param filepath: Path to the _index.json file
|
||||
"""
|
||||
|
||||
try:
|
||||
index = parse_mapping_index(filepath)
|
||||
context_dir = Path(filepath).parent
|
||||
rebase_program(index)
|
||||
create_segments(index, context_dir)
|
||||
write_reg_info(index)
|
||||
except ContextLoaderError as ex:
|
||||
print(ex)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(ida_kernwin.ask_file(1, '*.json', 'Import file name'))
|
1
unicorn_mode/unicornafl
Submodule
1
unicorn_mode/unicornafl
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit fb2fc9f25df32f17f6b6b859e4dbd70f9a857e0c
|
@ -237,38 +237,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
||||
|
||||
if (fsrv->qemu_mode) {
|
||||
|
||||
u8 *qemu_preload = getenv("QEMU_SET_ENV");
|
||||
u8 *afl_preload = getenv("AFL_PRELOAD");
|
||||
u8 *buf;
|
||||
|
||||
s32 i, afl_preload_size = strlen(afl_preload);
|
||||
for (i = 0; i < afl_preload_size; ++i) {
|
||||
|
||||
if (afl_preload[i] == ',') {
|
||||
|
||||
PFATAL(
|
||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||
"specified!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (qemu_preload) {
|
||||
|
||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
qemu_preload, afl_preload, afl_preload);
|
||||
|
||||
} else {
|
||||
|
||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||
afl_preload, afl_preload);
|
||||
|
||||
}
|
||||
|
||||
setenv("QEMU_SET_ENV", buf, 1);
|
||||
|
||||
afl_free(buf);
|
||||
/* afl-qemu-trace takes care of converting AFL_PRELOAD. */
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -187,6 +187,8 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
|
||||
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
}
|
||||
|
||||
free(buf);
|
||||
@ -208,6 +210,16 @@ int main(int argc, char **argv) {
|
||||
"======================================================\n",
|
||||
argv[0], argv[0]);
|
||||
|
||||
if (getenv("AFL_GDB")) {
|
||||
|
||||
char cmd[64];
|
||||
snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());
|
||||
system(cmd);
|
||||
fprintf(stderr, "DEBUG: aflpp_driver pid is %d\n", getpid());
|
||||
sleep(1);
|
||||
|
||||
}
|
||||
|
||||
output_file = stderr;
|
||||
maybe_duplicate_stderr();
|
||||
maybe_close_fd_mask();
|
||||
|
@ -60,12 +60,12 @@ if
|
||||
fi
|
||||
|
||||
if [ ! -f "$BIN" -o ! -x "$BIN" ]; then
|
||||
echo "[-] Error: binary '$2' not found or is not executable." 1>&2
|
||||
echo "[-] Error: binary '$BIN' not found or is not executable." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$DIR/queue" ]; then
|
||||
echo "[-] Error: directory '$1' not found or not created by afl-fuzz." 1>&2
|
||||
echo "[-] Error: directory '$DIR' not found or not created by afl-fuzz." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -168,7 +168,7 @@ static void *__dislocator_alloc(size_t len) {
|
||||
|
||||
u8 * ret, *base;
|
||||
size_t tlen;
|
||||
int flags, fd, sp;
|
||||
int flags, protflags, fd, sp;
|
||||
|
||||
if (total_mem + len > max_mem || total_mem + len < total_mem) {
|
||||
|
||||
@ -191,8 +191,14 @@ static void *__dislocator_alloc(size_t len) {
|
||||
|
||||
base = NULL;
|
||||
tlen = (1 + PG_COUNT(rlen + 8)) * PAGE_SIZE;
|
||||
protflags = PROT_READ | PROT_WRITE;
|
||||
flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||
fd = -1;
|
||||
#if defined(PROT_MAX)
|
||||
// apply when sysctl vm.imply_prot_max is set to 1
|
||||
// no-op otherwise
|
||||
protflags |= PROT_MAX(PROT_READ | PROT_WRITE);
|
||||
#endif
|
||||
#if defined(USEHUGEPAGE)
|
||||
sp = (rlen >= SUPER_PAGE_SIZE && !(rlen % SUPER_PAGE_SIZE));
|
||||
|
||||
@ -215,7 +221,7 @@ static void *__dislocator_alloc(size_t len) {
|
||||
(void)sp;
|
||||
#endif
|
||||
|
||||
ret = (u8 *)mmap(base, tlen, PROT_READ | PROT_WRITE, flags, fd, 0);
|
||||
ret = (u8 *)mmap(base, tlen, protflags, flags, fd, 0);
|
||||
#if defined(USEHUGEPAGE)
|
||||
/* We try one more time with regular call */
|
||||
if (ret == MAP_FAILED) {
|
||||
@ -229,7 +235,7 @@ static void *__dislocator_alloc(size_t len) {
|
||||
#elif defined(__sun)
|
||||
flags &= -MAP_ALIGN;
|
||||
#endif
|
||||
ret = (u8 *)mmap(NULL, tlen, PROT_READ | PROT_WRITE, flags, fd, 0);
|
||||
ret = (u8 *)mmap(NULL, tlen, protflags, flags, fd, 0);
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user