Merge pull request #837 from AFLplusplus/dev

final pull to stable
This commit is contained in:
van Hauser 2021-03-24 11:23:01 +01:00 committed by GitHub
commit 2dac4e785f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 579 additions and 158 deletions

View File

@ -558,6 +558,7 @@ clean:
-$(MAKE) -f GNUmakefile.gcc_plugin clean -$(MAKE) -f GNUmakefile.gcc_plugin clean
$(MAKE) -C utils/libdislocator clean $(MAKE) -C utils/libdislocator clean
$(MAKE) -C utils/libtokencap clean $(MAKE) -C utils/libtokencap clean
$(MAKE) -C utils/aflpp_driver clean
$(MAKE) -C utils/afl_network_proxy clean $(MAKE) -C utils/afl_network_proxy clean
$(MAKE) -C utils/socket_fuzzing clean $(MAKE) -C utils/socket_fuzzing clean
$(MAKE) -C utils/argv_fuzzing clean $(MAKE) -C utils/argv_fuzzing clean

View File

@ -507,6 +507,8 @@ install: all
@echo .SH LICENSE >> ./$@ @echo .SH LICENSE >> ./$@
@echo Apache License Version 2.0, January 2004 >> ./$@ @echo Apache License Version 2.0, January 2004 >> ./$@
@ln -sf afl-cc.8 ./afl-c++.8 @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)" "" ifneq "$(AFL_CLANG_FLTO)" ""
ifeq "$(LLVM_LTO)" "1" ifeq "$(LLVM_LTO)" "1"
@ln -sf afl-cc.8 ./afl-clang-lto.8 @ln -sf afl-cc.8 ./afl-clang-lto.8

View File

@ -2,9 +2,9 @@
<img align="right" src="https://raw.githubusercontent.com/andreafioraldi/AFLplusplus-website/master/static/logo_256x256.png" alt="AFL++ Logo"> <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) Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
@ -1184,6 +1184,7 @@ without feedback, bug reports, or patches from:
Josephine Calliotte Konrad Welc Josephine Calliotte Konrad Welc
Thomas Rooijakkers David Carlier Thomas Rooijakkers David Carlier
Ruben ten Hove Joey Jiao Ruben ten Hove Joey Jiao
fuzzah
``` ```
Thank you! Thank you!

View File

@ -2,6 +2,7 @@
## Roadmap 3.00+ ## Roadmap 3.00+
- Update afl->pending_not_fuzzed for MOpt
- CPU affinity for many cores? There seems to be an issue > 96 cores - CPU affinity for many cores? There seems to be an issue > 96 cores
- afl-plot to support multiple plot_data - afl-plot to support multiple plot_data
- afl_custom_fuzz_splice_optin() - afl_custom_fuzz_splice_optin()

View File

@ -8,18 +8,28 @@
Want to stay in the loop on major new features? Join our mailing list by Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>. sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++3.12a (dev) ### Version ++3.12c (release)
- afl-fuzz: - afl-fuzz:
- better map detection, AFL_MAP_SIZE not needed anymore for most cases - 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: - afl-cc:
- fix cmplog rtn (rare crash and not being able to gather ptr data) - 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 - link runtime not to shared libs
- ensure shared libraries are properly built and instrumented - 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): - qemu_mode (thanks @realmadsci):
- move AFL_PRELOAD and AFL_USE_QASAN logic inside afl-qemu-trace - move AFL_PRELOAD and AFL_USE_QASAN logic inside afl-qemu-trace
- add AFL_QEMU_CUSTOM_BIN - add AFL_QEMU_CUSTOM_BIN
- unicorn_mode - unicorn_mode
- accidently removed the subfolder from github, re-added - 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) ### Version ++3.11c (release)
- afl-fuzz: - afl-fuzz:

View File

@ -408,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 without disrupting the afl-fuzz process itself. This is useful, among other
things, for bootstrapping libdislocator.so. 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 - Setting `AFL_NO_UI` inhibits the UI altogether, and just periodically prints
some basic stats. This behavior is also automatically triggered when the some basic stats. This behavior is also automatically triggered when the
output from afl-fuzz is redirected to a file or to a pipe. output from afl-fuzz is redirected to a file or to a pipe.
@ -419,7 +425,8 @@ checks or alter some of the more exotic semantics of the tool:
no valid terminal was detected (for virtual consoles) no valid terminal was detected (for virtual consoles)
- If you are Jakub, you may need `AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES`. - 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 - 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 processing the first queue entry; and `AFL_BENCH_UNTIL_CRASH` causes it to

View File

@ -390,7 +390,7 @@ typedef struct afl_env_vars {
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload,
*afl_max_det_extras, *afl_statsd_host, *afl_statsd_port, *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
*afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size, *afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
*afl_testcache_entries, *afl_kill_signal; *afl_testcache_entries, *afl_kill_signal, *afl_target_env;
} afl_env_vars_t; } afl_env_vars_t;

View File

@ -49,6 +49,10 @@ 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_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv);
char * get_afl_env(char *env); char * get_afl_env(char *env);
/* 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 be_quiet;
extern u8 *doc_path; /* path to documentation dir */ extern u8 *doc_path; /* path to documentation dir */

View File

@ -26,7 +26,7 @@
/* Version string: */ /* Version string: */
// c = release, a = volatile github dev, e = experimental branch // c = release, a = volatile github dev, e = experimental branch
#define VERSION "++3.12a" #define VERSION "++3.12c"
/****************************************************** /******************************************************
* * * *
@ -43,6 +43,9 @@
Default: 8MB (defined in bytes) */ Default: 8MB (defined in bytes) */
#define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024) #define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024)
/* Default file permission umode when creating files (default: 0600) */
#define DEFAULT_PERMISSION 0600
/* CMPLOG/REDQUEEN TUNING /* CMPLOG/REDQUEEN TUNING
* *
* Here you can modify tuning and solving options for CMPLOG. * Here you can modify tuning and solving options for CMPLOG.

View File

@ -131,6 +131,7 @@ static char *afl_environment_variables[] = {
"AFL_PATH", "AFL_PATH",
"AFL_PERFORMANCE_FILE", "AFL_PERFORMANCE_FILE",
"AFL_PRELOAD", "AFL_PRELOAD",
"AFL_TARGET_ENV",
"AFL_PYTHON_MODULE", "AFL_PYTHON_MODULE",
"AFL_QEMU_CUSTOM_BIN", "AFL_QEMU_CUSTOM_BIN",
"AFL_QEMU_COMPCOV", "AFL_QEMU_COMPCOV",

View File

@ -507,6 +507,7 @@ bool ModuleSanitizerCoverage::instrumentModule(
Zero = ConstantInt::get(Int8Tyi, 0); Zero = ConstantInt::get(Int8Tyi, 0);
One = ConstantInt::get(Int8Tyi, 1); One = ConstantInt::get(Int8Tyi, 1);
initInstrumentList();
scanForDangerousFunctions(&M); scanForDangerousFunctions(&M);
Mo = &M; Mo = &M;
@ -1229,7 +1230,7 @@ void ModuleSanitizerCoverage::instrumentFunction(
// afl++ START // afl++ START
if (!F.size()) return; if (!F.size()) return;
if (isIgnoreFunction(&F)) return; if (!isInInstrumentList(&F)) return;
// afl++ END // afl++ END
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge) if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)

View File

@ -135,12 +135,14 @@ class ModuleSanitizerCoverage {
public: public:
ModuleSanitizerCoverage( ModuleSanitizerCoverage(
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(), const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()
const SpecialCaseList * Allowlist = nullptr, #if LLVM_MAJOR > 10
const SpecialCaseList * Blocklist = nullptr) ,
: Options(OverrideFromCL(Options)), const SpecialCaseList *Allowlist = nullptr,
Allowlist(Allowlist), const SpecialCaseList *Blocklist = nullptr
Blocklist(Blocklist) { #endif
)
: Options(OverrideFromCL(Options)) {
} }
@ -210,9 +212,6 @@ class ModuleSanitizerCoverage {
SanitizerCoverageOptions Options; SanitizerCoverageOptions Options;
const SpecialCaseList *Allowlist;
const SpecialCaseList *Blocklist;
uint32_t instr = 0; uint32_t instr = 0;
GlobalVariable *AFLMapPtr = NULL; GlobalVariable *AFLMapPtr = NULL;
ConstantInt * One = NULL; ConstantInt * One = NULL;
@ -224,27 +223,17 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
public: public:
ModuleSanitizerCoverageLegacyPass( ModuleSanitizerCoverageLegacyPass(
const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(), const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()
#if LLVM_VERSION_MAJOR > 10
,
const std::vector<std::string> &AllowlistFiles = const std::vector<std::string> &AllowlistFiles =
std::vector<std::string>(), std::vector<std::string>(),
const std::vector<std::string> &BlocklistFiles = const std::vector<std::string> &BlocklistFiles =
std::vector<std::string>()) std::vector<std::string>()
#endif
)
: ModulePass(ID), Options(Options) { : 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( initializeModuleSanitizerCoverageLegacyPassPass(
*PassRegistry::getPassRegistry()); *PassRegistry::getPassRegistry());
@ -252,8 +241,12 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
bool runOnModule(Module &M) override { bool runOnModule(Module &M) override {
ModuleSanitizerCoverage ModuleSancov(Options, Allowlist.get(), ModuleSanitizerCoverage ModuleSancov(Options
Blocklist.get()); #if LLVM_MAJOR > 10
,
Allowlist.get(), Blocklist.get()
#endif
);
auto DTCallback = [this](Function &F) -> const DominatorTree * { auto DTCallback = [this](Function &F) -> const DominatorTree * {
return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree(); return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
@ -298,8 +291,12 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M,
ModuleAnalysisManager &MAM) { ModuleAnalysisManager &MAM) {
ModuleSanitizerCoverage ModuleSancov(Options, Allowlist.get(), ModuleSanitizerCoverage ModuleSancov(Options
Blocklist.get()); #if LLVM_MAJOR > 10
,
Allowlist.get(), Blocklist.get()
#endif
);
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
auto DTCallback = [&FAM](Function &F) -> const DominatorTree * { auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
@ -418,12 +415,6 @@ bool ModuleSanitizerCoverage::instrumentModule(
} }
if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false; 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()); C = &(M.getContext());
DL = &M.getDataLayout(); DL = &M.getDataLayout();
CurModule = &M; CurModule = &M;
@ -696,9 +687,6 @@ void ModuleSanitizerCoverage::instrumentFunction(
if (F.hasPersonalityFn() && if (F.hasPersonalityFn() &&
isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
return; 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) if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
SplitAllCriticalEdges( SplitAllCriticalEdges(
F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests()); F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
@ -1216,12 +1204,20 @@ INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov",
false) false)
ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass(
const SanitizerCoverageOptions &Options, const SanitizerCoverageOptions &Options
#if LLVM_MAJOR > 10
,
const std::vector<std::string> &AllowlistFiles, const std::vector<std::string> &AllowlistFiles,
const std::vector<std::string> &BlocklistFiles) { const std::vector<std::string> &BlocklistFiles
#endif
) {
return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles, return new ModuleSanitizerCoverageLegacyPass(Options
BlocklistFiles); #if LLVM_MAJOR > 10
,
AllowlistFiles, BlocklistFiles
#endif
);
} }

View File

@ -204,7 +204,7 @@ static void __afl_map_shm_fuzz() {
int shm_fd = -1; int shm_fd = -1;
/* create the shared memory segment as if it was a file */ /* 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) { if (shm_fd == -1) {
fprintf(stderr, "shm_open() failed for fuzz\n"); fprintf(stderr, "shm_open() failed for fuzz\n");
@ -353,7 +353,7 @@ static void __afl_map_shm(void) {
unsigned char *shm_base = NULL; unsigned char *shm_base = NULL;
/* create the shared memory segment as if it was a file */ /* 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) { if (shm_fd == -1) {
fprintf(stderr, "shm_open() failed\n"); fprintf(stderr, "shm_open() failed\n");
@ -528,7 +528,7 @@ static void __afl_map_shm(void) {
struct cmp_map *shm_base = NULL; struct cmp_map *shm_base = NULL;
/* create the shared memory segment as if it was a file */ /* 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) { if (shm_fd == -1) {
perror("shm_open() failed\n"); perror("shm_open() failed\n");
@ -729,7 +729,7 @@ static void __afl_start_snapshots(void) {
static uint32_t counter = 0; static uint32_t counter = 0;
char fn[32]; char fn[32];
sprintf(fn, "%09u:forkserver", counter); 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 (fd_doc >= 0) {
if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) { 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; static uint32_t counter = 0;
char fn[32]; char fn[32];
sprintf(fn, "%09u:forkserver", counter); 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 (fd_doc >= 0) {
if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) { if (write(fd_doc, __afl_fuzz_ptr, *__afl_fuzz_len) != *__afl_fuzz_len) {

View File

@ -1 +1 @@
0fb212daab ddc4a9748d

View File

@ -212,7 +212,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
unlink(path); /* Ignore errors */ 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); } if (ret < 0) { PFATAL("Unable to create '%s'", path); }

View File

@ -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); } if (outfd < 0) { PFATAL("Unable to write to '%s'", modified_file); }

View File

@ -590,6 +590,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
#ifdef __ANDROID__ #ifdef __ANDROID__
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
instrument_mode != INSTRUMENT_LLVMNATIVE;
#else #else
if (have_instr_list) { 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 " "-fsanitize-coverage-allow/denylist, you can use "
"AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n"); "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n");
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
instrument_mode = INSTRUMENT_LLVMNATIVE;
} else { } 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 " "Using unoptimized trace-pc-guard, upgrade to llvm 10.0.1+ for "
"enhanced version.\n"); "enhanced version.\n");
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
instrument_mode = INSTRUMENT_LLVMNATIVE;
#else #else
FATAL("pcguard instrumentation requires llvm 4.0.1+"); FATAL("pcguard instrumentation requires llvm 4.0.1+");
#endif #endif
@ -718,8 +721,13 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} }
if (!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) || if ((!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) ||
!strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) { !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); } if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
continue; continue;
@ -1256,6 +1264,7 @@ int main(int argc, char **argv, char **envp) {
} else if (strcasecmp(ptr, "LLVMNATIVE") == 0 || } else if (strcasecmp(ptr, "LLVMNATIVE") == 0 ||
strcasecmp(ptr, "NATIVE") == 0 ||
strcasecmp(ptr, "LLVM-NATIVE") == 0) { strcasecmp(ptr, "LLVM-NATIVE") == 0) {
compiler_mode = LLVM; compiler_mode = LLVM;
@ -1668,8 +1677,8 @@ int main(int argc, char **argv, char **envp) {
"of afl-cc.\n\n"); "of afl-cc.\n\n");
#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
#define NATIVE_MSG \ #define NATIVE_MSG \
" NATIVE: use llvm's native PCGUARD instrumentation (less " \ " LLVM-NATIVE: use llvm's native PCGUARD instrumentation (less " \
"performant)\n" "performant)\n"
#else #else
#define NATIVE_MSG "" #define NATIVE_MSG ""

View File

@ -618,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. */ /* Read mask bitmap from file. This is for the -B option. */
void read_bitmap(u8 *fname, u8 *map, size_t len) { void read_bitmap(u8 *fname, u8 *map, size_t len) {
@ -1012,7 +1104,7 @@ FILE *create_ffile(u8 *fn) {
s32 fd; s32 fd;
FILE *f; 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); } if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
@ -1030,7 +1122,7 @@ s32 create_file(u8 *fn) {
s32 fd; 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); } if (fd < 0) { PFATAL("Unable to create '%s'", fn); }

View File

@ -809,7 +809,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
"have a\n" "have a\n"
" restrictive memory limit configured, this is expected; please " " restrictive memory limit configured, this is expected; please "
"read\n" "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); doc_path);
} else if (!fsrv->mem_limit) { } else if (!fsrv->mem_limit) {
@ -817,18 +817,21 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Whoops, the target binary crashed suddenly, " "Whoops, the target binary crashed suddenly, "
"before receiving any input\n" "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 " " - The target binary crashes because necessary runtime "
"reporting.\n" "conditions it needs\n"
" Set a high value (e.g. AFL_MAP_SIZE=8000000) or use " " are not met. Try to:\n"
"AFL_DEBUG=1 to see the\n" " 1. Run again with AFL_DEBUG=1 set and check the output of "
" message from the target binary\n\n" "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. " " - Possibly the target requires a huge coverage map and has "
"If so, you\n" "CTORS.\n"
" need to fix the underlying problem or find a better " " Retry with setting AFL_MAP_SIZE=10000000.\n\n"
"replacement.\n\n"
MSG_FORK_ON_APPLE MSG_FORK_ON_APPLE
@ -844,13 +847,17 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Whoops, the target binary crashed suddenly, " "Whoops, the target binary crashed suddenly, "
"before receiving any input\n" "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 " " - The target binary crashes because necessary runtime "
"reporting.\n" "conditions it needs\n"
" Set a high value (e.g. AFL_MAP_SIZE=8000000) or use " " are not met. Try to:\n"
"AFL_DEBUG=1 to see the\n" " 1. Run again with AFL_DEBUG=1 set and check the output of "
" message from the target binary\n\n" "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 current memory limit (%s) is too restrictive, causing "
"the\n" "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 " " estimate the required amount of virtual memory for the "
"binary.\n\n" "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 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 " " - Less likely, there is a horrible bug in the fuzzer. If other "
"options\n" "options\n"
" fail, poke <afl-users@googlegroups.com> for troubleshooting " " 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" "with ASAN and\n"
" you have a restrictive memory limit configured, this is " " you have a restrictive memory limit configured, this is "
"expected; please\n" "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); doc_path);
} else if (!fsrv->mem_limit) { } else if (!fsrv->mem_limit) {
@ -911,10 +917,22 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
SAYF("\n" cLRD "[-] " cRST SAYF("\n" cLRD "[-] " cRST
"Hmm, looks like the target binary terminated before we could complete" "Hmm, looks like the target binary terminated before we could complete"
" a\n" " a\n"
"handshake with the injected code.\n" "handshake with the injected code. You can try the following:\n\n"
"Most likely the target has a huge coverage map, retry with setting"
" the\n" " - The target binary crashes because necessary runtime conditions "
"environment variable AFL_MAP_SIZE=8000000\n" "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" "Otherwise there is a horrible bug in the fuzzer.\n"
"Poke <afl-users@googlegroups.com> for troubleshooting tips.\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 "\n" cLRD "[-] " cRST
"Hmm, looks like the target binary terminated " "Hmm, looks like the target binary terminated "
"before we could complete a\n" "before we could complete a\n"
" handshake with the injected code. There are %s probable " " handshake with the injected code. You can try the following:\n\n"
"explanations:\n\n"
"%s" "%s"
" - Most likely the target has a huge coverage map, retry with " " - The target binary crashes because necessary runtime conditions "
"setting the\n" "it needs\n"
" environment variable AFL_MAP_SIZE=8000000\n\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 " " - The current memory limit (%s) is too restrictive, causing an "
"OOM\n" "OOM\n"
@ -958,7 +985,6 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
"options\n" "options\n"
" fail, poke <afl-users@googlegroups.com> for troubleshooting " " fail, poke <afl-users@googlegroups.com> for troubleshooting "
"tips.\n", "tips.\n",
getenv(DEFER_ENV_VAR) ? "three" : "two",
getenv(DEFER_ENV_VAR) getenv(DEFER_ENV_VAR)
? " - You are using deferred forkserver, but __AFL_INIT() is " ? " - You are using deferred forkserver, but __AFL_INIT() is "
"never\n" "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)) { 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 { } else {
unlink(fsrv->out_file); /* Ignore errors. */ 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);
} }

View File

@ -42,7 +42,7 @@ void write_bitmap(afl_state_t *afl) {
afl->bitmap_changed = 0; afl->bitmap_changed = 0;
snprintf(fname, PATH_MAX, "%s/fuzz_bitmap", afl->out_dir); 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); } 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); 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. */ /* 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); alloc_printf("%s/queue/id_%06u", afl->out_dir, afl->queued_paths);
#endif /* ^!SIMPLE_FILES */ #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); } if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); }
ck_write(fd, mem, len, queue_fn); ck_write(fd, mem, len, queue_fn);
close(fd); 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 /* If we're here, we apparently want to save the crash or hang
test case, too. */ 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); } if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn); }
ck_write(fd, mem, len, fn); ck_write(fd, mem, len, fn);
close(fd); close(fd);

View File

@ -731,7 +731,7 @@ void save_auto(afl_state_t *afl) {
alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i); alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i);
s32 fd; 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); } if (fd < 0) { PFATAL("Unable to create '%s'", fn); }

View File

@ -152,7 +152,8 @@ void bind_to_free_cpu(afl_state_t *afl) {
do { 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) { if (first) {
@ -1219,7 +1220,7 @@ static void link_or_copy(u8 *old_path, u8 *new_path) {
sfd = open(old_path, O_RDONLY); sfd = open(old_path, O_RDONLY);
if (sfd < 0) { PFATAL("Unable to open '%s'", old_path); } 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); } if (dfd < 0) { PFATAL("Unable to create '%s'", new_path); }
tmp = ck_alloc(64 * 1024); 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 (!afl->in_place_resume) {
if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; }
ck_free(fn); 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); fn = alloc_printf("%s/cmdline", afl->out_dir);
if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; } if (unlink(fn) && errno != ENOENT) { goto dir_cleanup_failed; }
@ -2008,17 +2013,35 @@ void setup_dirs_fds(afl_state_t *afl) {
/* Gnuplot output file. */ /* Gnuplot output file. */
tmp = alloc_printf("%s/plot_data", afl->out_dir); 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->in_place_resume) {
if (!afl->fsrv.plot_file) { PFATAL("fdopen() failed"); }
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); fflush(afl->fsrv.plot_file);
/* ignore errors */ /* ignore errors */
@ -2035,7 +2058,7 @@ void setup_cmdline_file(afl_state_t *afl, char **argv) {
/* Store the command line to reproduce our findings */ /* Store the command line to reproduce our findings */
tmp = alloc_printf("%s/cmdline", afl->out_dir); 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); } if (fd < 0) { PFATAL("Unable to create '%s'", tmp); }
ck_free(tmp); ck_free(tmp);
@ -2070,7 +2093,8 @@ void setup_stdio_file(afl_state_t *afl) {
unlink(afl->fsrv.out_file); /* Ignore errors */ 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) { if (afl->fsrv.out_fd < 0) {

View File

@ -465,7 +465,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
unlink(q->fname); /* ignore errors */ 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); } if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }

View File

@ -5119,14 +5119,23 @@ pacemaker_fuzzing:
/* Update afl->pending_not_fuzzed count if we made it through the /* Update afl->pending_not_fuzzed count if we made it through the
calibration cycle and have not seen this entry before. */ 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 && if (!afl->queue_cur->was_fuzzed) {
// !afl->queue_cur->was_fuzzed) {
// afl->queue_cur->was_fuzzed = 1; --afl->pending_not_fuzzed;
// --afl->pending_not_fuzzed; afl->queue_cur->was_fuzzed = 1;
// if (afl->queue_cur->favored) --afl->pending_favored; if (afl->queue_cur->favored) { --afl->pending_favored; }
// }
}
}
*/
orig_in = NULL; orig_in = NULL;

View File

@ -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, snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir,
strrchr(q->fname, '/') + 1); 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); } if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
close(fd); close(fd);
@ -272,7 +272,7 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
if (symlink(ldest, fn)) { 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); } if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
close(fd); close(fd);
@ -300,7 +300,7 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
s32 fd; 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); } if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
close(fd); close(fd);
@ -680,13 +680,17 @@ void cull_queue(afl_state_t *afl) {
} }
afl->top_rated[i]->favored = 1; if (!afl->top_rated[i]->favored) {
++afl->queued_favored;
if (afl->top_rated[i]->fuzz_level == 0 || afl->top_rated[i]->favored = 1;
!afl->top_rated[i]->was_fuzzed) { ++afl->queued_favored;
++afl->pending_favored; if (afl->top_rated[i]->fuzz_level == 0 ||
!afl->top_rated[i]->was_fuzzed) {
++afl->pending_favored;
}
} }

View File

@ -83,7 +83,8 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
afl->document_counter++, afl->document_counter++,
describe_op(afl, 0, NAME_MAX - strlen("000000000:"))); 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) if (write(doc_fd, mem, len) != len)
PFATAL("write to mutation file failed: %s", fn); 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)) { 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 { } else {
unlink(afl->fsrv.out_file); /* Ignore errors. */ 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 */ /* document the attempt to sync to this instance */
sprintf(qd_synced_path, "%s/.synced/%s.last", afl->out_dir, sd_ent->d_name); 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); if (id_fd >= 0) close(id_fd);
/* Skip anything that doesn't have a queue/ subdirectory. */ /* 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); 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); } 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)) { 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); } 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 { } else {
unlink(q->fname); /* ignore errors */ 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); } if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }

View File

@ -433,6 +433,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_kill_signal = afl->afl_env.afl_kill_signal =
(u8 *)get_afl_env(afl_environment_variables[i]); (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 { } else {

View File

@ -391,10 +391,11 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
fprintf(afl->fsrv.plot_file, fprintf(afl->fsrv.plot_file,
"%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, " "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, "
"%u\n", "%u\n",
get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry, (afl->prev_run_time + get_cur_time() - afl->start_time),
afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored, afl->queue_cycle - 1, afl->current_entry, afl->queued_paths,
bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth, afl->pending_not_fuzzed, afl->pending_favored, bitmap_cvg,
eps, afl->plot_prev_ed, t_bytes); /* ignore errors */ afl->unique_crashes, afl->unique_hangs, afl->max_depth, eps,
afl->plot_prev_ed, t_bytes); /* ignore errors */
fflush(afl->fsrv.plot_file); fflush(afl->fsrv.plot_file);

View 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_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n"
"AFL_QUIET: suppress forkserver status messages\n" "AFL_QUIET: suppress forkserver status messages\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\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_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_BIN_CHECK: skip the check, if the target is an executable\n"
"AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n"
@ -1303,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); save_cmdline(afl, argc, argv);
fix_up_banner(afl, argv[optind]); fix_up_banner(afl, argv[optind]);

View File

@ -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()); snprintf(shm->g_shm_file_path, L_tmpnam, "/afl_%d_%ld", getpid(), random());
/* create the shared memory segment as if it was a file */ /* create the shared memory segment as if it was a file */
shm->g_shm_fd = shm->g_shm_fd = shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL,
shm_open(shm->g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600); DEFAULT_PERMISSION);
if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); } if (shm->g_shm_fd == -1) { PFATAL("shm_open() failed"); }
/* configure the size of the shared memory segment */ /* 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 */ /* create the shared memory segment as if it was a file */
shm->cmplog_g_shm_fd = 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"); } if (shm->cmplog_g_shm_fd == -1) { PFATAL("shm_open() failed"); }
/* configure the size of the shared memory segment */ /* configure the size of the shared memory segment */
@ -241,13 +242,14 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
#else #else
u8 *shm_str; 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->shm_id < 0) { PFATAL("shmget() failed"); }
if (shm->cmplog_mode) { if (shm->cmplog_mode) {
shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map), 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) { if (shm->cmplog_shm_id < 0) {

View File

@ -252,7 +252,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
} else { } else {
unlink(outfile); /* Ignore errors */ 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); } if (fd < 0) { PFATAL("Unable to create '%s'", outfile); }
} }
@ -1119,7 +1119,8 @@ int main(int argc, char **argv_orig, char **envp) {
unlink(stdin_file); unlink(stdin_file);
atexit(at_exit_handler); atexit(at_exit_handler);
fsrv->out_file = stdin_file; 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 (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
if (arg_offset && use_argv[arg_offset] != stdin_file) { if (arg_offset && use_argv[arg_offset] != stdin_file) {

View File

@ -244,7 +244,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
unlink(path); /* Ignore errors */ 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); } 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); unlink(out_file);
fsrv->out_file = 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); } if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }

View 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'))

View File

@ -187,6 +187,8 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
} }
close(fd);
} }
free(buf); free(buf);

View File

@ -168,7 +168,7 @@ static void *__dislocator_alloc(size_t len) {
u8 * ret, *base; u8 * ret, *base;
size_t tlen; size_t tlen;
int flags, fd, sp; int flags, protflags, fd, sp;
if (total_mem + len > max_mem || total_mem + len < total_mem) { if (total_mem + len > max_mem || total_mem + len < total_mem) {
@ -191,8 +191,14 @@ static void *__dislocator_alloc(size_t len) {
base = NULL; base = NULL;
tlen = (1 + PG_COUNT(rlen + 8)) * PAGE_SIZE; tlen = (1 + PG_COUNT(rlen + 8)) * PAGE_SIZE;
protflags = PROT_READ | PROT_WRITE;
flags = MAP_PRIVATE | MAP_ANONYMOUS; flags = MAP_PRIVATE | MAP_ANONYMOUS;
fd = -1; 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) #if defined(USEHUGEPAGE)
sp = (rlen >= SUPER_PAGE_SIZE && !(rlen % SUPER_PAGE_SIZE)); sp = (rlen >= SUPER_PAGE_SIZE && !(rlen % SUPER_PAGE_SIZE));
@ -215,7 +221,7 @@ static void *__dislocator_alloc(size_t len) {
(void)sp; (void)sp;
#endif #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) #if defined(USEHUGEPAGE)
/* We try one more time with regular call */ /* We try one more time with regular call */
if (ret == MAP_FAILED) { if (ret == MAP_FAILED) {
@ -229,7 +235,7 @@ static void *__dislocator_alloc(size_t len) {
#elif defined(__sun) #elif defined(__sun)
flags &= -MAP_ALIGN; flags &= -MAP_ALIGN;
#endif #endif
ret = (u8 *)mmap(NULL, tlen, PROT_READ | PROT_WRITE, flags, fd, 0); ret = (u8 *)mmap(NULL, tlen, protflags, flags, fd, 0);
} }