diff --git a/GNUmakefile b/GNUmakefile
index f885f998..ac8fe796 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -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
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index cc332f6c..111a847d 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -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
diff --git a/README.md b/README.md
index 2528e1d1..084971f3 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
- 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)
@@ -1184,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!
diff --git a/TODO.md b/TODO.md
index e5a678cf..b8a091ff 100644
--- a/TODO.md
+++ b/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()
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 166393cb..5b7d6ab6 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -8,18 +8,28 @@
Want to stay in the loop on major new features? Join our mailing list by
sending a mail to .
-### Version ++3.12a (dev)
+### Version ++3.12c (release)
- 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:
- 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:
diff --git a/docs/env_variables.md b/docs/env_variables.md
index c6ad0aa4..409425f1 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -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
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.
@@ -419,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
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 5003b563..565e9afd 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -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;
diff --git a/include/common.h b/include/common.h
index 46585c88..7bba9e91 100644
--- a/include/common.h
+++ b/include/common.h
@@ -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_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 *doc_path; /* path to documentation dir */
diff --git a/include/config.h b/include/config.h
index 29225f6b..c93a6d51 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,7 @@
/* Version string: */
// 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) */
#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.
diff --git a/include/envs.h b/include/envs.h
index 2ce50be7..d7578045 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -131,6 +131,7 @@ 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",
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 28d905a3..6dd390e6 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -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)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 99ead3d6..09cda9e2 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -135,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)) {
}
@@ -210,9 +212,6 @@ class ModuleSanitizerCoverage {
SanitizerCoverageOptions Options;
- const SpecialCaseList *Allowlist;
- const SpecialCaseList *Blocklist;
-
uint32_t instr = 0;
GlobalVariable *AFLMapPtr = NULL;
ConstantInt * One = NULL;
@@ -224,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 &AllowlistFiles =
std::vector(),
const std::vector &BlocklistFiles =
- std::vector())
+ std::vector()
+#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());
@@ -252,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(F).getDomTree();
@@ -298,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(M).getManager();
auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
@@ -418,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;
@@ -696,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());
@@ -1216,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 &AllowlistFiles,
- const std::vector &BlocklistFiles) {
+ const std::vector &BlocklistFiles
+#endif
+) {
- return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles,
- BlocklistFiles);
+ return new ModuleSanitizerCoverageLegacyPass(Options
+#if LLVM_MAJOR > 10
+ ,
+ AllowlistFiles, BlocklistFiles
+#endif
+ );
}
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index ab1bfb31..f241447a 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -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) {
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 68290650..8d95c359 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-0fb212daab
+ddc4a9748d
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 86b0f7e9..e106cd31 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -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); }
diff --git a/src/afl-as.c b/src/afl-as.c
index 7de267a3..aebd0ac8 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -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); }
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 5251465b..80fc0742 100644
--- a/src/afl-cc.c
+++ b/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
@@ -718,8 +721,13 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- if (!strncmp(cur, "-fsanitize=fuzzer-", strlen("-fsanitize=fuzzer-")) ||
- !strncmp(cur, "-fsanitize-coverage", strlen("-fsanitize-coverage"))) {
+ 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;
@@ -1256,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;
@@ -1668,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 ""
diff --git a/src/afl-common.c b/src/afl-common.c
index 04736901..37b4788c 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -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. */
void read_bitmap(u8 *fname, u8 *map, size_t len) {
@@ -1012,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); }
@@ -1030,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); }
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 68995388..c2d552cd 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -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 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 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 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);
}
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 4ed59364..3d0228db 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -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);
diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c
index 52100fa1..6091db15 100644
--- a/src/afl-fuzz-extras.c
+++ b/src/afl-fuzz-extras.c
@@ -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); }
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 82c1799e..70a49a6b 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -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) {
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 80df6d08..a47b4f5f 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -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); }
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index c73e394a..4e8154cd 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -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;
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index b2f88205..e5f51a6c 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -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;
+
+ }
}
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index 0b84a542..83133dad 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -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); }
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 3d36e712..0ddf8cf3 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -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 {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 99059a2d..2c814d90 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -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);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 1518a707..d70ffd31 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -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"
@@ -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);
fix_up_banner(afl, argv[optind]);
diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c
index 3241a130..fbb8e65d 100644
--- a/src/afl-sharedmem.c
+++ b/src/afl-sharedmem.c
@@ -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) {
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 7bf5a9c7..077c9248 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -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); }
}
@@ -1119,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) {
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 7ef8b9bf..fc974262 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -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); }
diff --git a/unicorn_mode/helper_scripts/ida_context_loader.py b/unicorn_mode/helper_scripts/ida_context_loader.py
new file mode 100644
index 00000000..31d47a90
--- /dev/null
+++ b/unicorn_mode/helper_scripts/ida_context_loader.py
@@ -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'))
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index f0f3a47d..ad781e64 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -187,6 +187,8 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
}
+ close(fd);
+
}
free(buf);
diff --git a/utils/libdislocator/libdislocator.so.c b/utils/libdislocator/libdislocator.so.c
index c041fec6..1b247c86 100644
--- a/utils/libdislocator/libdislocator.so.c
+++ b/utils/libdislocator/libdislocator.so.c
@@ -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);
}