aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2023-03-17 12:47:33 +0100
committerGitHub <noreply@github.com>2023-03-17 12:47:33 +0100
commit24503fba5fd2580559223ec3c6ee408dfa15e080 (patch)
tree95826d4a61f3c423d0e70eb7f1da568dc793204b
parent2ff0ff7a903c57f9df5ed1e97370c187ec45a31e (diff)
parentd80cedcf02f56351bb08e7520ddcd76b0ff3f84e (diff)
downloadafl++-24503fba5fd2580559223ec3c6ee408dfa15e080.tar.gz
Merge pull request #1668 from AFLplusplus/dev
push to stable
-rw-r--r--.github/workflows/ci.yml8
-rw-r--r--GNUmakefile4
-rw-r--r--docs/Changelog.md6
-rw-r--r--docs/env_variables.md6
-rw-r--r--docs/fuzzing_binary-only_targets.md8
-rw-r--r--include/afl-fuzz.h1
-rw-r--r--include/common.h4
-rw-r--r--include/envs.h1
-rw-r--r--instrumentation/afl-compiler-rt.o.c57
-rw-r--r--instrumentation/afl-llvm-common.h8
-rw-r--r--qemu_mode/QEMUAFL_VERSION2
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-analyze.c4
-rw-r--r--src/afl-common.c75
-rw-r--r--src/afl-fuzz-bitmap.c42
-rw-r--r--src/afl-fuzz-init.c19
-rw-r--r--src/afl-fuzz-queue.c2
-rw-r--r--src/afl-fuzz-state.c22
-rw-r--r--src/afl-fuzz-stats.c31
-rw-r--r--src/afl-fuzz.c5
-rw-r--r--src/afl-showmap.c4
-rw-r--r--src/afl-tmin.c4
-rwxr-xr-xtest/test-basic.sh101
-rw-r--r--test/test-cmplog.c2
-rw-r--r--utils/aflpp_driver/aflpp_driver.c13
-rw-r--r--utils/aflpp_driver/aflpp_driver_test.c13
26 files changed, 296 insertions, 146 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 04cbaca8..ed1f3228 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -23,15 +23,17 @@ jobs:
- name: debug
run: apt-cache search plugin-dev | grep gcc-; echo; apt-cache search clang-format- | grep clang-format-
- name: update
- run: sudo apt-get update && sudo apt-get upgrade -y
+ run: sudo apt-get update
+ # && sudo apt-get upgrade -y
- name: install packages
- run: sudo apt-get install -y -m -f --install-suggests build-essential git libtool libtool-bin automake bison libglib2.0-0 clang llvm-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build
+ #run: sudo apt-get install -y -m -f --install-suggests build-essential git libtool libtool-bin automake bison libglib2.0-0 clang llvm-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip
+ run: sudo apt-get install -y -m -f build-essential git libtool libtool-bin automake flex bison libglib2.0-0 clang llvm-dev libc++-dev findutils libcmocka-dev python3-dev python3-setuptools ninja-build python3-pip
- name: compiler installed
run: gcc -v; echo; clang -v
- name: install gcc plugin
run: sudo apt-get install -y -m -f --install-suggests $(readlink /usr/bin/gcc)-plugin-dev
- name: build afl++
- run: make distrib ASAN_BUILD=1
+ run: make distrib ASAN_BUILD=1 NO_NYX=1
- name: run tests
run: sudo -E ./afl-system-config; make tests
macos:
diff --git a/GNUmakefile b/GNUmakefile
index 6921cc85..8d66e2f4 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -546,8 +546,8 @@ ifndef AFL_NO_X86
test_build: afl-cc afl-gcc afl-as afl-showmap
@echo "[*] Testing the CC wrapper afl-cc and its instrumentation output..."
@unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c $(LDFLAGS) -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 )
- ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr0 ./test-instr < /dev/null
- echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
+ - ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -o .test-instr0 ./test-instr < /dev/null
+ -echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr
@rm -f test-instr
@cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-cc does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi
@echo
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 8f71fd83..25c1f6bc 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -7,16 +7,20 @@
- afl-fuzz:
- ensure temporary file descriptor is closed when not used
- added `AFL_NO_WARN_INSTABILITY`
+ - added `AFL_FRIDA_STATS_INTERVAL`
- afl-cc:
- add CFI sanitizer variant to gcc targets
- llvm 16 support (thanks to @devnexen!)
- support llvm 15 native pcguard changes
+ - support for LLVMFuzzerTestOneInput -1 return
+ - qemu_mode:
+ - fix _RANGES envs to allow hyphens in the filenames
- new custom module: autotoken, grammar free fuzzer for text inputs
- LTO autoken and llvm_mode: added AFL_LLVM_DICT2FILE_NO_MAIN support
- better sanitizer default options support for all tools
- unicorn_mode: updated and minor issues fixed
- frida_mode: fix issue on MacOS
- - more minor fixes
+ - more minor fixes and cross-platform support
### Version ++4.05c (release)
- MacOS: libdislocator, libtokencap etc. do not work with modern
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 6cd4104b..c9dc1bbd 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -584,6 +584,12 @@ checks or alter some of the more exotic semantics of the tool:
- Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to 0
to disable although it is 1st of April.
+ - If you need a specific interval to update fuzzer_stats file, you can
+ set `AFL_FUZZER_STATS_UPDATE_INTERVAL` to the interval in seconds you'd
+ the file to be updated.
+ Note that will not be exact and with slow targets it can take seconds
+ until there is a slice for the time test.
+
## 5) Settings for afl-qemu-trace
The QEMU wrapper used to instrument binary-only code supports several settings:
diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md
index 266920e6..9d9d6bb6 100644
--- a/docs/fuzzing_binary-only_targets.md
+++ b/docs/fuzzing_binary-only_targets.md
@@ -201,10 +201,10 @@ afl-clang-fast's.
### RetroWrite
RetroWrite is a static binary rewriter that can be combined with AFL++. If you
-have an x86_64 binary that still has its symbols (i.e., not stripped binary), is
-compiled with position independent code (PIC/PIE), and does not contain C++
-exceptions, then the RetroWrite solution might be for you. It decompiles to ASM
-files which can then be instrumented with afl-gcc.
+have an x86_64 or arm64 binary that does not contain C++ exceptions and - if
+x86_64 - still has it's symbols and compiled with position independent code
+(PIC/PIE), then the RetroWrite solution might be for you.
+It decompiles to ASM files which can then be instrumented with afl-gcc.
Binaries that are statically instrumented for fuzzing using RetroWrite are close
in performance to compiler-instrumented binaries and outperform the QEMU-based
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 9bf91faf..6a8e8b5d 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -693,6 +693,7 @@ typedef struct afl_state {
/* statistics file */
double last_bitmap_cvg, last_stability, last_eps;
+ u64 stats_file_update_freq_msecs; /* Stats update frequency (msecs) */
/* plot file saves from last run */
u32 plot_prev_qp, plot_prev_pf, plot_prev_pnf, plot_prev_ce, plot_prev_md;
diff --git a/include/common.h b/include/common.h
index c5a32cdb..0958b035 100644
--- a/include/common.h
+++ b/include/common.h
@@ -143,5 +143,9 @@ FILE *create_ffile(u8 *fn);
/* create a file */
s32 create_file(u8 *fn);
+/* memmem implementation as not all platforms support this */
+void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle,
+ size_t needlelen);
+
#endif
diff --git a/include/envs.h b/include/envs.h
index cf069a00..066921b9 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -91,6 +91,7 @@ static char *afl_environment_variables[] = {
"AFL_FRIDA_TRACEABLE",
"AFL_FRIDA_VERBOSE",
"AFL_FUZZER_ARGS", // oss-fuzz
+ "AFL_FUZZER_STATS_UPDATE_INTERVAL",
"AFL_GDB",
"AFL_GCC_ALLOWLIST",
"AFL_GCC_DENYLIST",
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 9871d7f4..a88396d4 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1539,12 +1539,16 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
if (start == stop || *start) return;
x = getenv("AFL_INST_RATIO");
- if (x) { inst_ratio = (u32)atoi(x); }
+ if (x) {
- if (!inst_ratio || inst_ratio > 100) {
+ inst_ratio = (u32)atoi(x);
- fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
- abort();
+ if (!inst_ratio || inst_ratio > 100) {
+
+ fprintf(stderr, "[-] ERROR: Invalid AFL_INST_RATIO (must be 1-100).\n");
+ abort();
+
+ }
}
@@ -1568,10 +1572,16 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
while (start < stop) {
- if (likely(inst_ratio == 100) || R(100) < inst_ratio)
- *start = offset;
- else
- *start = 0; // write to map[0]
+ if (likely(inst_ratio == 100) || R(100) < inst_ratio) {
+
+ *(start++) = offset;
+
+ } else {
+
+ *(start++) = 0; // write to map[0]
+
+ }
+
if (unlikely(++offset >= __afl_final_loc)) { offset = 4; }
}
@@ -1592,12 +1602,15 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
while (start < stop) {
- if (likely(inst_ratio == 100) || R(100) < inst_ratio)
- *start = ++__afl_final_loc;
- else
- *start = 0; // write to map[0]
+ if (likely(inst_ratio == 100) || R(100) < inst_ratio) {
+
+ *(start++) = ++__afl_final_loc;
+
+ } else {
+
+ *(start++) = 0; // write to map[0]
- start++;
+ }
}
@@ -1609,17 +1622,23 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
}
- if (__afl_already_initialized_shm && __afl_final_loc > __afl_map_size) {
+ if (__afl_already_initialized_shm) {
- if (__afl_debug) {
+ if (__afl_final_loc > __afl_map_size) {
+
+ if (__afl_debug) {
+
+ fprintf(stderr, "Reinit shm necessary (+%u)\n",
+ __afl_final_loc - __afl_map_size);
+
+ }
- fprintf(stderr, "Reinit shm necessary (+%u)\n",
- __afl_final_loc - __afl_map_size);
+ __afl_unmap_shm();
+ __afl_map_shm();
}
- __afl_unmap_shm();
- __afl_map_shm();
+ __afl_map_size = __afl_final_loc + 1;
}
diff --git a/instrumentation/afl-llvm-common.h b/instrumentation/afl-llvm-common.h
index 0112c325..16a13da5 100644
--- a/instrumentation/afl-llvm-common.h
+++ b/instrumentation/afl-llvm-common.h
@@ -37,10 +37,10 @@ typedef long double max_align_t;
#define MNAME M.getSourceFileName()
#define FMNAME F.getParent()->getSourceFileName()
#if LLVM_VERSION_MAJOR >= 16
- // None becomes deprecated
- // the standard std::nullopt_t is recommended instead
- // from C++17 and onwards.
- constexpr std::nullopt_t None = std::nullopt;
+// None becomes deprecated
+// the standard std::nullopt_t is recommended instead
+// from C++17 and onwards.
+constexpr std::nullopt_t None = std::nullopt;
#endif
#else
#define MNAME std::string("")
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 9c68f02c..43dc832b 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-a8af9cbde7
+249bf0c872
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject a8af9cbde71e333ce72a46f15e655d0b82ed093
+Subproject 249bf0c8723671a1eebe400a9631d9e69306ff4
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index d4a9aa91..548956d8 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -725,7 +725,11 @@ static void setup_signal_handlers(void) {
struct sigaction sa;
sa.sa_handler = NULL;
+#ifdef SA_RESTART
sa.sa_flags = SA_RESTART;
+#else
+ sa.sa_flags = 0;
+#endif
sa.sa_sigaction = NULL;
sigemptyset(&sa.sa_mask);
diff --git a/src/afl-common.c b/src/afl-common.c
index d83130b4..86226c9f 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -58,6 +58,25 @@ u8 last_intr = 0;
#define AFL_PATH "/usr/local/lib/afl/"
#endif
+void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle,
+ size_t needlelen) {
+
+ if (unlikely(needlelen > haystacklen)) { return NULL; }
+
+ for (u32 i = 0; i <= haystacklen - needlelen; ++i) {
+
+ if (unlikely(memcmp(haystack + i, needle, needlelen) == 0)) {
+
+ return (void *)(haystack + i);
+
+ }
+
+ }
+
+ return (void *)NULL;
+
+}
+
void set_sanitizer_defaults() {
/* Set sane defaults for ASAN if nothing else is specified. */
@@ -66,23 +85,44 @@ void set_sanitizer_defaults() {
u8 *have_msan_options = getenv("MSAN_OPTIONS");
u8 *have_lsan_options = getenv("LSAN_OPTIONS");
u8 have_san_options = 0;
+ u8 default_options[1024] =
+ "detect_odr_violation=0:abort_on_error=1:symbolize=0:allocator_may_"
+ "return_null=1:handle_segv=0:handle_sigbus=0:handle_abort=0:handle_"
+ "sigfpe=0:handle_sigill=0:";
+
if (have_asan_options || have_ubsan_options || have_msan_options ||
- have_lsan_options)
+ have_lsan_options) {
+
have_san_options = 1;
- u8 default_options[1024] =
- "detect_odr_violation=0:abort_on_error=1:symbolize=0:malloc_context_"
- "size=0:allocator_may_return_null=1:handle_segv=0:handle_sigbus=0:"
- "handle_abort=0:handle_sigfpe=0:handle_sigill=0:";
- if (!have_lsan_options) strcat(default_options, "detect_leaks=0:");
+ }
+
+ /* LSAN does not support abort_on_error=1. (is this still true??) */
+
+ if (!have_lsan_options) {
+
+ u8 buf[2048] = "";
+ if (!have_san_options) { strcpy(buf, default_options); }
+ strcat(buf, "exitcode=" STRINGIFY(LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:detect_leaks=1:malloc_context_size=30:");
+ setenv("LSAN_OPTIONS", buf, 1);
+
+ }
+
+ /* for everything not LSAN we disable detect_leaks */
+
+ if (!have_lsan_options) {
+
+ strcat(default_options, "detect_leaks=0:malloc_context_size=0:");
+
+ }
/* Set sane defaults for ASAN if nothing else is specified. */
- if (!have_san_options) setenv("ASAN_OPTIONS", default_options, 1);
+ if (!have_san_options) { setenv("ASAN_OPTIONS", default_options, 1); }
/* Set sane defaults for UBSAN if nothing else is specified. */
- if (!have_san_options) setenv("UBSAN_OPTIONS", default_options, 1);
+ if (!have_san_options) { setenv("UBSAN_OPTIONS", default_options, 1); }
/* MSAN is tricky, because it doesn't support abort_on_error=1 at this
point. So, we do this in a very hacky way. */
@@ -90,25 +130,12 @@ void set_sanitizer_defaults() {
if (!have_msan_options) {
u8 buf[2048] = "";
- if (!have_san_options) strcpy(buf, default_options);
+ if (!have_san_options) { strcpy(buf, default_options); }
strcat(buf, "exit_code=" STRINGIFY(MSAN_ERROR) ":msan_track_origins=0:");
setenv("MSAN_OPTIONS", buf, 1);
}
- /* LSAN, too, does not support abort_on_error=1. (is this still true??) */
-
- if (!have_lsan_options) {
-
- u8 buf[2048] = "";
- if (!have_san_options) strcpy(buf, default_options);
- strcat(buf,
- "exitcode=" STRINGIFY(
- LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:");
- setenv("LSAN_OPTIONS", buf, 1);
-
- }
-
/* Envs for QASan */
setenv("QASAN_MAX_CALL_STACK", "0", 0);
setenv("QASAN_SYMBOLIZE", "0", 0);
@@ -126,7 +153,7 @@ u32 check_binary_signatures(u8 *fn) {
if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); }
close(fd);
- if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
+ if (afl_memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
if (!be_quiet) { OKF(cPIN "Persistent mode binary detected."); }
setenv(PERSIST_ENV_VAR, "1", 1);
@@ -151,7 +178,7 @@ u32 check_binary_signatures(u8 *fn) {
}
- if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
+ if (afl_memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
if (!be_quiet) { OKF(cPIN "Deferred forkserver binary detected."); }
setenv(DEFER_ENV_VAR, "1", 1);
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index b4e9537e..c65dd641 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -475,10 +475,13 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
only be used for special schedules */
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
+ classify_counts(&afl->fsrv);
+ classified = 1;
+
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
/* Saturated increment */
- if (afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF)
+ if (likely(afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF))
afl->n_fuzz[cksum % N_FUZZ_SIZE]++;
}
@@ -488,7 +491,15 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
/* Keep only if there are new bits in the map, add to queue for
future fuzzing, etc. */
- new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
+ if (likely(classified)) {
+
+ new_bits = has_new_bits(afl, afl->virgin_bits);
+
+ } else {
+
+ new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
+
+ }
if (likely(!new_bits)) {
@@ -497,8 +508,6 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
}
- classified = new_bits;
-
save_to_queue:
#ifndef SIMPLE_FILES
@@ -556,21 +565,21 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
}
- /* AFLFast schedule? update the new queue entry */
- if (cksum) {
+ if (unlikely(!classified && new_bits)) {
- afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
- afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
+ /* due to classify counts we have to recalculate the checksum */
+ afl->queue_top->exec_cksum =
+ hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+ classified = 1;
}
- /* due to classify counts we have to recalculate the checksum */
- afl->queue_top->exec_cksum =
- hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+ /* For AFLFast schedules we update the new queue entry */
+ afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
+ afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
/* Try to calibrate inline; this also calls update_bitmap_score() when
successful. */
-
res = calibrate_case(afl, afl->queue_top, mem, afl->queue_cycle - 1, 0);
if (unlikely(res == FSRV_RUN_ERROR)) {
@@ -604,7 +613,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (likely(!afl->non_instrumented_mode)) {
- if (!classified) {
+ if (unlikely(!classified)) {
classify_counts(&afl->fsrv);
classified = 1;
@@ -729,7 +738,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (likely(!afl->non_instrumented_mode)) {
- if (!classified) { classify_counts(&afl->fsrv); }
+ if (unlikely(!classified)) {
+
+ classify_counts(&afl->fsrv);
+ classified = 1;
+
+ }
simplify_trace(afl, afl->fsrv.trace_bits);
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index c20965b4..01d1e82e 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -24,7 +24,9 @@
*/
#include "afl-fuzz.h"
+#include "common.h"
#include <limits.h>
+#include <string.h>
#include "cmplog.h"
#ifdef HAVE_AFFINITY
@@ -2786,7 +2788,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
!afl->fsrv.nyx_mode &&
#endif
!afl->fsrv.cs_mode && !afl->non_instrumented_mode &&
- !memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
+ !afl_memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
SAYF("\n" cLRD "[-] " cRST
"Looks like the target binary is not instrumented! The fuzzer depends "
@@ -2817,7 +2819,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
}
if ((afl->fsrv.cs_mode || afl->fsrv.qemu_mode || afl->fsrv.frida_mode) &&
- memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
+ afl_memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
SAYF("\n" cLRD "[-] " cRST
"This program appears to be instrumented with afl-gcc, but is being "
@@ -2830,9 +2832,9 @@ void check_binary(afl_state_t *afl, u8 *fname) {
}
- if (memmem(f_data, f_len, "__asan_init", 11) ||
- memmem(f_data, f_len, "__msan_init", 11) ||
- memmem(f_data, f_len, "__lsan_init", 11)) {
+ if (afl_memmem(f_data, f_len, "__asan_init", 11) ||
+ afl_memmem(f_data, f_len, "__msan_init", 11) ||
+ afl_memmem(f_data, f_len, "__lsan_init", 11)) {
afl->fsrv.uses_asan = 1;
@@ -2840,7 +2842,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
/* Detect persistent & deferred init signatures in the binary. */
- if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
+ if (afl_memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
OKF(cPIN "Persistent mode binary detected.");
setenv(PERSIST_ENV_VAR, "1", 1);
@@ -2867,7 +2869,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
}
if (afl->fsrv.frida_mode ||
- memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
+ afl_memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
OKF(cPIN "Deferred forkserver binary detected.");
setenv(DEFER_ENV_VAR, "1", 1);
@@ -2923,8 +2925,11 @@ void setup_signal_handlers(void) {
struct sigaction sa;
+ memset((void *)&sa, 0, sizeof(sa));
sa.sa_handler = NULL;
+#ifdef SA_RESTART
sa.sa_flags = SA_RESTART;
+#endif
sa.sa_sigaction = NULL;
sigemptyset(&sa.sa_mask);
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 65446799..4eb55bb3 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -67,7 +67,7 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q,
if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
u32 hits = afl->n_fuzz[q->n_fuzz_entry];
- if (likely(hits)) { weight *= (log10(hits) + 1); }
+ if (likely(hits)) { weight /= (log10(hits) + 1); }
}
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 6d8c8758..f9aa5cfe 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -24,6 +24,7 @@
*/
#include <signal.h>
+#include <limits.h>
#include "afl-fuzz.h"
#include "envs.h"
@@ -100,6 +101,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->hang_tmout = EXEC_TIMEOUT;
afl->exit_on_time = 0;
afl->stats_update_freq = 1;
+ afl->stats_file_update_freq_msecs = STATS_UPDATE_SEC * 1000;
afl->stats_avg_exec = 0;
afl->skip_deterministic = 1;
afl->sync_time = SYNC_TIME;
@@ -565,6 +567,26 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
}
+ } else if (!strncmp(env, "AFL_FUZZER_STATS_UPDATE_INTERVAL",
+
+ afl_environment_variable_len)) {
+
+ u64 stats_update_freq_sec =
+ strtoull(get_afl_env(afl_environment_variables[i]), NULL, 0);
+ if (stats_update_freq_sec >= UINT_MAX ||
+ 0 == stats_update_freq_sec) {
+
+ WARNF(
+ "Incorrect value given to AFL_FUZZER_STATS_UPDATE_INTERVAL, "
+ "using default of %d seconds\n",
+ STATS_UPDATE_SEC);
+
+ } else {
+
+ afl->stats_file_update_freq_msecs = stats_update_freq_sec * 1000;
+
+ }
+
}
} else {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index bfd30845..f53fd610 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -62,7 +62,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
if (memchr(argv[i], '\'', strlen(argv[i]))) {
#else
- if (index(argv[i], '\'')) {
+ if (strchr(argv[i], '\'')) {
#endif
@@ -611,9 +611,10 @@ void show_stats_normal(afl_state_t *afl) {
/* Roughly every minute, update fuzzer stats and save auto tokens. */
- if (unlikely(!afl->non_instrumented_mode &&
- (afl->force_ui_update ||
- cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000))) {
+ if (unlikely(
+ !afl->non_instrumented_mode &&
+ (afl->force_ui_update || cur_ms - afl->stats_last_stats_ms >
+ afl->stats_file_update_freq_msecs))) {
afl->stats_last_stats_ms = cur_ms;
write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio,
@@ -669,9 +670,14 @@ void show_stats_normal(afl_state_t *afl) {
/* AFL_EXIT_ON_TIME. */
- if (unlikely(afl->last_find_time && !afl->non_instrumented_mode &&
- afl->afl_env.afl_exit_on_time &&
- (cur_ms - afl->last_find_time) > afl->exit_on_time)) {
+ /* If no coverage was found yet, check whether run time is greater than
+ * exit_on_time. */
+
+ if (unlikely(!afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time &&
+ ((afl->last_find_time &&
+ (cur_ms - afl->last_find_time) > afl->exit_on_time) ||
+ (!afl->last_find_time &&
+ (cur_ms - afl->start_time) > afl->exit_on_time)))) {
afl->stop_soon = 2;
@@ -1470,12 +1476,11 @@ void show_stats_pizza(afl_state_t *afl) {
/* If no coverage was found yet, check whether run time is greater than
* exit_on_time. */
- if (unlikely(
- !afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time &&
- ((afl->last_find_time &&
- (cur_ms - afl->last_find_time) > afl->exit_on_time) ||
- (!afl->last_find_time && (afl->prev_run_time + cur_ms -
- afl->start_time) > afl->exit_on_time)))) {
+ if (unlikely(!afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time &&
+ ((afl->last_find_time &&
+ (cur_ms - afl->last_find_time) > afl->exit_on_time) ||
+ (!afl->last_find_time &&
+ (cur_ms - afl->start_time) > afl->exit_on_time)))) {
afl->stop_soon = 2;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 4914ce0b..d7708fdf 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -210,7 +210,8 @@ static void usage(u8 *argv0, int more_help) {
" -b cpu_id - bind the fuzzing process to the specified CPU core "
"(0-...)\n"
" -e ext - file extension for the fuzz test input file (if "
- "needed)\n\n",
+ "needed)\n"
+ "\n",
argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX);
if (more_help > 1) {
@@ -312,6 +313,8 @@ static void usage(u8 *argv0, int more_help) {
" afl-clang-lto/afl-gcc-fast target\n"
"AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n"
"AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so)\n"
+ "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in seconds, "
+ "(default: 60, minimum: 1)\n"
"\n"
);
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 1e281d08..29abeb13 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -654,7 +654,11 @@ static void setup_signal_handlers(void) {
struct sigaction sa;
sa.sa_handler = NULL;
+#ifdef SA_RESTART
sa.sa_flags = SA_RESTART;
+#else
+ sa.sa_flags = 0;
+#endif
sa.sa_sigaction = NULL;
sigemptyset(&sa.sa_mask);
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 12c5e0c9..c0087f5f 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -743,7 +743,11 @@ static void setup_signal_handlers(void) {
struct sigaction sa;
sa.sa_handler = NULL;
+#ifdef SA_RESTART
sa.sa_flags = SA_RESTART;
+#else
+ sa.sa_flags = 0;
+#endif
sa.sa_sigaction = NULL;
sigemptyset(&sa.sa_mask);
diff --git a/test/test-basic.sh b/test/test-basic.sh
index 538b6931..067d8a47 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -7,9 +7,10 @@ AFL_GCC=afl-gcc
$ECHO "$BLUE[*] Testing: ${AFL_GCC}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" -o "$SYS" = "i386" && {
test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && {
- ../${AFL_GCC} -o test-instr.plain -O0 ../test-instr.c > /dev/null 2>&1
- AFL_HARDEN=1 ../${AFL_GCC} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
- test -e test-instr.plain && {
+ ../${AFL_GCC} -v 2>&1 | grep -qi "gcc version" && {
+ ../${AFL_GCC} -o test-instr.plain -O0 ../test-instr.c > /dev/null 2>&1
+ AFL_HARDEN=1 ../${AFL_GCC} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
+ test -e test-instr.plain && {
$ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded"
echo 0 | AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o test-instr.plain.0 -r -- ./test-instr.plain > /dev/null 2>&1
AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o test-instr.plain.1 -r -- ./test-instr.plain < /dev/null > /dev/null 2>&1
@@ -35,15 +36,15 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
test "$TUPLES" -lt 3 && SKIP=1
true # this is needed because of the test above
- } || {
+ } || {
$ECHO "$RED[!] ${AFL_GCC} failed"
echo CUT------------------------------------------------------------------CUT
uname -a
../${AFL_GCC} -o test-instr.plain -O0 ../test-instr.c
echo CUT------------------------------------------------------------------CUT
CODE=1
- }
- test -e test-compcov.harden && {
+ }
+ test -e test-compcov.harden && {
nm test-compcov.harden | grep -Eq 'stack_chk_fail|fstack-protector-all|fortified' > /dev/null 2>&1 && {
$ECHO "$GREEN[+] ${AFL_GCC} hardened mode succeeded and is working"
} || {
@@ -54,16 +55,16 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
CODE=1
}
rm -f test-compcov.harden
- } || {
+ } || {
$ECHO "$RED[!] ${AFL_GCC} hardened mode compilation failed"
CODE=1
- }
- # now we want to be sure that afl-fuzz is working
- # make sure crash reporter is disabled on Mac OS X
- (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
+ }
+ # now we want to be sure that afl-fuzz is working
+ # make sure crash reporter is disabled on Mac OS X
+ (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET"
true
- }) || {
+ }) || {
mkdir -p in
echo 0 > in/in
test -z "$SKIP" && {
@@ -116,83 +117,89 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
rm -rf in out errors in2
unset AFL_QUIET
+ }
+ rm -f test-instr.plain
+ } || {
+ $ECHO "$YELLOW[-] afl-gcc executes clang, cannot test!"
+ INCOMPLETE=1
}
- rm -f test-instr.plain
} || {
- $ECHO "$YELLOW[-] afl is not compiled, cannot test"
- INCOMPLETE=1
+ $ECHO "$YELLOW[-] afl is not compiled, cannot test"
+ INCOMPLETE=1
}
- if [ ${AFL_GCC} = "afl-gcc" ] ; then AFL_GCC=afl-clang ; else AFL_GCC=afl-gcc ; fi
- $ECHO "$BLUE[*] Testing: ${AFL_GCC}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
+
+ AFL_CLANG=afl-clang
+ $ECHO "$BLUE[*] Testing: ${AFL_CLANG}, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
SKIP=
- test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && {
- ../${AFL_GCC} -o test-instr.plain -O0 ../test-instr.c > /dev/null 2>&1
- AFL_HARDEN=1 ../${AFL_GCC} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
- test -e test-instr.plain && {
- $ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded"
+ test -e ../${AFL_CLANG} -a -e ../afl-showmap -a -e ../afl-fuzz && {
+ ../${AFL_CLANG} -v 2>&1 | grep -qi "clang version" && {
+ ../${AFL_CLANG} -o test-instr.plain -O0 ../test-instr.c > /dev/null 2>&1
+ AFL_HARDEN=1 ../${AFL_CLANG} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
+ test -e test-instr.plain && {
+ $ECHO "$GREEN[+] ${AFL_CLANG} compilation succeeded"
echo 0 | AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o test-instr.plain.0 -r -- ./test-instr.plain > /dev/null 2>&1
AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o test-instr.plain.1 -r -- ./test-instr.plain < /dev/null > /dev/null 2>&1
test -e test-instr.plain.0 -a -e test-instr.plain.1 && {
diff test-instr.plain.0 test-instr.plain.1 > /dev/null 2>&1 && {
- $ECHO "$RED[!] ${AFL_GCC} instrumentation should be different on different input but is not"
+ $ECHO "$RED[!] ${AFL_CLANG} instrumentation should be different on different input but is not"
CODE=1
} || {
- $ECHO "$GREEN[+] ${AFL_GCC} instrumentation present and working correctly"
+ $ECHO "$GREEN[+] ${AFL_CLANG} instrumentation present and working correctly"
}
} || {
- $ECHO "$RED[!] ${AFL_GCC} instrumentation failed"
+ $ECHO "$RED[!] ${AFL_CLANG} instrumentation failed"
CODE=1
}
rm -f test-instr.plain.0 test-instr.plain.1
TUPLES=`echo 1|AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-instr.plain 2>&1 | grep Captur | awk '{print$3}'`
test "$TUPLES" -gt 1 -a "$TUPLES" -lt 12 && {
- $ECHO "$GREEN[+] ${AFL_GCC} run reported $TUPLES instrumented locations which is fine"
+ $ECHO "$GREEN[+] ${AFL_CLANG} run reported $TUPLES instrumented locations which is fine"
} || {
- $ECHO "$RED[!] ${AFL_GCC} instrumentation produces weird numbers: $TUPLES"
+ $ECHO "$RED[!] ${AFL_CLANG} instrumentation produces weird numbers: $TUPLES"
CODE=1
}
test "$TUPLES" -lt 3 && SKIP=1
true # this is needed because of the test above
- } || {
- $ECHO "$RED[!] ${AFL_GCC} failed"
+ } || {
+ $ECHO "$RED[!] ${AFL_CLANG} failed"
echo CUT------------------------------------------------------------------CUT
uname -a
- ../${AFL_GCC} -o test-instr.plain ../test-instr.c
+ ../${AFL_CLANG} -o test-instr.plain ../test-instr.c
echo CUT------------------------------------------------------------------CUT
CODE=1
- }
- test -e test-compcov.harden && {
+ }
+ test -e test-compcov.harden && {
nm test-compcov.harden | grep -Eq 'stack_chk_fail|fstack-protector-all|fortified' > /dev/null 2>&1 && {
- $ECHO "$GREEN[+] ${AFL_GCC} hardened mode succeeded and is working"
+ $ECHO "$GREEN[+] ${AFL_CLANG} hardened mode succeeded and is working"
} || {
- $ECHO "$RED[!] ${AFL_GCC} hardened mode is not hardened"
+ $ECHO "$RED[!] ${AFL_CLANG} hardened mode is not hardened"
CODE=1
}
rm -f test-compcov.harden
- } || {
- $ECHO "$RED[!] ${AFL_GCC} hardened mode compilation failed"
+ } || {
+ $ECHO "$RED[!] ${AFL_CLANG} hardened mode compilation failed"
CODE=1
- }
- # now we want to be sure that afl-fuzz is working
- # make sure crash reporter is disabled on Mac OS X
- (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
+ }
+ # now we want to be sure that afl-fuzz is working
+ # make sure crash reporter is disabled on Mac OS X
+ (test "$(uname -s)" = "Darwin" && test $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') && {
$ECHO "$RED[!] we cannot run afl-fuzz with enabled crash reporter. Run 'sudo sh afl-system-config'.$RESET"
true
- }) || {
+ }) || {
mkdir -p in
echo 0 > in/in
test -z "$SKIP" && {
- $ECHO "$GREY[*] running afl-fuzz for ${AFL_GCC}, this will take approx 10 seconds"
+ $ECHO "$GREY[*] running afl-fuzz for ${AFL_CLANG}, this will take approx 10 seconds"
{
../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -D -- ./test-instr.plain >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/default/queue/id:000002* 2>/dev/null )" && {
- $ECHO "$GREEN[+] afl-fuzz is working correctly with ${AFL_GCC}"
+ $ECHO "$GREEN[+] afl-fuzz is working correctly with ${AFL_CLANG}"
} || {
echo CUT------------------------------------------------------------------CUT
cat errors
echo CUT------------------------------------------------------------------CUT
- $ECHO "$RED[!] afl-fuzz is not working correctly with ${AFL_GCC}"
+ $ECHO "$RED[!] afl-fuzz is not working correctly with ${AFL_CLANG}"
CODE=1
}
}
@@ -247,8 +254,12 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
rm -rf in out errors in2
unset AFL_QUIET
+ }
+ rm -f test-instr.plain
+ } || {
+ $ECHO "$YELLOW[-] afl-clang executes gcc, cannot test"
+ INCOMPLETE=1
}
- rm -f test-instr.plain
} || {
$ECHO "$YELLOW[-] afl is not compiled, cannot test"
INCOMPLETE=1
diff --git a/test/test-cmplog.c b/test/test-cmplog.c
index d724ecaf..bd1b73e3 100644
--- a/test/test-cmplog.c
+++ b/test/test-cmplog.c
@@ -8,7 +8,7 @@
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t i) {
- if (i < 30) return 0;
+ if (i < 30) return -1;
if (buf[0] != 'A') return 0;
if (buf[1] != 'B') return 0;
if (buf[2] != 'C') return 0;
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index 03376b6a..f08c9864 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -58,10 +58,15 @@ $AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
#include "hash.h"
#endif
+// AFL++ shared memory fuzz cases
int __afl_sharedmem_fuzzing = 1;
extern unsigned int *__afl_fuzz_len;
extern unsigned char *__afl_fuzz_ptr;
+// AFL++ coverage map
+extern unsigned char *__afl_area_ptr;
+extern unsigned int __afl_map_size;
+
// libFuzzer interface is thin, so we don't include any libFuzzer headers.
__attribute__((weak)) int LLVMFuzzerTestOneInput(const uint8_t *Data,
size_t Size);
@@ -375,7 +380,13 @@ int LLVMFuzzerRunDriver(int *argcp, char ***argvp,
}
prev_length = length;
- (void)callback(__afl_fuzz_ptr, length);
+
+ if (unlikely(callback(__afl_fuzz_ptr, length) == -1)) {
+
+ memset(__afl_area_ptr, 0, __afl_map_size);
+ __afl_area_ptr[0] = 1;
+
+ }
}
diff --git a/utils/aflpp_driver/aflpp_driver_test.c b/utils/aflpp_driver/aflpp_driver_test.c
index 527ba57b..7cffa4a1 100644
--- a/utils/aflpp_driver/aflpp_driver_test.c
+++ b/utils/aflpp_driver/aflpp_driver_test.c
@@ -2,9 +2,9 @@
#include <stdlib.h>
#include <stdint.h>
-void __attribute__((noinline)) crashme(const uint8_t *Data, size_t Size) {
+int __attribute__((noinline)) crashme(const uint8_t *Data, size_t Size) {
- if (Size < 5) return;
+ if (Size < 5) return -1;
if (Data[0] == 'F')
if (Data[1] == 'A')
@@ -12,13 +12,16 @@ void __attribute__((noinline)) crashme(const uint8_t *Data, size_t Size) {
if (Data[3] == '$')
if (Data[4] == '$') abort();
+ return 0;
+
}
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- if (Size) crashme(Data, Size);
-
- return 0;
+ if (Size)
+ return crashme(Data, Size);
+ else
+ return -1;
}