mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-10 01:01:33 +00:00
Merge branch 'AFLplusplus:stable' into stable
This commit is contained in:
commit
fa8dc2028f
@ -21,12 +21,15 @@ import os
|
||||
# import re # TODO: for future use
|
||||
import shutil
|
||||
import importlib.metadata
|
||||
import hashlib
|
||||
|
||||
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use
|
||||
|
||||
CURRENT_LLVM = os.getenv('LLVM_VERSION', 18)
|
||||
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
|
||||
|
||||
FORMAT_CACHE_DIR = '.format-cache'
|
||||
os.makedirs(FORMAT_CACHE_DIR, exist_ok=True)
|
||||
|
||||
def check_clang_format_pip_version():
|
||||
"""
|
||||
@ -69,6 +72,8 @@ to install via pip.")
|
||||
if CLANG_FORMAT_PIP:
|
||||
CLANG_FORMAT_BIN = shutil.which("clang-format")
|
||||
|
||||
CLANG_FORMAT_VERSION = subprocess.check_output([CLANG_FORMAT_BIN, '--version'])
|
||||
|
||||
COLUMN_LIMIT = 80
|
||||
for line in fmt.split("\n"):
|
||||
line = line.split(":")
|
||||
@ -86,9 +91,10 @@ def custom_format(filename):
|
||||
out = ""
|
||||
|
||||
for line in src.split("\n"):
|
||||
define_start = False
|
||||
if line.lstrip().startswith("#"):
|
||||
if line[line.find("#") + 1:].lstrip().startswith("define"):
|
||||
in_define = True
|
||||
define_start = True
|
||||
|
||||
if (
|
||||
"/*" in line
|
||||
@ -126,9 +132,7 @@ def custom_format(filename):
|
||||
and last_line.strip() != ""
|
||||
):
|
||||
line = (" " * define_padding + "\\" if in_define else "") + "\n" + line
|
||||
|
||||
if not line.endswith("\\"):
|
||||
in_define = False
|
||||
in_define = (define_start or in_define) and line.endswith("\\")
|
||||
|
||||
out += line + "\n"
|
||||
last_line = line
|
||||
@ -136,6 +140,38 @@ def custom_format(filename):
|
||||
return out
|
||||
|
||||
|
||||
def hash_code_and_formatter(code):
|
||||
hasher = hashlib.sha256()
|
||||
|
||||
hasher.update(code.encode())
|
||||
hasher.update(CLANG_FORMAT_VERSION)
|
||||
with open(__file__, 'rb') as f:
|
||||
hasher.update(f.read())
|
||||
|
||||
return hasher.hexdigest()
|
||||
|
||||
|
||||
def custom_format_cached(filename):
|
||||
filename_hash = hashlib.sha256(filename.encode()).hexdigest()
|
||||
cache_file = os.path.join(FORMAT_CACHE_DIR, filename_hash)
|
||||
|
||||
if os.path.exists(cache_file):
|
||||
with open(filename) as f:
|
||||
code = f.read()
|
||||
code_hash = hash_code_and_formatter(code)
|
||||
with open(cache_file) as f:
|
||||
if f.read() == code_hash:
|
||||
return code
|
||||
|
||||
code = custom_format(filename)
|
||||
|
||||
code_hash = hash_code_and_formatter(code)
|
||||
with open(cache_file, 'w') as f:
|
||||
f.write(code_hash)
|
||||
|
||||
return code
|
||||
|
||||
|
||||
args = sys.argv[1:]
|
||||
if len(args) == 0:
|
||||
print("Usage: ./format.py [-i] <filename>")
|
||||
@ -151,7 +187,7 @@ if args[0] == "-i":
|
||||
args = args[1:]
|
||||
|
||||
for filename in args:
|
||||
code = custom_format(filename)
|
||||
code = custom_format_cached(filename)
|
||||
if in_place:
|
||||
with open(filename, "w") as f:
|
||||
f.write(code)
|
||||
|
2
.github/workflows/rust_custom_mutator.yml
vendored
2
.github/workflows/rust_custom_mutator.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
working-directory: custom_mutators/rust
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04]
|
||||
os: [ubuntu-22.04]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Rust Toolchain
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,6 +7,7 @@
|
||||
*.so
|
||||
*.swp
|
||||
.DS_Store
|
||||
.format-cache
|
||||
.sync_tmp
|
||||
.test
|
||||
.test2
|
||||
|
13
GNUmakefile
13
GNUmakefile
@ -473,7 +473,7 @@ ready:
|
||||
@echo "[+] Everything seems to be working, ready to compile. ($(shell $(CC) --version 2>&1|head -n 1))"
|
||||
|
||||
src/afl-performance.o : $(COMM_HDR) src/afl-performance.c include/hash.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_OPT) $(SPECIAL_PERFORMANCE) -Iinclude -c src/afl-performance.c -o src/afl-performance.o
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(CFLAGS_OPT) $(SPECIAL_PERFORMANCE) -Iinclude -c src/afl-performance.c -o src/afl-performance.o
|
||||
|
||||
src/afl-common.o : $(COMM_HDR) src/afl-common.c include/common.h
|
||||
$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -c src/afl-common.c -o src/afl-common.o
|
||||
@ -490,7 +490,7 @@ ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
endif
|
||||
|
||||
afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
afl-showmap: src/afl-showmap.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86
|
||||
$(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) src/$@.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS)
|
||||
ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
@ -535,20 +535,20 @@ ifdef IS_IOS
|
||||
endif
|
||||
|
||||
test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
|
||||
@$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
|
||||
|
||||
unit_hash: test/unittests/unit_hash.o src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_hash
|
||||
ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
endif
|
||||
|
||||
test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
|
||||
@$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
|
||||
|
||||
unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o
|
||||
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
@$(CC) $(CFLAGS) $(CFLAGS_FLTO) $(ASAN_CFLAGS) $(SPECIAL_PERFORMANCE) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
|
||||
./test/unittests/unit_rand
|
||||
ifdef IS_IOS
|
||||
@ldid -Sentitlements.plist $@ && echo "[+] Signed $@" || { echo "[-] Failed to sign $@"; }
|
||||
@ -684,6 +684,7 @@ deepclean: clean
|
||||
rm -rf unicorn_mode/unicornafl
|
||||
rm -rf qemu_mode/qemuafl
|
||||
rm -rf nyx_mode/libnyx nyx_mode/packer nyx_mode/QEMU-Nyx
|
||||
rm -rf .format-cache
|
||||
ifeq "$(IN_REPO)" "1"
|
||||
git checkout coresight_mode/coresight-trace
|
||||
git checkout unicorn_mode/unicornafl
|
||||
|
@ -240,7 +240,7 @@ ifeq "$(LLVM_LTO)" "1"
|
||||
else
|
||||
ifneq "$(shell command -v ld.lld 2>/dev/null)" ""
|
||||
AFL_REAL_LD = $(shell command -v ld.lld)
|
||||
TMP_LDLDD_VERSION = $(shell $(AFL_REAL_LD) --version | awk '{ print $$2 }')
|
||||
TMP_LDLDD_VERSION = $(shell $(AFL_REAL_LD) --version | sed -E -ne '/^.*LLD\ ([12]?[0-9]\.[0-9]\.[0-9]).*/s//\1/p')
|
||||
ifeq "$(LLVMVER)" "$(TMP_LDLDD_VERSION)"
|
||||
$(warning ld.lld found in a weird location ($(AFL_REAL_LD)), but its the same version as LLVM so we will allow it)
|
||||
else
|
||||
|
2
afl-cmin
2
afl-cmin
@ -432,7 +432,7 @@ BEGIN {
|
||||
} else {
|
||||
stat_format = "-f '%z %N'" # *BSD, MacOS
|
||||
}
|
||||
cmdline = "(cd "in_dir" && find . \\( ! -name \".*\" -a -type d \\) -o -type f -exec stat "stat_format" \\{\\} + | sort -k1n -k2r) | grep -Ev '^0'"
|
||||
cmdline = "(cd "in_dir" && find . \\( ! -name \".*\" -a -type d \\) -o \\( -type f -a ! -name \"cmdline\" -a ! -name \"fastresume.bin\" -a ! -name \"fuzz_bitmap\" -a ! -name \"fuzzer_setup\" -a ! -name \"fuzzer_stats\" -a ! -name \"plot_data\" -a ! -name \"target_hash\" \\) -exec stat "stat_format" \\{\\} + | sort -k1n -k2r) | grep -Ev '^0'"
|
||||
#cmdline = "ls "in_dir" | (cd "in_dir" && xargs stat "stat_format" 2>/dev/null) | sort -k1n -k2r"
|
||||
#cmdline = "(cd "in_dir" && stat "stat_format" *) | sort -k1n -k2r"
|
||||
#cmdline = "(cd "in_dir" && ls | xargs stat "stat_format" ) | sort -k1n -k2r"
|
||||
|
@ -121,6 +121,7 @@ kernel.sched_child_runs_first=1
|
||||
kernel.sched_autogroup_enabled=1
|
||||
kernel.sched_migration_cost_ns=50000000
|
||||
kernel.sched_latency_ns=250000000
|
||||
vm.swappiness=10
|
||||
EOF
|
||||
}
|
||||
|
||||
@ -129,7 +130,7 @@ EOF
|
||||
if ! grep -E "^$KEY=" /etc/default/grub | grep -E -q 'noibrs pcid nopti'; then
|
||||
echo "Configuring performance boot options"
|
||||
LINE=`grep -E "^$KEY=" /etc/default/grub | sed "s/^$KEY=//" | tr -d '"'`
|
||||
OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off spec_rstack_overflow=off mds=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"
|
||||
OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off spec_rstack_overflow=off mds=off nokaslr no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"
|
||||
echo Setting boot options in /etc/default/grub to $KEY=\"$OPTIONS\"
|
||||
sed -i "s|^$KEY=.*|$KEY=\"$OPTIONS\"|" /etc/default/grub
|
||||
fi
|
||||
|
@ -41,6 +41,7 @@ if [ "$PLATFORM" = "Linux" ] ; then
|
||||
sysctl -w kernel.sched_autogroup_enabled=1
|
||||
sysctl -w kernel.sched_migration_cost_ns=50000000 2>/dev/null
|
||||
sysctl -w kernel.sched_latency_ns=250000000 2>/dev/null
|
||||
sysctl -w vm.swappiness=10 2>/dev/null
|
||||
echo never > /sys/kernel/mm/transparent_hugepage/enabled
|
||||
test -e /sys/devices/system/cpu/cpufreq/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpufreq/scaling_governor
|
||||
test -e /sys/devices/system/cpu/cpufreq/policy0/scaling_governor && echo performance | tee /sys/devices/system/cpu/cpufreq/policy*/scaling_governor
|
||||
@ -54,7 +55,7 @@ if [ "$PLATFORM" = "Linux" ] ; then
|
||||
echo
|
||||
dmesg | grep -E -q 'noibrs pcid nopti' || {
|
||||
echo It is recommended to boot the kernel with lots of security off - if you are running a machine that is in a secured network - so set this:
|
||||
echo ' /etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=0 l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx_async_abort=off arm64.nopauth audit=0 hardened_usercopy=off ssbd=force-off"'
|
||||
echo ' /etc/default/grub:GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off spec_rstack_overflow=off mds=off nokaslr no_stf_barrier noibpb noibrs pcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=on pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off srbds=off noexec=off noexec32=off tsx=on tsx=on tsx_async_abort=off mitigations=off audit=0 hardened_usercopy=off ssbd=force-off"'
|
||||
echo
|
||||
}
|
||||
echo If you run fuzzing instances in docker, run them with \"--security-opt seccomp=unconfined\" for more speed.
|
||||
|
@ -6,6 +6,14 @@
|
||||
### Version ++4.32a (dev)
|
||||
- Fixed a bug where after a fast restart of a full fuzzed corpus afl-fuzz
|
||||
terminates with "need at least one valid input seed that does not crash"
|
||||
- Small improvements to afl-*-config
|
||||
- afl-fuzz:
|
||||
- memory leak fixes by @kcwu - thanks!
|
||||
- some more nits and small memory saves thanks to @kcwu
|
||||
- remove deprecated files from queue/.state
|
||||
- fix bitmap update function if no current trace is present
|
||||
- frida_mode:
|
||||
- fixes for new MacOS + M4 hardware
|
||||
|
||||
|
||||
### Version ++4.31c (release)
|
||||
|
@ -236,7 +236,7 @@ If you find an interesting or important question missing, submit it via
|
||||
[AFLFast](https://github.com/mboehme/aflfast), however, modified to be more
|
||||
effective and several more modes added.
|
||||
|
||||
The most effective modes are `-p fast` (default) and `-p explore`.
|
||||
The most effective modes are `-p explore` (default) and `-p fast`.
|
||||
|
||||
If you fuzz with several parallel afl-fuzz instances, then it is beneficial
|
||||
to assign a different schedule to each instance, however the majority should
|
||||
|
@ -385,10 +385,6 @@ there are several things to look at:
|
||||
subsequent iterations (e.g., due to incomplete clean-up or reinitialization of
|
||||
the state) and that most of the fuzzing effort goes to waste.
|
||||
|
||||
The paths where variable behavior is detected are marked with a matching entry
|
||||
in the `<out_dir>/queue/.state/variable_behavior/` directory, so you can look
|
||||
them up easily.
|
||||
|
||||
### CPU load
|
||||
|
||||
```
|
||||
|
@ -247,6 +247,12 @@ CFISAN. You might need to experiment which sanitizers you can combine in a
|
||||
target (which means more instances can be run without a sanitized target, which
|
||||
is more effective).
|
||||
|
||||
Note that some sanitizers (MSAN and LSAN) exit with a particular exit code
|
||||
instead of aborting. afl-fuzz treats these exit codes as a crash when these
|
||||
sanitizers are enabled. If the target uses these exit codes there could be false
|
||||
positives among the saved crashes. LSAN uses exit code 23 and MSAN uses exit
|
||||
code 86.
|
||||
|
||||
### d) Modifying the target
|
||||
|
||||
If the target has features that make fuzzing more difficult, e.g., checksums,
|
||||
@ -496,6 +502,8 @@ Note:
|
||||
protection against attacks! So set strong firewall rules and only expose SSH
|
||||
as a network service if you use these (which is highly recommended).
|
||||
|
||||
If you execute afl-fuzz in a Docker container, it is recommended to pass [`--cpuset-cpus`](https://docs.docker.com/engine/containers/resource_constraints/#configure-the-default-cfs-scheduler) option with free CPU cores to docker daemon when starting the container, or pass `AFL_NO_AFFINITY` to afl-fuzz. This is due to the fact that AFL++ will bind to a free CPU core by default, while Docker container will prevent AFL++ instance from seeing processes in other containers or host, which leads to all AFL++ instances trying to bind the same CPU core.
|
||||
|
||||
If you have an input corpus from [step 2](#2-preparing-the-fuzzing-campaign),
|
||||
then specify this directory with the `-i` option. Otherwise, create a new
|
||||
directory and create a file with any content as test data in there.
|
||||
|
@ -190,12 +190,25 @@ GUM_DEVKIT_VERSION=16.1.11
|
||||
GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.xz
|
||||
GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)"
|
||||
|
||||
ifeq ($(OS),macos)
|
||||
# Extract the major version
|
||||
GUM_VERSION_MAJOR := $(shell echo "$(GUM_DEVKIT_VERSION)" | sed -E 's/\..*//')
|
||||
# Extract the minor version (assumes format "MAJOR.MINOR[.PATCH...]")
|
||||
GUM_VERSION_MINOR := $(shell echo "$(GUM_DEVKIT_VERSION)" | sed -E 's/^[^.]*\.//; s/\..*//')
|
||||
|
||||
# Evaluate the version condition in a separate shell call
|
||||
IS_GUM_16_6_PLUS := $(shell \
|
||||
if (( $(GUM_VERSION_MAJOR) > 16 || ( $(GUM_VERSION_MAJOR) == 16 && $(GUM_VERSION_MINOR) >= 6 ) )); then \
|
||||
echo 1; \
|
||||
fi)
|
||||
else
|
||||
IS_GUM_16_6_PLUS := $(shell VERSION="$(GUM_DEVKIT_VERSION)"; \
|
||||
MAJOR=$${VERSION%%.*}; \
|
||||
MINOR=$${VERSION#*.}; MINOR=$${MINOR%%.*}; \
|
||||
if [ $$MAJOR -gt 16 ] || { [ $$MAJOR -eq 16 ] && [ $$MINOR -ge 6 ]; }; then \
|
||||
echo 1; \
|
||||
fi)
|
||||
endif
|
||||
|
||||
CFLAGS += $(if $(IS_GUM_16_6_PLUS),-DGUM_16_6_PLUS)
|
||||
|
||||
|
@ -28,8 +28,7 @@ void asan_init(void) {
|
||||
}
|
||||
|
||||
#ifdef GUM_16_6_PLUS
|
||||
static gboolean asan_exclude_module(GumModule *module,
|
||||
gpointer user_data) {
|
||||
static gboolean asan_exclude_module(GumModule *module, gpointer user_data) {
|
||||
|
||||
gchar *symbol_name = (gchar *)user_data;
|
||||
GumAddress address;
|
||||
@ -41,14 +40,13 @@ static gboolean asan_exclude_module(GumModule *module,
|
||||
/* If the reported address of the symbol is outside of the range of the module
|
||||
* then ignore it */
|
||||
if (address < range->base_address) { return TRUE; }
|
||||
if (address > (range->base_address + range->size)) {
|
||||
return TRUE;
|
||||
}
|
||||
if (address > (range->base_address + range->size)) { return TRUE; }
|
||||
|
||||
ranges_add_exclude((GumMemoryRange *)range);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
static gboolean asan_exclude_module(const GumModuleDetails *details,
|
||||
gpointer user_data) {
|
||||
@ -72,6 +70,7 @@ static gboolean asan_exclude_module(const GumModuleDetails *details,
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void asan_exclude_module_by_symbol(gchar *symbol_name) {
|
||||
@ -79,3 +78,4 @@ void asan_exclude_module_by_symbol(gchar *symbol_name) {
|
||||
gum_process_enumerate_modules(asan_exclude_module, symbol_name);
|
||||
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,7 @@ static guint64 text_base = 0;
|
||||
static guint64 text_limit = 0;
|
||||
|
||||
#ifdef GUM_16_6_PLUS
|
||||
static gboolean lib_find_exe(GumModule *module,
|
||||
gpointer user_data) {
|
||||
static gboolean lib_find_exe(GumModule *module, gpointer user_data) {
|
||||
|
||||
lib_details_t *lib_details = (lib_details_t *)user_data;
|
||||
const gchar *name = gum_module_get_name(module);
|
||||
@ -57,6 +56,7 @@ static gboolean lib_find_exe(GumModule *module,
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
static gboolean lib_find_exe(const GumModuleDetails *details,
|
||||
gpointer user_data) {
|
||||
@ -72,6 +72,7 @@ static gboolean lib_find_exe(const GumModuleDetails *details,
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void lib_validate_hdr(Elf_Ehdr *hdr) {
|
||||
@ -210,3 +211,4 @@ guint64 lib_get_text_limit(void) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -13,15 +13,14 @@ static guint64 text_base = 0;
|
||||
static guint64 text_limit = 0;
|
||||
|
||||
#ifdef GUM_16_6_PLUS
|
||||
static gboolean lib_get_main_module(GumModule *module,
|
||||
gpointer user_data) {
|
||||
static gboolean lib_get_main_module(GumModule *module, gpointer user_data) {
|
||||
|
||||
GumDarwinModule **ret = (GumDarwinModule **)user_data;
|
||||
const gchar *path = gum_module_get_path(module);
|
||||
const GumMemoryRange *range = gum_module_get_range(module);
|
||||
GumDarwinModule *darwin_module = gum_darwin_module_new_from_memory(
|
||||
path, mach_task_self(), range->base_address,
|
||||
GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
|
||||
path, mach_task_self(), range->base_address, GUM_DARWIN_MODULE_FLAGS_NONE,
|
||||
NULL);
|
||||
|
||||
FVERBOSE("Found main module: %s", darwin_module->name);
|
||||
|
||||
@ -30,6 +29,7 @@ static gboolean lib_get_main_module(GumModule *module,
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
static gboolean lib_get_main_module(const GumModuleDetails *details,
|
||||
gpointer user_data) {
|
||||
@ -46,6 +46,7 @@ static gboolean lib_get_main_module(const GumModuleDetails *details,
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
gboolean lib_get_text_section(const GumDarwinSectionDetails *details,
|
||||
@ -105,3 +106,4 @@ guint64 lib_get_text_limit(void) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -262,6 +262,7 @@ static int prefetch_on_fork(void) {
|
||||
}
|
||||
|
||||
static void prefetch_hook_fork(void) {
|
||||
|
||||
#ifdef GUM_16_6_PLUS
|
||||
void *fork_addr =
|
||||
GSIZE_TO_POINTER(gum_module_find_global_export_by_name("fork"));
|
||||
@ -305,3 +306,4 @@ void prefetch_init(void) {
|
||||
iface->notify_backpatch = gum_afl_stalker_backpatcher_notify;
|
||||
|
||||
}
|
||||
|
||||
|
@ -129,14 +129,15 @@ static gboolean convert_name_token_for_module(GumModule *module,
|
||||
|
||||
FVERBOSE("Found module - prefix: %s, 0x%016" G_GINT64_MODIFIER
|
||||
"x-0x%016" G_GINT64_MODIFIER "x %s",
|
||||
ctx->suffix, range->base_address,
|
||||
range->base_address + range->size, path);
|
||||
ctx->suffix, range->base_address, range->base_address + range->size,
|
||||
path);
|
||||
|
||||
*ctx->range = *range;
|
||||
ctx->done = true;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
static gboolean convert_name_token_for_module(const GumModuleDetails *details,
|
||||
gpointer user_data) {
|
||||
@ -156,6 +157,7 @@ static gboolean convert_name_token_for_module(const GumModuleDetails *details,
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void convert_name_token(gchar *token, GumMemoryRange *range) {
|
||||
@ -736,3 +738,4 @@ void ranges_exclude() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -353,6 +353,8 @@ enum {
|
||||
|
||||
};
|
||||
|
||||
#define FAST_RESUME_VERSION 0x01000000
|
||||
|
||||
/* Python stuff */
|
||||
#ifdef USE_PYTHON
|
||||
|
||||
@ -719,6 +721,8 @@ typedef struct afl_state {
|
||||
|
||||
struct queue_entry **top_rated; /* Top entries for bitmap bytes */
|
||||
|
||||
u32 **top_rated_candidates; /* Candidate IDs per bitmap index */
|
||||
|
||||
struct extra_data *extras; /* Extra tokens to fuzz with */
|
||||
u32 extras_cnt; /* Total number of tokens read */
|
||||
|
||||
@ -860,6 +864,8 @@ typedef struct afl_state {
|
||||
|
||||
struct skipdet_global *skipdet_g;
|
||||
|
||||
s64 last_scored_idx; /* Index of the last queue entry re-scored */
|
||||
|
||||
#ifdef INTROSPECTION
|
||||
char mutation[8072];
|
||||
char m_tmp[4096];
|
||||
@ -1182,13 +1188,13 @@ void deinit_py(void *);
|
||||
/* Queue */
|
||||
|
||||
void mark_as_det_done(afl_state_t *, struct queue_entry *);
|
||||
void mark_as_variable(afl_state_t *, struct queue_entry *);
|
||||
void mark_as_redundant(afl_state_t *, struct queue_entry *, u8);
|
||||
void add_to_queue(afl_state_t *, u8 *, u32, u8);
|
||||
void destroy_queue(afl_state_t *);
|
||||
void update_bitmap_score(afl_state_t *, struct queue_entry *);
|
||||
void update_bitmap_score(afl_state_t *, struct queue_entry *, bool);
|
||||
void cull_queue(afl_state_t *);
|
||||
u32 calculate_score(afl_state_t *, struct queue_entry *);
|
||||
void recalculate_all_scores(afl_state_t *);
|
||||
void update_bitmap_rescore(afl_state_t *, struct queue_entry *, u32);
|
||||
|
||||
/* Bitmap */
|
||||
|
||||
@ -1338,7 +1344,6 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
||||
|
||||
ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed),
|
||||
"/dev/urandom");
|
||||
// srandom(afl->rand_seed[0]);
|
||||
afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG);
|
||||
|
||||
}
|
||||
@ -1452,6 +1457,18 @@ static inline int permissive_create(afl_state_t *afl, const char *fn) {
|
||||
|
||||
}
|
||||
|
||||
static inline void bitmap_set(u8 *map, u32 index) {
|
||||
|
||||
map[index / 8] |= (1u << (index % 8));
|
||||
|
||||
}
|
||||
|
||||
static inline u8 bitmap_read(u8 *map, u32 index) {
|
||||
|
||||
return (map[index / 8] >> (index % 8)) & 1;
|
||||
|
||||
}
|
||||
|
||||
#if TESTCASE_CACHE == 1
|
||||
#error define of TESTCASE_CACHE must be zero or larger than 1
|
||||
#endif
|
||||
|
@ -31,7 +31,8 @@ int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) {
|
||||
if (__cmd == IPC_RMID) {
|
||||
|
||||
int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
|
||||
struct ashmem_pin pin = {0, length};
|
||||
unsigned int safe_length = length >= 0 ? length : 0;
|
||||
struct ashmem_pin pin = {0, safe_length};
|
||||
ret = ioctl(__shmid, ASHMEM_UNPIN, &pin);
|
||||
close(__shmid);
|
||||
|
||||
|
@ -37,11 +37,12 @@
|
||||
|
||||
enum SanitizerAbstraction {
|
||||
|
||||
SIMPLIFY_TRACE = 0, // Feed all unique trace to sanitizers, the
|
||||
// most sensitive
|
||||
UNIQUE_TRACE,
|
||||
SIMPLIFY_TRACE = 0, // Feed all simplified trace to sanitizers, moderate
|
||||
// sensitive and default for SAND. Not missing bugs.
|
||||
UNIQUE_TRACE, // Feed all unique trace to sanitizers, the most sensitive
|
||||
// and not missing bugs.
|
||||
COVERAGE_INCREASE // Feed all coverage increasing cases to sanitizers, the
|
||||
// least sensitive
|
||||
// least sensitive at a risk of missing ~20% bugs.
|
||||
|
||||
};
|
||||
|
||||
|
@ -171,7 +171,8 @@
|
||||
#define EXEC_TM_ROUND 20U
|
||||
|
||||
/* 64bit arch MACRO */
|
||||
#if (defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__))
|
||||
#if (defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__) || \
|
||||
(defined(__riscv) && __riscv_xlen == 64))
|
||||
#define WORD_SIZE_64 1
|
||||
#endif
|
||||
|
||||
@ -200,8 +201,8 @@
|
||||
|
||||
/* Maximum number of unique hangs or crashes to record: */
|
||||
|
||||
#define KEEP_UNIQUE_HANG 500U
|
||||
#define KEEP_UNIQUE_CRASH 10000U
|
||||
#define KEEP_UNIQUE_HANG 512U
|
||||
#define KEEP_UNIQUE_CRASH 25600U
|
||||
|
||||
/* Baseline number of random tweaks during a single 'havoc' stage: */
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
u32 skim(const u32 *virgin, const u32 *current, const u32 *current_end);
|
||||
u32 classify_word(u32 word);
|
||||
void classify_counts_mem(u32 *mem, u32 size);
|
||||
|
||||
inline u32 classify_word(u32 word) {
|
||||
|
||||
@ -24,22 +23,6 @@ inline u32 classify_word(u32 word) {
|
||||
|
||||
}
|
||||
|
||||
inline void classify_counts_mem(u32 *mem, u32 size) {
|
||||
|
||||
u32 i = (size >> 2);
|
||||
|
||||
while (i--) {
|
||||
|
||||
/* Optimize for sparse bitmaps. */
|
||||
|
||||
if (unlikely(*mem)) { *mem = classify_word(*mem); }
|
||||
|
||||
mem++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void simplify_trace(afl_state_t *afl, u8 *bytes) {
|
||||
|
||||
u32 *mem = (u32 *)bytes;
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
u32 skim(const u64 *virgin, const u64 *current, const u64 *current_end);
|
||||
u64 classify_word(u64 word);
|
||||
void classify_counts_mem(u64 *mem, u32 size);
|
||||
|
||||
inline u64 classify_word(u64 word) {
|
||||
|
||||
@ -79,22 +78,6 @@ inline void classify_counts(afl_forkserver_t *fsrv) {
|
||||
|
||||
}
|
||||
|
||||
inline void classify_counts_mem(u64 *mem, u32 size) {
|
||||
|
||||
u32 i = (size >> 3);
|
||||
|
||||
while (i--) {
|
||||
|
||||
/* Optimize for sparse bitmaps. */
|
||||
|
||||
if (unlikely(*mem)) { *mem = classify_word(*mem); }
|
||||
|
||||
mem++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Updates the virgin bits, then reflects whether a new count or a new tuple is
|
||||
* seen in ret. */
|
||||
inline void discover_word(u8 *ret, u64 *current, u64 *virgin) {
|
||||
|
@ -137,6 +137,8 @@ typedef struct afl_forkserver {
|
||||
|
||||
u8 last_kill_signal; /* Signal that killed the child */
|
||||
|
||||
u8 last_exit_code; /* Child exit code if counted as a crash */
|
||||
|
||||
bool use_shmem_fuzz; /* use shared mem for test cases */
|
||||
|
||||
bool support_shmem_fuzz; /* set by afl-fuzz */
|
||||
@ -155,7 +157,7 @@ typedef struct afl_forkserver {
|
||||
|
||||
bool no_unlink; /* do not unlink cur_input */
|
||||
|
||||
bool uses_asan; /* Target uses ASAN? */
|
||||
u8 uses_asan; /* Target uses ASAN/LSAN/MSAN? (bit 0/1/2 respectively) */
|
||||
|
||||
bool debug; /* debug mode? */
|
||||
|
||||
|
@ -3169,7 +3169,7 @@ static xxh_u32 XXH32_avalanche(xxh_u32 hash) {
|
||||
*/
|
||||
static XXH_PUREF xxh_u32 XXH32_finalize(xxh_u32 hash, const xxh_u8 *ptr,
|
||||
size_t len, XXH_alignment align) {
|
||||
\
|
||||
|
||||
#define XXH_PROCESS1 \
|
||||
do { \
|
||||
\
|
||||
|
@ -40,7 +40,7 @@ ALPINE_ROOT=<your-alpine-sysroot-directory>
|
||||
FUZZ=<your-path-to-the-code>
|
||||
sudo systemd-nspawn -D $ALPINE_ROOT --bind=$FUZZ:/fuzz
|
||||
CC=$(which clang) CFLAGS="-g" LDSHARED="clang -shared" python3 -m pip install /fuzz
|
||||
clang $(python3-config --embed --cflags) $(python3-config --embed --ldflags) -o /fuzz/fuzz_harness /fuzz/fuzz_harness.c
|
||||
clang $(python3-config --embed --cflags) -o /fuzz/fuzz_harness /fuzz/fuzz_harness.c $(python3-config --embed --ldflags)
|
||||
exit
|
||||
```
|
||||
|
||||
|
@ -187,9 +187,6 @@ typedef struct aflcc_state {
|
||||
u8 need_aflpplib;
|
||||
int passthrough;
|
||||
|
||||
u8 use_stdin; /* dummy */
|
||||
u8 *argvnull; /* dummy */
|
||||
|
||||
} aflcc_state_t;
|
||||
|
||||
void aflcc_state_init(aflcc_state_t *, u8 *argv0);
|
||||
@ -2033,8 +2030,10 @@ void add_sanitizers(aflcc_state_t *aflcc, char **envp) {
|
||||
}
|
||||
|
||||
if (getenv("AFL_USE_RTSAN") && !aflcc->have_rtsan) {
|
||||
|
||||
insert_param(aflcc, "-fsanitize=realtime");
|
||||
aflcc->have_rtsan = 1;
|
||||
|
||||
}
|
||||
|
||||
if (getenv("AFL_USE_CFISAN") || aflcc->have_cfisan) {
|
||||
|
@ -978,10 +978,9 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) {
|
||||
inline u64 get_cur_time(void) {
|
||||
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
// TO NOT REPLACE WITH clock_gettime!!!
|
||||
gettimeofday(&tv, &tz);
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);
|
||||
|
||||
@ -992,10 +991,9 @@ inline u64 get_cur_time(void) {
|
||||
inline u64 get_cur_time_us(void) {
|
||||
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
// TO NOT REPLACE WITH clock_gettime!!!
|
||||
gettimeofday(&tv, &tz);
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
return (tv.tv_sec * 1000000ULL) + tv.tv_usec;
|
||||
|
||||
@ -1006,7 +1004,7 @@ inline u64 get_cur_time_us(void) {
|
||||
Will return buf for convenience. */
|
||||
|
||||
u8 *stringify_int(u8 *buf, size_t len, u64 val) {
|
||||
\
|
||||
|
||||
#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
|
||||
do { \
|
||||
\
|
||||
@ -1170,7 +1168,7 @@ u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms) {
|
||||
Will return buf for convenience. */
|
||||
|
||||
u8 *u_stringify_int(u8 *buf, u64 val) {
|
||||
\
|
||||
|
||||
#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) \
|
||||
do { \
|
||||
\
|
||||
|
@ -258,7 +258,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
|
||||
fsrv->last_run_timed_out = false;
|
||||
fsrv->debug = false;
|
||||
fsrv->uses_crash_exitcode = false;
|
||||
fsrv->uses_asan = false;
|
||||
fsrv->uses_asan = 0;
|
||||
|
||||
#ifdef __AFL_CODE_COVERAGE
|
||||
fsrv->persistent_trace_bits = NULL;
|
||||
@ -2087,17 +2087,19 @@ fsrv_run_result_t __attribute__((hot)) afl_fsrv_run_target(
|
||||
|
||||
/* Did we crash?
|
||||
In a normal case, (abort) WIFSIGNALED(child_status) will be set.
|
||||
MSAN in uses_asan mode uses a special exit code as it doesn't support
|
||||
MSAN & LSAN in uses_asan mode use special exit codes as they doesn't support
|
||||
abort_on_error. On top, a user may specify a custom AFL_CRASH_EXITCODE.
|
||||
Handle all three cases here. */
|
||||
Handle all four cases here. */
|
||||
|
||||
if (unlikely(
|
||||
/* A normal crash/abort */
|
||||
(WIFSIGNALED(fsrv->child_status)) ||
|
||||
/* special handling for msan and lsan */
|
||||
(fsrv->uses_asan &&
|
||||
(WEXITSTATUS(fsrv->child_status) == MSAN_ERROR ||
|
||||
WEXITSTATUS(fsrv->child_status) == LSAN_ERROR)) ||
|
||||
/* special handling for msan */
|
||||
((fsrv->uses_asan & 4) &&
|
||||
WEXITSTATUS(fsrv->child_status) == MSAN_ERROR) ||
|
||||
/* special handling for lsan */
|
||||
((fsrv->uses_asan & 2) &&
|
||||
WEXITSTATUS(fsrv->child_status) == LSAN_ERROR) ||
|
||||
/* the custom crash_exitcode was returned by the target */
|
||||
(fsrv->uses_crash_exitcode &&
|
||||
WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) {
|
||||
@ -2106,6 +2108,10 @@ fsrv_run_result_t __attribute__((hot)) afl_fsrv_run_target(
|
||||
fsrv->last_kill_signal =
|
||||
WIFSIGNALED(fsrv->child_status) ? WTERMSIG(fsrv->child_status) : 0;
|
||||
|
||||
/* For a special exit code, set last_exit_code to non-zero */
|
||||
fsrv->last_exit_code =
|
||||
WIFSIGNALED(fsrv->child_status) ? 0 : WEXITSTATUS(fsrv->child_status);
|
||||
|
||||
#ifdef AFL_PERSISTENT_RECORD
|
||||
if (unlikely(fsrv->persistent_record)) {
|
||||
|
||||
|
@ -462,18 +462,6 @@ void write_crash_readme(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
static inline void bitmap_set(u8 *map, u32 index) {
|
||||
|
||||
map[index / 8] |= (1u << (index % 8));
|
||||
|
||||
}
|
||||
|
||||
static inline u8 bitmap_read(u8 *map, u32 index) {
|
||||
|
||||
return (map[index / 8] >> (index % 8)) & 1;
|
||||
|
||||
}
|
||||
|
||||
/* Check if the result of an execve() during routine fuzzing is interesting,
|
||||
save or queue the input test case for further analysis if so. Returns 1 if
|
||||
entry is saved, 0 otherwise. */
|
||||
@ -481,6 +469,8 @@ static inline u8 bitmap_read(u8 *map, u32 index) {
|
||||
u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
u32 len, u8 fault) {
|
||||
|
||||
u8 classified = 0;
|
||||
|
||||
if (unlikely(len == 0)) { return 0; }
|
||||
|
||||
if (unlikely(fault == FSRV_RUN_TMOUT && afl->afl_env.afl_ignore_timeouts)) {
|
||||
@ -489,6 +479,7 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
|
||||
classify_counts(&afl->fsrv);
|
||||
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
classified = 1;
|
||||
|
||||
// Saturated increment
|
||||
if (likely(afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF))
|
||||
@ -502,8 +493,7 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
|
||||
u8 fn[PATH_MAX];
|
||||
u8 *queue_fn = "";
|
||||
u8 new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0,
|
||||
need_hash = 1;
|
||||
u8 new_bits = 0, keeping = 0, res, is_timeout = 0, need_hash = 1;
|
||||
s32 fd;
|
||||
u64 cksum = 0;
|
||||
u32 cksum_simplified = 0, cksum_unique = 0;
|
||||
@ -520,7 +510,6 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
|
||||
|
||||
classify_counts(&afl->fsrv);
|
||||
classified = 1;
|
||||
need_hash = 0;
|
||||
|
||||
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
@ -539,8 +528,6 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
|
||||
memcpy(afl->san_fsrvs[0].trace_bits, afl->fsrv.trace_bits,
|
||||
afl->fsrv.map_size);
|
||||
classify_counts_mem((_AFL_INTSIZEVAR *)afl->san_fsrvs[0].trace_bits,
|
||||
afl->fsrv.map_size);
|
||||
simplify_trace(afl, afl->san_fsrvs[0].trace_bits);
|
||||
|
||||
// Note: Original SAND implementation used XXHASH32
|
||||
@ -569,6 +556,16 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
if (unlikely(afl->san_binary_length) &&
|
||||
likely(afl->san_abstraction == UNIQUE_TRACE)) {
|
||||
|
||||
// If schedule is not FAST..RARE, we need to classify counts here
|
||||
// Note: SAND was evaluated under FAST schedule but should also work
|
||||
// with other scedules.
|
||||
if (!classified) {
|
||||
|
||||
classify_counts(&afl->fsrv);
|
||||
classified = 1;
|
||||
|
||||
}
|
||||
|
||||
cksum_unique =
|
||||
hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
if (unlikely(!bitmap_read(afl->n_fuzz_dup, cksum) &&
|
||||
@ -631,10 +628,19 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
|
||||
/* If we are in coverage increasing abstraction and have fed input to
|
||||
sanitizers, we are sure it has new bits.*/
|
||||
if (classified) {
|
||||
|
||||
/* We could have classified the bits in SAND with UNIQUE_TRACE */
|
||||
new_bits = has_new_bits(afl, afl->virgin_bits);
|
||||
|
||||
} else {
|
||||
|
||||
new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (likely(!new_bits)) {
|
||||
|
||||
if (san_fault == FSRV_RUN_OK) {
|
||||
@ -646,7 +652,6 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
|
||||
afl->san_case_status |= NON_COV_INCREASE_BUG;
|
||||
fault = san_fault;
|
||||
classified = new_bits;
|
||||
goto may_save_fault;
|
||||
|
||||
}
|
||||
@ -654,7 +659,6 @@ u8 __attribute__((hot)) save_if_interesting(afl_state_t *afl, void *mem,
|
||||
}
|
||||
|
||||
fault = san_fault;
|
||||
classified = new_bits;
|
||||
|
||||
save_to_queue:
|
||||
|
||||
@ -799,13 +803,6 @@ may_save_fault:
|
||||
|
||||
if (likely(!afl->non_instrumented_mode)) {
|
||||
|
||||
if (unlikely(!classified)) {
|
||||
|
||||
classify_counts(&afl->fsrv);
|
||||
classified = 1;
|
||||
|
||||
}
|
||||
|
||||
simplify_trace(afl, afl->fsrv.trace_bits);
|
||||
|
||||
if (!has_new_bits(afl, afl->virgin_tmout)) { return keeping; }
|
||||
@ -939,13 +936,6 @@ may_save_fault:
|
||||
|
||||
if (likely(!afl->non_instrumented_mode)) {
|
||||
|
||||
if (unlikely(!classified)) {
|
||||
|
||||
classify_counts(&afl->fsrv);
|
||||
classified = 1;
|
||||
|
||||
}
|
||||
|
||||
simplify_trace(afl, afl->fsrv.trace_bits);
|
||||
|
||||
if (!has_new_bits(afl, afl->virgin_crash)) { return keeping; }
|
||||
|
@ -354,6 +354,7 @@ void load_extras(afl_state_t *afl, u8 *dir) {
|
||||
"Extra '%s' is too big (%s, limit is %s)", fn,
|
||||
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size),
|
||||
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
||||
ck_free(fn);
|
||||
continue;
|
||||
|
||||
}
|
||||
@ -742,10 +743,8 @@ void save_auto(afl_state_t *afl) {
|
||||
|
||||
for (i = 0; i < MIN((u32)USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) {
|
||||
|
||||
u8 *fn = alloc_printf(
|
||||
"%s/queue/.state/auto_extras/auto_%06u%s%s", afl->out_dir, i,
|
||||
afl->file_extension ? "." : "",
|
||||
afl->file_extension ? (const char *)afl->file_extension : "");
|
||||
u8 *fn =
|
||||
alloc_printf("%s/queue/.state/auto_extras/auto_%06u", afl->out_dir, i);
|
||||
|
||||
s32 fd;
|
||||
|
||||
|
@ -567,6 +567,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
|
||||
|
||||
}
|
||||
|
||||
free(nl);
|
||||
continue;
|
||||
|
||||
}
|
||||
@ -593,6 +594,7 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
|
||||
if (unlikely(lstat(fn2, &st) || access(fn2, R_OK))) {
|
||||
|
||||
if (first) PFATAL("Unable to access '%s'", fn2);
|
||||
ck_free(fn2);
|
||||
continue;
|
||||
|
||||
}
|
||||
@ -634,19 +636,16 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
|
||||
// as this could add duplicates of the startup input corpus
|
||||
|
||||
int fd = open(fn2, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
|
||||
ck_free(fn2);
|
||||
continue;
|
||||
|
||||
}
|
||||
if (fd < 0) { continue; }
|
||||
|
||||
u8 fault;
|
||||
u8 *mem = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
|
||||
if (mem == MAP_FAILED) {
|
||||
|
||||
ck_free(fn2);
|
||||
close(fd);
|
||||
continue;
|
||||
|
||||
}
|
||||
@ -668,7 +667,12 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
|
||||
|
||||
}
|
||||
|
||||
if (mtime_max > afl->foreign_syncs[iter].mtime) {
|
||||
|
||||
afl->foreign_syncs[iter].mtime = mtime_max;
|
||||
|
||||
}
|
||||
|
||||
free(nl); /* not tracked */
|
||||
|
||||
}
|
||||
@ -749,8 +753,6 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
|
||||
|
||||
}
|
||||
|
||||
// if (getenv("MYTEST")) afl->in_place_resume = 1;
|
||||
|
||||
if (nl_cnt) {
|
||||
|
||||
u32 done = 0;
|
||||
@ -1042,6 +1044,47 @@ void perform_dry_run(afl_state_t *afl) {
|
||||
|
||||
if (afl->crash_mode) { break; }
|
||||
|
||||
const u8 *msg_exit_code = "";
|
||||
|
||||
if (afl->fsrv.uses_asan && !afl->fsrv.last_kill_signal) {
|
||||
|
||||
if ((afl->fsrv.uses_asan & 4) &&
|
||||
afl->fsrv.last_exit_code == MSAN_ERROR) {
|
||||
|
||||
msg_exit_code =
|
||||
" - The test case terminated with the exit code that is "
|
||||
"used by MSAN to\n"
|
||||
" indicate an error. This is counted as a crash by "
|
||||
"afl-fuzz because you\n"
|
||||
" have compiled the target with MSAN enabled. This could "
|
||||
"be a false\n"
|
||||
" positive if the program returns this exit code under "
|
||||
"normal operation.\n"
|
||||
" In that case, either disable MSAN or change the test "
|
||||
"case or program\n"
|
||||
" to avoid generating this exit code.\n\n";
|
||||
|
||||
} else if ((afl->fsrv.uses_asan & 2) &&
|
||||
|
||||
afl->fsrv.last_exit_code == LSAN_ERROR) {
|
||||
|
||||
msg_exit_code =
|
||||
" - The test case terminated with the exit code that is "
|
||||
"used by LSAN to\n"
|
||||
" indicate an error. This is counted as a crash by "
|
||||
"afl-fuzz because you\n"
|
||||
" have compiled the target with LSAN enabled. This could "
|
||||
"be a false\n"
|
||||
" positive if the program returns this exit code under "
|
||||
"normal operation.\n"
|
||||
" In that case, either disable LSAN or change the test "
|
||||
"case or program\n"
|
||||
" to avoid generating this exit code.\n\n";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (afl->fsrv.mem_limit) {
|
||||
|
||||
u8 val_buf[STRINGIFY_VAL_SIZE_MAX];
|
||||
@ -1056,6 +1099,7 @@ void perform_dry_run(afl_state_t *afl) {
|
||||
" so, please remove it. The fuzzer should be seeded with "
|
||||
"interesting\n"
|
||||
" inputs - but not ones that cause an outright crash.\n\n"
|
||||
"%s"
|
||||
|
||||
" - The current memory limit (%s) is too low for this "
|
||||
"program, causing\n"
|
||||
@ -1085,6 +1129,7 @@ void perform_dry_run(afl_state_t *afl) {
|
||||
"other options\n"
|
||||
" fail, poke the Awesome Fuzzing Discord for "
|
||||
"troubleshooting tips.\n",
|
||||
msg_exit_code,
|
||||
stringify_mem_size(val_buf, sizeof(val_buf),
|
||||
afl->fsrv.mem_limit << 20),
|
||||
afl->fsrv.mem_limit - 1);
|
||||
@ -1101,6 +1146,7 @@ void perform_dry_run(afl_state_t *afl) {
|
||||
" so, please remove it. The fuzzer should be seeded with "
|
||||
"interesting\n"
|
||||
" inputs - but not ones that cause an outright crash.\n\n"
|
||||
"%s"
|
||||
|
||||
" - In QEMU persistent mode the selected address(es) for the "
|
||||
"loop are not\n"
|
||||
@ -1113,7 +1159,8 @@ void perform_dry_run(afl_state_t *afl) {
|
||||
" - Least likely, there is a horrible bug in the fuzzer. If "
|
||||
"other options\n"
|
||||
" fail, poke the Awesome Fuzzing Discord for "
|
||||
"troubleshooting tips.\n");
|
||||
"troubleshooting tips.\n",
|
||||
msg_exit_code);
|
||||
|
||||
}
|
||||
|
||||
@ -2180,10 +2227,17 @@ int check_main_node_exists(afl_state_t *afl) {
|
||||
fn = alloc_printf("%s/%s/is_main_node", afl->sync_dir, sd_ent->d_name);
|
||||
int res = access(fn, F_OK);
|
||||
free(fn);
|
||||
if (res == 0) return 1;
|
||||
if (res == 0) {
|
||||
|
||||
closedir(sd);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
closedir(sd);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
@ -2267,18 +2321,6 @@ void setup_dirs_fds(afl_state_t *afl) {
|
||||
if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); }
|
||||
ck_free(tmp);
|
||||
|
||||
/* The set of paths currently deemed redundant. */
|
||||
|
||||
tmp = alloc_printf("%s/queue/.state/redundant_edges/", afl->out_dir);
|
||||
if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); }
|
||||
ck_free(tmp);
|
||||
|
||||
/* The set of paths showing variable behavior. */
|
||||
|
||||
tmp = alloc_printf("%s/queue/.state/variable_behavior/", afl->out_dir);
|
||||
if (mkdir(tmp, 0700)) { PFATAL("Unable to create '%s'", tmp); }
|
||||
ck_free(tmp);
|
||||
|
||||
/* Sync directory for keeping track of cooperating fuzzers. */
|
||||
|
||||
if (afl->sync_id) {
|
||||
@ -2601,7 +2643,7 @@ void check_cpu_governor(afl_state_t *afl) {
|
||||
" afl-fuzz. To keep things moving, run these commands as root:\n\n"
|
||||
|
||||
" cd /sys/devices/system/cpu\n"
|
||||
" echo performance | tee cpu*/cpufreq/scaling_governor\n\n"
|
||||
" echo performance | sudo tee cpu*/cpufreq/scaling_governor\n\n"
|
||||
|
||||
" You can later go back to the original state by replacing "
|
||||
"'performance'\n"
|
||||
@ -3118,11 +3160,23 @@ void check_binary(afl_state_t *afl, u8 *fname) {
|
||||
|
||||
}
|
||||
|
||||
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 = 0;
|
||||
|
||||
afl->fsrv.uses_asan = 1;
|
||||
if (afl_memmem(f_data, f_len, "__asan_init", 11)) {
|
||||
|
||||
afl->fsrv.uses_asan |= 1;
|
||||
|
||||
}
|
||||
|
||||
if (afl_memmem(f_data, f_len, "__lsan_init", 11)) {
|
||||
|
||||
afl->fsrv.uses_asan |= 2;
|
||||
|
||||
}
|
||||
|
||||
if (afl_memmem(f_data, f_len, "__msan_init", 11)) {
|
||||
|
||||
afl->fsrv.uses_asan |= 4;
|
||||
|
||||
}
|
||||
|
||||
|
@ -636,7 +636,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
||||
q->len = out_len;
|
||||
|
||||
memcpy(afl->fsrv.trace_bits, afl->clean_trace_custom, afl->fsrv.map_size);
|
||||
update_bitmap_score(afl, q);
|
||||
update_bitmap_score(afl, q, true);
|
||||
|
||||
}
|
||||
|
||||
|
@ -634,7 +634,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
afl->stage_cur_byte = afl->stage_cur >> 3;
|
||||
|
||||
if (!skip_eff_map[afl->stage_cur_byte]) continue;
|
||||
if (!bitmap_read(skip_eff_map, afl->stage_cur_byte)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -754,7 +754,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
afl->stage_cur_byte = afl->stage_cur >> 3;
|
||||
|
||||
if (!skip_eff_map[afl->stage_cur_byte]) continue;
|
||||
if (!bitmap_read(skip_eff_map, afl->stage_cur_byte)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -793,7 +793,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
afl->stage_cur_byte = afl->stage_cur >> 3;
|
||||
|
||||
if (!skip_eff_map[afl->stage_cur_byte]) continue;
|
||||
if (!bitmap_read(skip_eff_map, afl->stage_cur_byte)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -837,7 +837,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
afl->stage_cur_byte = afl->stage_cur;
|
||||
|
||||
if (!skip_eff_map[afl->stage_cur_byte]) continue;
|
||||
if (!bitmap_read(skip_eff_map, afl->stage_cur_byte)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -858,7 +858,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
if (skip_eff_map[i]) afl->blocks_eff_select += 1;
|
||||
if (bitmap_read(skip_eff_map, i)) afl->blocks_eff_select += 1;
|
||||
|
||||
}
|
||||
|
||||
@ -887,7 +887,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
/* Let's consult the effector map... */
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -930,7 +930,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
|
||||
|
||||
/* Let's consult the effector map... */
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -983,7 +983,7 @@ skip_bitflip:
|
||||
|
||||
/* Let's consult the effector map... */
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1067,7 +1067,7 @@ skip_bitflip:
|
||||
|
||||
/* Let's consult the effector map... */
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1197,7 +1197,7 @@ skip_bitflip:
|
||||
|
||||
/* Let's consult the effector map... */
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1331,7 +1331,7 @@ skip_arith:
|
||||
|
||||
/* Let's consult the effector map... */
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1391,7 +1391,7 @@ skip_arith:
|
||||
|
||||
/* Let's consult the effector map... */
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1479,7 +1479,7 @@ skip_arith:
|
||||
|
||||
/* Let's consult the effector map... */
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1573,7 +1573,7 @@ skip_interest:
|
||||
|
||||
u32 last_len = 0;
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1642,7 +1642,7 @@ skip_interest:
|
||||
|
||||
for (i = 0; i <= (u32)len; ++i) {
|
||||
|
||||
if (!skip_eff_map[i % len]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i % len)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1708,7 +1708,7 @@ skip_user_extras:
|
||||
|
||||
u32 last_len = 0;
|
||||
|
||||
if (!skip_eff_map[i]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
@ -1768,7 +1768,7 @@ skip_user_extras:
|
||||
|
||||
for (i = 0; i <= (u32)len; ++i) {
|
||||
|
||||
if (!skip_eff_map[i % len]) continue;
|
||||
if (!bitmap_read(skip_eff_map, i % len)) continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 0)) { goto custom_mutator_stage; }
|
||||
|
||||
|
@ -440,30 +440,6 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
}
|
||||
|
||||
/* Mark as variable. Create symlinks if possible to make it easier to examine
|
||||
the files. */
|
||||
|
||||
void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
char fn[PATH_MAX];
|
||||
char ldest[PATH_MAX];
|
||||
|
||||
char *fn_name = strrchr((char *)q->fname, '/') + 1;
|
||||
|
||||
sprintf(ldest, "../../%s", fn_name);
|
||||
sprintf(fn, "%s/queue/.state/variable_behavior/%s", afl->out_dir, fn_name);
|
||||
|
||||
if (symlink(ldest, fn)) {
|
||||
|
||||
s32 fd = permissive_create(afl, fn);
|
||||
if (fd >= 0) { close(fd); }
|
||||
|
||||
}
|
||||
|
||||
q->var_behavior = 1;
|
||||
|
||||
}
|
||||
|
||||
/* Mark / unmark as redundant (edge-only). This is not used for restoring state,
|
||||
but may be useful for post-processing datasets. */
|
||||
|
||||
@ -471,8 +447,6 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
|
||||
|
||||
if (likely(state == q->fs_redundant)) { return; }
|
||||
|
||||
char fn[PATH_MAX];
|
||||
|
||||
q->fs_redundant = state;
|
||||
|
||||
if (likely(q->fs_redundant)) {
|
||||
@ -486,22 +460,9 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
|
||||
|
||||
}
|
||||
|
||||
sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir,
|
||||
strrchr((char *)q->fname, '/') + 1);
|
||||
|
||||
if (state) {
|
||||
|
||||
s32 fd;
|
||||
|
||||
if (unlikely(afl->afl_env.afl_disable_redundant)) { q->disabled = 1; }
|
||||
fd = permissive_create(afl, fn);
|
||||
if (fd >= 0) { close(fd); }
|
||||
|
||||
} else {
|
||||
|
||||
if (unlink(fn)) { /*PFATAL("Unable to remove '%s'", fn);*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -805,6 +766,7 @@ void destroy_queue(afl_state_t *afl) {
|
||||
for (i = 0; i < afl->queued_items; i++) {
|
||||
|
||||
q = afl->queue_buf[i];
|
||||
ck_free(q->testcase_buf);
|
||||
ck_free(q->fname);
|
||||
ck_free(q->trace_mini);
|
||||
if (q->skipdet_e) {
|
||||
@ -833,7 +795,8 @@ void destroy_queue(afl_state_t *afl) {
|
||||
previous contender, or if the contender has a more favorable speed x size
|
||||
factor. */
|
||||
|
||||
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q,
|
||||
bool have_trace) {
|
||||
|
||||
u32 i;
|
||||
u64 fav_factor;
|
||||
@ -863,6 +826,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
}
|
||||
|
||||
if (have_trace) {
|
||||
|
||||
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
|
||||
winner, and how it compares to us. */
|
||||
for (i = 0; i < afl->fsrv.map_size; ++i) {
|
||||
@ -906,7 +871,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
if (likely(fav_factor > top_rated_fav_factor)) { continue; }
|
||||
|
||||
/* Looks like we're going to win. Decrease ref count for the
|
||||
previous winner, discard its afl->fsrv.trace_bits[] if necessary. */
|
||||
previous winner, discard its afl->fsrv.trace_bits[] if necessary.
|
||||
*/
|
||||
|
||||
if (!--afl->top_rated[i]->tc_ref) {
|
||||
|
||||
@ -924,7 +890,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
if (!q->trace_mini) {
|
||||
|
||||
u32 len = (afl->fsrv.map_size >> 3);
|
||||
u32 len = ((afl->fsrv.map_size + 7) >> 3);
|
||||
q->trace_mini = (u8 *)ck_alloc(len);
|
||||
minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits);
|
||||
|
||||
@ -938,6 +904,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* The second part of the mechanism discussed above is a routine that
|
||||
goes over afl->top_rated[] entries, and then sequentially grabs winners for
|
||||
previously-unseen bytes (temp_v) and marks them as favored, at least
|
||||
@ -1025,6 +993,186 @@ void cull_queue(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
/* Re-selects top_rated[] entries based on the current fuzzing schedule.
|
||||
Each queued entry is executed once to collect trace_bits, and potential
|
||||
candidates for each bitmap index are stored.
|
||||
|
||||
The candidate list format is [count][id1][id2]... as a u32 array,
|
||||
where 'count' indicates how many queue IDs hit that index. */
|
||||
|
||||
void recalculate_all_scores(afl_state_t *afl) {
|
||||
|
||||
u8 *in_buf;
|
||||
u32 i;
|
||||
u32 j;
|
||||
|
||||
for (i = afl->last_scored_idx + 1; i < afl->queued_items; i++) {
|
||||
|
||||
if (likely(!afl->queue_buf[i]->disabled)) {
|
||||
|
||||
in_buf = queue_testcase_get(afl, afl->queue_buf[i]);
|
||||
(void)write_to_testcase(afl, (void **)&in_buf, afl->queue_buf[i]->len, 1);
|
||||
(void)fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||
|
||||
for (j = 0; j < afl->fsrv.map_size; ++j) {
|
||||
|
||||
if (afl->fsrv.trace_bits[j]) {
|
||||
|
||||
u32 *candidate_ids = afl->top_rated_candidates[j];
|
||||
u32 id = afl->queue_buf[i]->id;
|
||||
|
||||
if (!candidate_ids) {
|
||||
|
||||
// first candidate: [count][id]
|
||||
candidate_ids = ck_alloc(sizeof(u32) * 2);
|
||||
candidate_ids[0] = 1; // count = 1
|
||||
candidate_ids[1] = id; // first ID
|
||||
|
||||
} else {
|
||||
|
||||
u32 count = candidate_ids[0];
|
||||
|
||||
candidate_ids =
|
||||
ck_realloc(candidate_ids, sizeof(u32) * (count + 2));
|
||||
candidate_ids[0] = count + 1; // increment the count
|
||||
candidate_ids[count + 1] = id; // append the new ID to the end
|
||||
|
||||
// fprintf(stderr, "enroll candidate[%u][%u] %u\n", i, j, id);
|
||||
|
||||
}
|
||||
|
||||
afl->top_rated_candidates[j] = candidate_ids;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
afl->last_scored_idx = i;
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < afl->fsrv.map_size; ++i) {
|
||||
|
||||
u32 *candidate_ids = afl->top_rated_candidates[i];
|
||||
if (candidate_ids) {
|
||||
|
||||
u32 count = candidate_ids[0];
|
||||
|
||||
for (u32 k = 0; k < count; k++) {
|
||||
|
||||
u32 id = candidate_ids[k + 1];
|
||||
struct queue_entry *entry = afl->queue_buf[id];
|
||||
update_bitmap_rescore(afl, entry, i);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Re-evaluates top-rated entries without checking trace_bits.
|
||||
Unlike update_bitmap_score(), this function assumes the trace
|
||||
information is already known and only compares entries */
|
||||
|
||||
void update_bitmap_rescore(afl_state_t *afl, struct queue_entry *q, u32 index) {
|
||||
|
||||
u32 i = index;
|
||||
u64 fav_factor;
|
||||
u64 fuzz_p2;
|
||||
|
||||
if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) {
|
||||
|
||||
fuzz_p2 = 0; // Skip the fuzz_p2 comparison
|
||||
|
||||
} else if (unlikely(afl->schedule == RARE)) {
|
||||
|
||||
fuzz_p2 = next_pow2(afl->n_fuzz[q->n_fuzz_entry]);
|
||||
|
||||
} else {
|
||||
|
||||
fuzz_p2 = q->fuzz_level;
|
||||
|
||||
}
|
||||
|
||||
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
|
||||
|
||||
fav_factor = q->len << 2;
|
||||
|
||||
} else {
|
||||
|
||||
fav_factor = q->exec_us * q->len;
|
||||
|
||||
}
|
||||
|
||||
if (afl->top_rated[i]) {
|
||||
|
||||
/* Faster-executing or smaller test cases are favored. */
|
||||
u64 top_rated_fav_factor;
|
||||
u64 top_rated_fuzz_p2;
|
||||
|
||||
if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) {
|
||||
|
||||
top_rated_fuzz_p2 = 0; // Skip the fuzz_p2 comparison
|
||||
|
||||
} else if (unlikely(afl->schedule == RARE)) {
|
||||
|
||||
top_rated_fuzz_p2 =
|
||||
next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]);
|
||||
|
||||
} else {
|
||||
|
||||
top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
|
||||
|
||||
}
|
||||
|
||||
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
|
||||
|
||||
top_rated_fav_factor = afl->top_rated[i]->len << 2;
|
||||
|
||||
} else {
|
||||
|
||||
top_rated_fav_factor =
|
||||
afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
|
||||
|
||||
}
|
||||
|
||||
if (likely(fuzz_p2 > top_rated_fuzz_p2)) { return; }
|
||||
|
||||
if (likely(fav_factor > top_rated_fav_factor)) { return; }
|
||||
|
||||
/* Looks like we're going to win. Decrease ref count for the
|
||||
previous winner, discard its afl->fsrv.trace_bits[] if necessary. */
|
||||
|
||||
if (!--afl->top_rated[i]->tc_ref) {
|
||||
|
||||
ck_free(afl->top_rated[i]->trace_mini);
|
||||
afl->top_rated[i]->trace_mini = NULL;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Insert ourselves as the new winner. */
|
||||
|
||||
afl->top_rated[i] = q;
|
||||
++q->tc_ref;
|
||||
|
||||
if (!q->trace_mini) {
|
||||
|
||||
u32 len = (afl->fsrv.map_size >> 3);
|
||||
q->trace_mini = (u8 *)ck_alloc(len);
|
||||
minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits);
|
||||
|
||||
}
|
||||
|
||||
afl->score_changed = 1;
|
||||
|
||||
}
|
||||
|
||||
/* Calculate case desirability score to adjust the length of havoc fuzzing.
|
||||
A helper function for fuzz_one(). Maybe some of these constants should
|
||||
go into config.h. */
|
||||
@ -1330,7 +1478,7 @@ inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q,
|
||||
|
||||
// only realloc if necessary or useful
|
||||
// (a custom trim can make the testcase larger)
|
||||
if (unlikely(len > old_len || len < old_len + 1024)) {
|
||||
if (unlikely(len > old_len || len + 1024 < old_len)) {
|
||||
|
||||
afl->q_testcase_cache_size += len - old_len;
|
||||
q->testcase_buf = (u8 *)realloc(q->testcase_buf, len);
|
||||
@ -1364,7 +1512,7 @@ inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q,
|
||||
if (likely(in != q->testcase_buf)) {
|
||||
|
||||
// only realloc if we save memory
|
||||
if (unlikely(len < old_len + 1024)) {
|
||||
if (unlikely(len + 1024 < old_len)) {
|
||||
|
||||
u8 *ptr = (u8 *)realloc(q->testcase_buf, len);
|
||||
|
||||
|
@ -592,11 +592,11 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
||||
// note: from_queue seems to only be set during initialization
|
||||
if (afl->afl_env.afl_no_ui || from_queue) {
|
||||
|
||||
WARNF("instability detected during calibration");
|
||||
WARNF("instability detected during calibration: %s", q->fname);
|
||||
|
||||
} else if (afl->debug) {
|
||||
|
||||
DEBUGF("instability detected during calibration\n");
|
||||
DEBUGF("instability detected during calibration: %s\n", q->fname);
|
||||
|
||||
}
|
||||
|
||||
@ -652,7 +652,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
||||
afl->total_bitmap_size += q->bitmap_size;
|
||||
++afl->total_bitmap_entries;
|
||||
|
||||
update_bitmap_score(afl, q);
|
||||
update_bitmap_score(afl, q, true);
|
||||
|
||||
/* If this case didn't result in new output from the instrumentation, tell
|
||||
parent. This is a non-critical problem, but something to warn the user
|
||||
@ -682,12 +682,7 @@ abort_calibration:
|
||||
|
||||
afl->var_byte_count = count_bytes(afl, afl->var_bytes);
|
||||
|
||||
if (!q->var_behavior) {
|
||||
|
||||
mark_as_variable(afl, q);
|
||||
++afl->queued_variable;
|
||||
|
||||
}
|
||||
if (!q->var_behavior) { ++afl->queued_variable; }
|
||||
|
||||
}
|
||||
|
||||
@ -872,7 +867,14 @@ void sync_fuzzers(afl_state_t *afl) {
|
||||
|
||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||
|
||||
if (afl->stop_soon) { goto close_sync; }
|
||||
if (afl->stop_soon) {
|
||||
|
||||
munmap(mem, st.st_size);
|
||||
close(fd);
|
||||
|
||||
goto close_sync;
|
||||
|
||||
}
|
||||
|
||||
afl->syncing_party = sd_ent->d_name;
|
||||
afl->queued_imported += save_if_interesting(afl, mem, new_len, fault);
|
||||
@ -1166,7 +1168,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
||||
queue_testcase_retake_mem(afl, q, in_buf, q->len, orig_len);
|
||||
|
||||
memcpy(afl->fsrv.trace_bits, afl->clean_trace, afl->fsrv.map_size);
|
||||
update_bitmap_score(afl, q);
|
||||
update_bitmap_score(afl, q, true);
|
||||
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
|
||||
|
||||
flip_range(out_buf, pos, flip_block_size);
|
||||
|
||||
if (common_fuzz_stuff(afl, out_buf, len)) return 0;
|
||||
if (common_fuzz_stuff(afl, out_buf, len)) { return 0; }
|
||||
|
||||
flip_range(out_buf, pos, flip_block_size);
|
||||
|
||||
@ -237,26 +237,26 @@ u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
|
||||
|
||||
if (!skip_eff_map) {
|
||||
|
||||
skip_eff_map = (u8 *)ck_alloc(sizeof(u8) * len);
|
||||
skip_eff_map = (u8 *)ck_alloc(sizeof(u8) * (len + 7) / 8);
|
||||
afl->queue_cur->skipdet_e->skip_eff_map = skip_eff_map;
|
||||
|
||||
} else {
|
||||
|
||||
memset(skip_eff_map, 0, sizeof(u8) * len);
|
||||
memset(skip_eff_map, 0, sizeof(u8) * (len + 7) / 8);
|
||||
|
||||
}
|
||||
|
||||
/* restore the starting point */
|
||||
if (!done_inf_map) {
|
||||
|
||||
done_inf_map = (u8 *)ck_alloc(sizeof(u8) * len);
|
||||
done_inf_map = (u8 *)ck_alloc(sizeof(u8) * (len + 7) / 8);
|
||||
afl->queue_cur->skipdet_e->done_inf_map = done_inf_map;
|
||||
|
||||
} else {
|
||||
|
||||
for (afl->stage_cur = 0; afl->stage_cur < len; afl->stage_cur++) {
|
||||
|
||||
if (done_inf_map[afl->stage_cur] == 0) break;
|
||||
if (bitmap_read(done_inf_map, afl->stage_cur) == 0) break;
|
||||
|
||||
}
|
||||
|
||||
@ -278,7 +278,13 @@ u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
|
||||
non_eff_bytes = (u8 *)ck_alloc(sizeof(u8) * len);
|
||||
|
||||
// clean exec cksum
|
||||
if (common_fuzz_stuff(afl, out_buf, len)) { return 0; }
|
||||
if (common_fuzz_stuff(afl, out_buf, len)) {
|
||||
|
||||
ck_free(non_eff_bytes);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
prev_cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||
|
||||
}
|
||||
@ -294,7 +300,7 @@ u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
|
||||
afl->stage_cur_byte = afl->stage_cur;
|
||||
|
||||
if (!inf_eff_map[afl->stage_cur_byte] ||
|
||||
skip_eff_map[afl->stage_cur_byte])
|
||||
bitmap_read(skip_eff_map, afl->stage_cur_byte))
|
||||
continue;
|
||||
|
||||
if (is_det_timeout(before_det_time, 1)) { goto cleanup_skipdet; }
|
||||
@ -311,7 +317,12 @@ u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
|
||||
|
||||
before_skip_inf = afl->queued_items;
|
||||
|
||||
if (common_fuzz_stuff(afl, out_buf, len)) { return 0; }
|
||||
if (common_fuzz_stuff(afl, out_buf, len)) {
|
||||
|
||||
ck_free(non_eff_bytes);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
out_buf[afl->stage_cur_byte] = orig;
|
||||
|
||||
@ -328,7 +339,7 @@ u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
|
||||
|
||||
if (afl->queued_items != before_skip_inf) {
|
||||
|
||||
skip_eff_map[afl->stage_cur_byte] = 1;
|
||||
bitmap_set(skip_eff_map, afl->stage_cur_byte);
|
||||
afl->queue_cur->skipdet_e->quick_eff_bytes += 1;
|
||||
|
||||
if (afl->stage_max < MAXIMUM_QUICK_EFF_EXECS) { afl->stage_max *= 2; }
|
||||
@ -338,7 +349,7 @@ u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
|
||||
|
||||
}
|
||||
|
||||
done_inf_map[afl->stage_cur_byte] = 1;
|
||||
bitmap_set(done_inf_map, afl->stage_cur_byte);
|
||||
|
||||
}
|
||||
|
||||
@ -364,7 +375,7 @@ cleanup_skipdet:
|
||||
while (i < len) {
|
||||
|
||||
// assume DWORD size, from i - 3 -> i + 3
|
||||
if (skip_eff_map[i]) {
|
||||
if (bitmap_read(skip_eff_map, i)) {
|
||||
|
||||
u32 fill_length = (i + 3 < len) ? 7 : len - i + 2;
|
||||
memset(nearby_bytes + i - 3, 1, fill_length);
|
||||
@ -378,7 +389,7 @@ cleanup_skipdet:
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
if (nearby_bytes[i] && !non_eff_bytes[i]) skip_eff_map[i] = 1;
|
||||
if (nearby_bytes[i] && !non_eff_bytes[i]) bitmap_set(skip_eff_map, i);
|
||||
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
|
||||
afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME * 1000;
|
||||
afl->q_testcase_max_cache_size = TESTCASE_CACHE_SIZE * 1048576UL;
|
||||
afl->q_testcase_max_cache_entries = 64 * 1024;
|
||||
afl->last_scored_idx = -1;
|
||||
|
||||
#ifdef HAVE_AFFINITY
|
||||
afl->cpu_aff = -1; /* Selected CPU core */
|
||||
@ -738,6 +739,21 @@ void afl_state_deinit(afl_state_t *afl) {
|
||||
if (afl->pass_stats) { ck_free(afl->pass_stats); }
|
||||
if (afl->orig_cmp_map) { ck_free(afl->orig_cmp_map); }
|
||||
if (afl->cmplog_binary) { ck_free(afl->cmplog_binary); }
|
||||
if (afl->cycle_schedules) {
|
||||
|
||||
for (u32 i = 0; i < afl->fsrv.map_size; i++) {
|
||||
|
||||
if (afl->top_rated_candidates[i]) {
|
||||
|
||||
ck_free(afl->top_rated_candidates[i]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ck_free(afl->top_rated_candidates);
|
||||
|
||||
}
|
||||
|
||||
afl_free(afl->queue_buf);
|
||||
afl_free(afl->out_buf);
|
||||
@ -746,6 +762,8 @@ void afl_state_deinit(afl_state_t *afl) {
|
||||
afl_free(afl->in_buf);
|
||||
afl_free(afl->in_scratch_buf);
|
||||
afl_free(afl->ex_buf);
|
||||
afl_free(afl->alias_table);
|
||||
afl_free(afl->alias_probability);
|
||||
|
||||
ck_free(afl->virgin_bits);
|
||||
ck_free(afl->virgin_tmout);
|
||||
@ -757,6 +775,11 @@ void afl_state_deinit(afl_state_t *afl) {
|
||||
ck_free(afl->first_trace);
|
||||
ck_free(afl->map_tmp_buf);
|
||||
|
||||
ck_free(afl->skipdet_g->inf_prof);
|
||||
ck_free(afl->skipdet_g->virgin_det_bits);
|
||||
ck_free(afl->skipdet_g);
|
||||
ck_free(afl->havoc_prof);
|
||||
|
||||
list_remove(&afl_states, afl);
|
||||
|
||||
}
|
||||
|
@ -604,6 +604,8 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
|
||||
|
||||
void plot_profile_data(afl_state_t *afl, struct queue_entry *q) {
|
||||
|
||||
if (afl->skip_deterministic) { return; }
|
||||
|
||||
u64 current_ms = get_cur_time() - afl->start_time;
|
||||
|
||||
u32 current_edges = count_non_255_bytes(afl, afl->virgin_bits);
|
||||
|
@ -1750,25 +1750,35 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
}
|
||||
|
||||
if (afl->cycle_schedules) {
|
||||
|
||||
afl->top_rated_candidates = ck_alloc(map_size * sizeof(u32));
|
||||
|
||||
}
|
||||
|
||||
if (afl->san_binary_length) {
|
||||
|
||||
if (afl->san_abstraction == UNIQUE_TRACE) {
|
||||
|
||||
afl->n_fuzz_dup = ck_alloc(N_FUZZ_SIZE_BITMAP * sizeof(u8));
|
||||
|
||||
}
|
||||
|
||||
if (afl->san_abstraction == SIMPLIFY_TRACE) {
|
||||
|
||||
afl->simplified_n_fuzz = ck_alloc(N_FUZZ_SIZE_BITMAP * sizeof(u8));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (get_afl_env("AFL_NO_FORKSRV")) { afl->no_forkserver = 1; }
|
||||
if (get_afl_env("AFL_NO_CPU_RED")) { afl->no_cpu_meter_red = 1; }
|
||||
if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; }
|
||||
if (get_afl_env("AFL_SHUFFLE_QUEUE")) { afl->shuffle_queue = 1; }
|
||||
if (get_afl_env("AFL_EXPAND_HAVOC_NOW")) { afl->expand_havoc = 1; }
|
||||
|
||||
if (afl->afl_env.afl_autoresume) {
|
||||
|
||||
afl->autoresume = 1;
|
||||
if (afl->in_place_resume) {
|
||||
|
||||
SAYF("AFL_AUTORESUME has no effect for '-i -'");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (afl->afl_env.afl_autoresume) { afl->autoresume = 1; }
|
||||
|
||||
if (afl->afl_env.afl_hang_tmout) {
|
||||
|
||||
@ -2326,8 +2336,8 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
u8 ver_string[8];
|
||||
u64 *ver = (u64 *)ver_string;
|
||||
u64 expect_ver =
|
||||
afl->shm.cmplog_mode + (sizeof(struct queue_entry) << 1);
|
||||
u64 expect_ver = FAST_RESUME_VERSION + afl->shm.cmplog_mode +
|
||||
(sizeof(struct queue_entry) << 1);
|
||||
|
||||
if (NZLIBREAD(fr_fd, ver_string, sizeof(ver_string)) !=
|
||||
sizeof(ver_string))
|
||||
@ -2605,7 +2615,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
} else {
|
||||
|
||||
WARNF("Unknown abstraction: %s, fallback to unique trace.\n",
|
||||
WARNF("Unknown abstraction: %s, fallback to simplified trace.\n",
|
||||
san_abstraction);
|
||||
afl->san_abstraction = SIMPLIFY_TRACE;
|
||||
|
||||
@ -2843,7 +2853,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
u8 *o_end = (u8 *)&(afl->queue_buf[0]->mother);
|
||||
u32 r = 8 + afl->fsrv.map_size * 4;
|
||||
u32 q_len = o_end - o_start;
|
||||
u32 m_len = (afl->fsrv.map_size >> 3);
|
||||
u32 m_len = ((afl->fsrv.map_size + 7) >> 3);
|
||||
struct queue_entry *q;
|
||||
|
||||
for (u32 i = 0; i < afl->queued_items; i++) {
|
||||
@ -2866,7 +2876,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
|
||||
afl->total_bitmap_size += q->bitmap_size;
|
||||
++afl->total_bitmap_entries;
|
||||
update_bitmap_score(afl, q);
|
||||
update_bitmap_score(afl, q, false);
|
||||
|
||||
if (q->was_fuzzed) { --afl->pending_not_fuzzed; }
|
||||
|
||||
@ -3236,15 +3246,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
||||
}
|
||||
|
||||
// we must recalculate the scores of all queue entries
|
||||
for (u32 i = 0; i < afl->queued_items; i++) {
|
||||
|
||||
if (likely(!afl->queue_buf[i]->disabled)) {
|
||||
|
||||
update_bitmap_score(afl, afl->queue_buf[i]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
recalculate_all_scores(afl);
|
||||
|
||||
}
|
||||
|
||||
@ -3546,7 +3548,8 @@ stop_fuzzing:
|
||||
u8 ver_string[8];
|
||||
u32 w = 0;
|
||||
u64 *ver = (u64 *)ver_string;
|
||||
*ver = afl->shm.cmplog_mode + (sizeof(struct queue_entry) << 1);
|
||||
*ver = FAST_RESUME_VERSION + afl->shm.cmplog_mode +
|
||||
(sizeof(struct queue_entry) << 1);
|
||||
|
||||
ZLIBWRITE(fr_fd, ver_string, sizeof(ver_string), "ver_string");
|
||||
ZLIBWRITE(fr_fd, afl->virgin_bits, afl->fsrv.map_size, "virgin_bits");
|
||||
@ -3559,7 +3562,7 @@ stop_fuzzing:
|
||||
u8 *o_start = (u8 *)&(afl->queue_buf[0]->colorized);
|
||||
u8 *o_end = (u8 *)&(afl->queue_buf[0]->mother);
|
||||
u32 q_len = o_end - o_start;
|
||||
u32 m_len = (afl->fsrv.map_size >> 3);
|
||||
u32 m_len = ((afl->fsrv.map_size + 7) >> 3);
|
||||
struct queue_entry *q;
|
||||
|
||||
afl->pending_not_fuzzed = afl->queued_items;
|
||||
@ -3626,6 +3629,10 @@ stop_fuzzing:
|
||||
|
||||
}
|
||||
|
||||
ck_free(afl->n_fuzz);
|
||||
ck_free(afl->n_fuzz_dup);
|
||||
ck_free(afl->simplified_n_fuzz);
|
||||
|
||||
if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
|
||||
ck_free(afl->fsrv.target_path);
|
||||
ck_free(afl->fsrv.out_file);
|
||||
|
@ -159,10 +159,11 @@ void show_stats(afl_state_t *afl) {
|
||||
|
||||
}
|
||||
|
||||
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q, bool x) {
|
||||
|
||||
(void)afl;
|
||||
(void)q;
|
||||
(void)x;
|
||||
|
||||
}
|
||||
|
||||
|
@ -106,11 +106,15 @@ __attribute__((weak)) void __asan_unpoison_memory_region(
|
||||
__attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size);
|
||||
|
||||
// Notify AFL about persistent mode.
|
||||
static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##";
|
||||
__attribute__((section(".rodata"), used,
|
||||
retain)) static const char AFL_PERSISTENT[] =
|
||||
"##SIG_AFL_PERSISTENT##";
|
||||
int __afl_persistent_loop(unsigned int);
|
||||
|
||||
// Notify AFL about deferred forkserver.
|
||||
static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##";
|
||||
__attribute__((section(".rodata"), used,
|
||||
retain)) static const char AFL_DEFER_FORKSVR[] =
|
||||
"##SIG_AFL_DEFER_FORKSRV##";
|
||||
void __afl_manual_init();
|
||||
|
||||
// Use this optionally defined function to output sanitizer messages even if
|
||||
@ -350,11 +354,6 @@ __attribute__((weak)) int LLVMFuzzerRunDriver(
|
||||
|
||||
// Do any other expensive one-time initialization here.
|
||||
|
||||
uint8_t dummy_input[64] = {0};
|
||||
memcpy(dummy_input, (void *)AFL_PERSISTENT, sizeof(AFL_PERSISTENT));
|
||||
memcpy(dummy_input + 32, (void *)AFL_DEFER_FORKSVR,
|
||||
sizeof(AFL_DEFER_FORKSVR));
|
||||
|
||||
int N = INT_MAX;
|
||||
|
||||
if (!in_afl && argc == 2 && !strcmp(argv[1], "-")) {
|
||||
|
@ -11,12 +11,12 @@
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "../include/android-ashmem.h"
|
||||
#include "../../include/android-ashmem.h"
|
||||
#endif
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../config.h"
|
||||
#include "../../config.h"
|
||||
|
||||
#include <QBDI.h>
|
||||
|
||||
@ -81,7 +81,7 @@ static void afl_forkserver() {
|
||||
while (1) {
|
||||
|
||||
int status;
|
||||
u32 was_killed;
|
||||
unsigned int was_killed;
|
||||
// wait for afl-fuzz
|
||||
if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user