about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile25
-rw-r--r--GNUmakefile.llvm18
-rwxr-xr-xafl-persistent-config8
-rwxr-xr-xafl-system-config2
-rw-r--r--docs/Changelog.md9
-rw-r--r--docs/env_variables.md8
-rw-r--r--docs/fuzzing_binary-only_targets.md2
-rw-r--r--docs/fuzzing_in_depth.md4
-rw-r--r--frida_mode/README.md2
-rw-r--r--frida_mode/Scripting.md4
-rwxr-xr-xfrida_mode/update_frida_version.sh4
-rw-r--r--instrumentation/README.lto.md4
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc36
-rw-r--r--instrumentation/SanitizerCoveragePCGUARD.so.cc74
-rw-r--r--nyx_mode/README.md2
-rw-r--r--qemu_mode/QEMUAFL_VERSION2
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-analyze.c4
-rw-r--r--src/afl-cc.c12
-rw-r--r--src/afl-fuzz-state.c6
-rw-r--r--src/afl-showmap.c12
-rwxr-xr-xtest/test-basic.sh2
-rw-r--r--unicorn_mode/UNICORNAFL_VERSION2
-rwxr-xr-xunicorn_mode/build_unicorn_support.sh14
-rw-r--r--utils/aflpp_driver/aflpp_driver.c19
-rwxr-xr-xutils/analysis_scripts/queue2csv.sh4
-rw-r--r--utils/libdislocator/libdislocator.so.c17
-rw-r--r--utils/libtokencap/libtokencap.so.c16
28 files changed, 142 insertions, 170 deletions
diff --git a/Dockerfile b/Dockerfile
index f1b2fc01..8a825b36 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -9,18 +9,29 @@ FROM ubuntu:22.04 AS aflplusplus
 LABEL "maintainer"="afl++ team <afl@aflplus.plus>"
 LABEL "about"="AFLplusplus container image"
 
+### Comment out to enable these features
+# Only available on specific ARM64 boards
+ENV NO_CORESIGHT=1
+# Possible but unlikely in a docker container
+ENV NO_NYX=1
+
+### Only change these if you know what you are doing:
+# LLVM 15 does not look good so we stay at 14 to still have LTO
+ENV LLVM_VERSION=14
+# GCC 12 is producing compile errors for some targets so we stay at GCC 11
+ENV GCC_VERSION=11
+
+### No changes beyond the point unless you know what you are doing :)
+
 ARG DEBIAN_FRONTEND=noninteractive
 
 ENV NO_ARCH_OPT=1
 ENV IS_DOCKER=1
 
 RUN apt-get update && apt-get full-upgrade -y && \
-    apt-get install -y --no-install-recommends wget ca-certificates && \
+    apt-get install -y --no-install-recommends wget ca-certificates apt-utils && \
     rm -rf /var/lib/apt/lists/*
 
-ENV LLVM_VERSION=14
-ENV GCC_VERSION=11
-
 RUN echo "deb [signed-by=/etc/apt/keyrings/llvm-snapshot.gpg.key] http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${LLVM_VERSION} main" > /etc/apt/sources.list.d/llvm.list && \
     wget -qO /etc/apt/keyrings/llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key
 
@@ -30,7 +41,7 @@ RUN apt-get update && \
     git xz-utils bzip2 wget jupp nano bash-completion less vim joe ssh psmisc \
     python3 python3-dev python3-setuptools python-is-python3 \
     libtool libtool-bin libglib2.0-dev \
-    apt-utils apt-transport-https gnupg dialog \
+    apt-transport-https gnupg dialog \
     gnuplot-nox libpixman-1-dev \
     gcc-${GCC_VERSION} g++-${GCC_VERSION} gcc-${GCC_VERSION}-plugin-dev gdb lcov \
     clang-${LLVM_VERSION} clang-tools-${LLVM_VERSION} libc++1-${LLVM_VERSION} \
@@ -64,10 +75,6 @@ ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
 RUN git clone --depth=1 https://github.com/vanhauser-thc/afl-cov && \
     (cd afl-cov && make install) && rm -rf afl-cov
 
-# Build currently broken
-ENV NO_CORESIGHT=1
-ENV NO_UNICORN_ARM64=1
-
 WORKDIR /AFLplusplus
 COPY . .
 
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index e775ca98..c37c4a51 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -45,11 +45,11 @@ endif
 LLVMVER  = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's/svn//' )
 LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' )
 LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' )
-LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 )
-LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[5-9]' && echo 1 || echo 0 )
-LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[0-9]' && echo 1 || echo 0 )
-LLVM_10_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]|^10\.[1-9]|^10\.0.[1-9]' && echo 1 || echo 0 )
-LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | egrep -q '^1[1-9]' && echo 1 || echo 0 )
+LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 )
+LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[5-9]' && echo 1 || echo 0 )
+LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
+LLVM_10_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]|^10\.[1-9]|^10\.0.[1-9]' && echo 1 || echo 0 )
+LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]' && echo 1 || echo 0 )
 LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
 LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
 LLVM_STDCXX = gnu++11
@@ -86,12 +86,6 @@ ifeq "$(LLVM_TOO_OLD)" "1"
   $(shell sleep 1)
 endif
 
-ifeq "$(LLVM_MAJOR)" "15"
-  $(info [!] llvm_mode detected llvm 15, which is currently broken for LTO plugins.)
-  LLVM_LTO = 0
-  LLVM_HAVE_LTO = 0
-endif
-
 ifeq "$(LLVM_HAVE_LTO)" "1"
   $(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation)
   LLVM_LTO = 1
@@ -99,7 +93,7 @@ ifeq "$(LLVM_HAVE_LTO)" "1"
 endif
 
 ifeq "$(LLVM_LTO)" "0"
-  $(info [+] llvm_mode detected llvm < 11 or llvm 15, afl-lto LTO will not be build.)
+  $(info [+] llvm_mode detected llvm < 11, afl-lto LTO will not be build.)
 endif
 
 ifeq "$(LLVM_APPLE_XCODE)" "1"
diff --git a/afl-persistent-config b/afl-persistent-config
index fd453cbc..927f0062 100755
--- a/afl-persistent-config
+++ b/afl-persistent-config
@@ -111,11 +111,11 @@ kernel.sched_latency_ns=250000000
 EOF
   }
 
-  egrep -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null || echo Error: /etc/default/grub with GRUB_CMDLINE_LINUX_DEFAULT is not present, cannot set boot options
-  egrep -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null && {
-    egrep '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | egrep -q hardened_usercopy=off || {
+  grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null || echo Error: /etc/default/grub with GRUB_CMDLINE_LINUX_DEFAULT is not present, cannot set boot options
+  grep -E -q '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub 2>/dev/null && {
+    grep -E '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | grep -E -q hardened_usercopy=off || {
       echo "Configuring performance boot options"
-      LINE=`egrep '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | sed 's/^GRUB_CMDLINE_LINUX_DEFAULT=//' | tr -d '"'`
+      LINE=`grep -E '^GRUB_CMDLINE_LINUX_DEFAULT=' /etc/default/grub | sed 's/^GRUB_CMDLINE_LINUX_DEFAULT=//' | tr -d '"'`
       OPTIONS="$LINE ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off 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 GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"
       sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"$OPTIONS\"|" /etc/default/grub
diff --git a/afl-system-config b/afl-system-config
index f482e4fb..faa64487 100755
--- a/afl-system-config
+++ b/afl-system-config
@@ -47,7 +47,7 @@ if [ "$PLATFORM" = "Linux" ] ; then
 } > /dev/null
   echo Settings applied.
   echo
-  dmesg | egrep -q 'nospectre_v2|spectre_v2=off' || {
+  dmesg | grep -E -q 'nospectre_v2|spectre_v2=off' || {
     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 nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off 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
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 5e4de45a..71607542 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,8 +18,10 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
       to variables queue items instead of 12.
   - afl-cc:
     - fixed off-by-one bug in our pcguard implemenation, thanks for
-      @toka for reporting
+      @tokatoka for reporting
+    - fix for llvm 15 and reenabling LTO, thanks to nikic for the PR!
     - better handling of -fsanitize=..,...,.. lists
+    - support added for LLVMFuzzerRunDriver()
     - fix gcc_mode cmplog
     - obtain the map size of a target with setting AFL_DUMP_MAP_SIZE=1
       note that this will exit the target before main()
@@ -27,6 +29,11 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
     - added AFL_QEMU_TRACK_UNSTABLE to log the addresses of unstable
       edges (together with AFL_DEBUG=1 afl-fuzz). thanks to
       worksbutnottested!
+  - afl-analyze broke at some point, fix by CodeLogicError, thank you!
+  - unicorn_mode:
+    - updated upstream unicorn version
+    - fixed builds for aarch64
+    - build now uses all available cores
 
 
 ### Version ++4.02c (release)
diff --git a/docs/env_variables.md b/docs/env_variables.md
index bb54357b..1abe9438 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -455,7 +455,7 @@ checks or alter some of the more exotic semantics of the tool:
     normally done when starting up the forkserver and causes a pretty
     significant performance drop.
 
-  - `AFL_NO_SNAPSHOT` will advice afl-fuzz not to use the snapshot feature if
+  - `AFL_NO_SNAPSHOT` will advise afl-fuzz not to use the snapshot feature if
     the snapshot lkm is loaded.
 
   - Setting `AFL_NO_UI` inhibits the UI altogether and just periodically prints
@@ -473,7 +473,7 @@ checks or alter some of the more exotic semantics of the tool:
     some targets keep inherent state due which a detected crash test case does
     not crash the target again when the test case is given. To be able to still
     re-trigger these crashes, you can use the `AFL_PERSISTENT_RECORD` variable
-    with a value of how many previous fuzz cases to keep prio a crash. If set to
+    with a value of how many previous fuzz cases to keep prior a crash. If set to
     e.g., 10, then the 9 previous inputs are written to out/default/crashes as
     RECORD:000000,cnt:000000 to RECORD:000000,cnt:000008 and
     RECORD:000000,cnt:000009 being the crash case. NOTE: This option needs to be
@@ -694,8 +694,8 @@ support.
 * `AFL_FRIDA_STALKER_ADJACENT_BLOCKS` - Configure the number of adjacent blocks
   to fetch when generating instrumented code. By fetching blocks in the same
   order they appear in the original program, rather than the order of execution
-  should help reduce locallity and adjacency. This includes allowing us to
-  vector between adjancent blocks using a NOP slide rather than an immediate
+  should help reduce locality and adjacency. This includes allowing us to
+  vector between adjacent blocks using a NOP slide rather than an immediate
   branch.
 * `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries
   stored along-side branch instructions which provide a cache to avoid having to
diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md
index c97af1b9..266920e6 100644
--- a/docs/fuzzing_binary-only_targets.md
+++ b/docs/fuzzing_binary-only_targets.md
@@ -291,7 +291,7 @@ its IPT performance is just 6%!
 
 There are many binary-only fuzzing frameworks. Some are great for CTFs but don't
 work with large binaries, others are very slow but have good path discovery,
-some are very hard to set-up...
+some are very hard to set up...
 
 * Jackalope:
   [https://github.com/googleprojectzero/Jackalope](https://github.com/googleprojectzero/Jackalope)
diff --git a/docs/fuzzing_in_depth.md b/docs/fuzzing_in_depth.md
index 92c9910b..a0bf1566 100644
--- a/docs/fuzzing_in_depth.md
+++ b/docs/fuzzing_in_depth.md
@@ -523,7 +523,7 @@ mode!) and switch the input directory with a dash (`-`):
 afl-fuzz -i - -o output -- bin/target -someopt @@
 ```
 
-Adding a dictionary is helpful. You have to following options:
+Adding a dictionary is helpful. You have the following options:
 
 * See the directory
 [dictionaries/](../dictionaries/), if something is already included for your
@@ -672,7 +672,7 @@ The syncing process itself is very simple. As the `-M main-$HOSTNAME` instance
 syncs to all `-S` secondaries as well as to other fuzzers, you have to copy only
 this directory to the other machines.
 
-Lets say all servers have the `-o out` directory in /target/foo/out, and you
+Let's say all servers have the `-o out` directory in /target/foo/out, and you
 created a file `servers.txt` which contains the hostnames of all participating
 servers, plus you have an ssh key deployed to all of them, then run:
 
diff --git a/frida_mode/README.md b/frida_mode/README.md
index bfe0948b..055bb3ee 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -86,7 +86,7 @@ To enable the powerful CMPLOG mechanism, set `-c 0` for `afl-fuzz`.
 
 ## Scripting
 
-One of the more powerful features of FRIDA mode is it's support for
+One of the more powerful features of FRIDA mode is its support for
 configuration by JavaScript, rather than using environment variables. For
 details of how this works, see [Scripting.md](Scripting.md).
 
diff --git a/frida_mode/Scripting.md b/frida_mode/Scripting.md
index 2b18e200..06d4212c 100644
--- a/frida_mode/Scripting.md
+++ b/frida_mode/Scripting.md
@@ -2,7 +2,7 @@
 
 FRIDA now supports the ability to configure itself using JavaScript. This allows
 the user to make use of the convenience of FRIDA's scripting engine (along with
-it's support for debug symbols and exports) to configure all of the things which
+its support for debug symbols and exports) to configure all of the things which
 were traditionally configured using environment variables.
 
 By default, FRIDA mode will look for the file `afl.js` in the current working
@@ -95,7 +95,7 @@ Afl.print("done");
 
 ## Stripped binaries
 
-Lastly, if the binary you attempting to fuzz has no symbol information and no
+Lastly, if the binary you're attempting to fuzz has no symbol information and no
 exports, then the following approach can be used.
 
 ```js
diff --git a/frida_mode/update_frida_version.sh b/frida_mode/update_frida_version.sh
index 7d938712..18243fbb 100755
--- a/frida_mode/update_frida_version.sh
+++ b/frida_mode/update_frida_version.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
 test -n "$1" && { echo This script has no options. It updates the referenced Frida version in GNUmakefile to the most current one. ; exit 1 ; }
 
-OLD=$(egrep '^GUM_DEVKIT_VERSION=' GNUmakefile 2>/dev/null|awk -F= '{print$2}')
-NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|egrep 'frida-gum-devkit-[0-9.]*-linux-x86_64'|head -n 1|sed 's/.*frida-gum-devkit-//'|sed 's/-linux.*//')
+OLD=$(grep -E '^GUM_DEVKIT_VERSION=' GNUmakefile 2>/dev/null|awk -F= '{print$2}')
+NEW=$(curl https://github.com/frida/frida/releases/ 2>/dev/null|grep -E 'frida-gum-devkit-[0-9.]*-linux-x86_64'|head -n 1|sed 's/.*frida-gum-devkit-//'|sed 's/-linux.*//')
 
 echo Current set version: $OLD
 echo Newest available version: $NEW
diff --git a/instrumentation/README.lto.md b/instrumentation/README.lto.md
index a20175b1..172115ae 100644
--- a/instrumentation/README.lto.md
+++ b/instrumentation/README.lto.md
@@ -38,7 +38,7 @@ many dead ends until we got to this:
 * Our compiler (afl-clang-lto/afl-clang-lto++) takes care of setting the correct
   LTO options and runs our own afl-ld linker instead of the system linker.
 * The LLVM linker collects all LTO files to link and instruments them so that we
-  have non-colliding edge overage.
+  have non-colliding edge coverage.
 * We use a new (for afl) edge coverage - which is the same as in llvm
   -fsanitize=coverage edge coverage mode. :)
 
@@ -361,4 +361,4 @@ control flow graph.
 This is all now fixed with llvm 11+. The llvm's own linker is now able to load
 passes and this bypasses all problems we had.
 
-Happy end :)
\ No newline at end of file
+Happy end :)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 721bc487..231151f5 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -111,6 +111,12 @@ static cl::opt<bool> ClPruneBlocks(
     cl::desc("Reduce the number of instrumented blocks"), cl::Hidden,
     cl::init(true));
 
+namespace llvm {
+
+void initializeModuleSanitizerCoverageLTOLegacyPassPass(PassRegistry &PB);
+
+}
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -255,13 +261,13 @@ class ModuleSanitizerCoverageLTO
 
 };
 
-class ModuleSanitizerCoverageLegacyPass : public ModulePass {
+class ModuleSanitizerCoverageLTOLegacyPass : public ModulePass {
 
  public:
   static char ID;
   StringRef   getPassName() const override {
 
-    return "sancov";
+    return "sancov-lto";
 
   }
 
@@ -272,11 +278,11 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass {
 
   }
 
-  ModuleSanitizerCoverageLegacyPass(
+  ModuleSanitizerCoverageLTOLegacyPass(
       const SanitizerCoverageOptions &Options = SanitizerCoverageOptions())
       : ModulePass(ID), Options(Options) {
 
-    initializeModuleSanitizerCoverageLegacyPassPass(
+    initializeModuleSanitizerCoverageLTOLegacyPassPass(
         *PassRegistry::getPassRegistry());
 
   }
@@ -318,8 +324,11 @@ llvmGetPassPluginInfo() {
 #if LLVM_VERSION_MAJOR <= 13
             using OptimizationLevel = typename PassBuilder::OptimizationLevel;
 #endif
-            //            PB.registerFullLinkTimeOptimizationLastEPCallback(
+#if LLVM_VERSION_MAJOR >= 15
+            PB.registerFullLinkTimeOptimizationLastEPCallback(
+#else
             PB.registerOptimizerLastEPCallback(
+#endif
                 [](ModulePassManager &MPM, OptimizationLevel OL) {
 
                   MPM.addPass(ModuleSanitizerCoverageLTO());
@@ -1750,30 +1759,21 @@ std::string ModuleSanitizerCoverageLTO::getSectionName(
 
 }
 
-char ModuleSanitizerCoverageLegacyPass::ID = 0;
+char ModuleSanitizerCoverageLTOLegacyPass::ID = 0;
 
-INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov",
+INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLTOLegacyPass, "sancov-lto",
                       "Pass for instrumenting coverage on functions", false,
                       false)
 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
-INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov",
+INITIALIZE_PASS_END(ModuleSanitizerCoverageLTOLegacyPass, "sancov-lto",
                     "Pass for instrumenting coverage on functions", false,
                     false)
 
-ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass(
-    const SanitizerCoverageOptions &Options,
-    const std::vector<std::string> &AllowlistFiles,
-    const std::vector<std::string> &BlocklistFiles) {
-
-  return new ModuleSanitizerCoverageLegacyPass(Options);
-
-}
-
 static void registerLTOPass(const PassManagerBuilder &,
                             legacy::PassManagerBase &PM) {
 
-  auto p = new ModuleSanitizerCoverageLegacyPass();
+  auto p = new ModuleSanitizerCoverageLTOLegacyPass();
   PM.add(p);
 
 }
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index faad0bf6..ef2d3b9c 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -209,57 +209,6 @@ class ModuleSanitizerCoverageAFL
 
 };
 
-class ModuleSanitizerCoverageLegacyPass : public ModulePass {
-
- public:
-  ModuleSanitizerCoverageLegacyPass(
-      const SanitizerCoverageOptions &Options = SanitizerCoverageOptions())
-      : ModulePass(ID), Options(Options) {
-
-    initializeModuleSanitizerCoverageLegacyPassPass(
-        *PassRegistry::getPassRegistry());
-
-  }
-
-  bool runOnModule(Module &M) override {
-
-    ModuleSanitizerCoverageAFL ModuleSancov(Options);
-    auto DTCallback = [this](Function &F) -> const DominatorTree * {
-
-      return &this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree();
-
-    };
-
-    auto PDTCallback = [this](Function &F) -> const PostDominatorTree * {
-
-      return &this->getAnalysis<PostDominatorTreeWrapperPass>(F)
-                  .getPostDomTree();
-
-    };
-
-    return ModuleSancov.instrumentModule(M, DTCallback, PDTCallback);
-
-  }
-
-  /*static*/ char ID;  // Pass identification, replacement for typeid
-  StringRef       getPassName() const override {
-
-    return "ModuleSanitizerCoverage";
-
-  }
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override {
-
-    AU.addRequired<DominatorTreeWrapperPass>();
-    AU.addRequired<PostDominatorTreeWrapperPass>();
-
-  }
-
- private:
-  SanitizerCoverageOptions Options;
-
-};
-
 }  // namespace
 
 #if LLVM_VERSION_MAJOR >= 11                        /* use new pass manager */
@@ -1530,26 +1479,3 @@ std::string ModuleSanitizerCoverageAFL::getSectionEnd(
 
 }
 
-#if 0
-
-char ModuleSanitizerCoverageLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov",
-                      "Pass for instrumenting coverage on functions", false,
-                      false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
-INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov",
-                    "Pass for instrumenting coverage on functions", false,
-                    false)
-ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass(
-    const SanitizerCoverageOptions &Options,
-    const std::vector<std::string> &AllowlistFiles,
-    const std::vector<std::string> &BlocklistFiles) {
-
-  return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles,
-                                               BlocklistFiles);
-
-}
-
-#endif
-
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index 1afedd9b..11698df9 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -97,7 +97,7 @@ sudo modprobe kvm-intel # or kvm-amd for AMD processors
 If you want to fuzz in parallel (and you should!), then this has to be done in a
 special way:
 
-* Instead of `-X` (standalone mode), you specify `-Y` (multi processor mode).
+* Instead of `-X` (standalone mode), you specify `-Y` (multiprocessor mode).
 * First, a Main afl-fuzz instance has to be started with `-M 0`.
 * Only afterwards you can start Secondary afl-fuzz instances, which must have an
   increasing number value, starting at 1, e.g., `-S 1`.
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index d59a04e7..10e875b1 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-12682ea816
+61bc152384
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject 12682ea8169604a6c0f9b2b36eaa53ff7dcc7fd
+Subproject 61bc1523848a5235b43719c9fa7d78e9a970a1a
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index d4822341..a21f014f 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -203,7 +203,7 @@ static void read_initial_file(void) {
 /* Execute target application. Returns exec checksum, or 0 if program
    times out. */
 
-static u32 analyze_run_target(u8 *mem, u32 len, u8 first_run) {
+static u64 analyze_run_target(u8 *mem, u32 len, u8 first_run) {
 
   afl_fsrv_write_to_testcase(&fsrv, mem, len);
   fsrv_run_result_t ret = afl_fsrv_run_target(&fsrv, exec_tmout, &stop_soon);
@@ -528,7 +528,7 @@ static void analyze() {
 
   for (i = 0; i < in_len; i++) {
 
-    u32 xor_ff, xor_01, sub_10, add_10;
+    u64 xor_ff, xor_01, sub_10, add_10;
     u8  xff_orig, x01_orig, s10_orig, a10_orig;
 
     /* Perform walking byte adjustments across the file. We perform four
diff --git a/src/afl-cc.c b/src/afl-cc.c
index c0449e64..5e7a9c9e 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -666,15 +666,21 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 #endif
       free(ld_path);
 
-#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13
+#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15
+      // The NewPM implementation only works fully since LLVM 15.
+      cc_params[cc_par_cnt++] =
+          alloc_printf("-Wl,--load-pass-plugin=%s/SanitizerCoverageLTO.so", obj_path);
+#elif defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13
       cc_params[cc_par_cnt++] = "-Wl,--lto-legacy-pass-manager";
+      cc_params[cc_par_cnt++] =
+          alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
 #else
       cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager";
+      cc_params[cc_par_cnt++] =
+          alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
 #endif
 
       cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition";
-      cc_params[cc_par_cnt++] =
-          alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path);
       cc_params[cc_par_cnt++] = lto_flag;
 
     } else {
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 0576f84f..5199f7e6 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -604,11 +604,7 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
 
   }
 
-  if (afl->afl_env.afl_pizza_mode) {
-
-    afl->pizza_is_served = 1;
-
-  }
+  if (afl->afl_env.afl_pizza_mode) { afl->pizza_is_served = 1; }
 
   if (issue_detected) { sleep(2); }
 
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 07f30326..b0b21011 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1241,11 +1241,15 @@ int main(int argc, char **argv_orig, char **envp) {
     u32 save_be_quiet = be_quiet;
     be_quiet = !debug;
     if (map_size > 4194304) {
-        fsrv->map_size = map_size;
-    }
-    else {
-        fsrv->map_size = 4194304; // dummy temporary value
+
+      fsrv->map_size = map_size;
+
+    } else {
+
+      fsrv->map_size = 4194304;  // dummy temporary value
+
     }
+
     u32 new_map_size =
         afl_fsrv_get_mapsize(fsrv, use_argv, &stop_soon,
                              (get_afl_env("AFL_DEBUG_CHILD") ||
diff --git a/test/test-basic.sh b/test/test-basic.sh
index bec42b4d..538b6931 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -48,7 +48,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
       $ECHO "$GREEN[+] ${AFL_GCC} hardened mode succeeded and is working"
     } || {
       $ECHO "$RED[!] ${AFL_GCC} hardened mode is not hardened"
-      env | egrep 'AFL|PATH|LLVM'
+      env | grep -E 'AFL|PATH|LLVM'
       AFL_DEBUG=1 AFL_HARDEN=1 ../${AFL_GCC} -o test-compcov.harden test-compcov.c
       nm test-compcov.harden
       CODE=1
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 5e7234c6..bba4215c 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-06796154996fef2d92ccd172181ee0cdf3631959
+6e00ceac
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index f24c8ce3..a3978d9d 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -196,13 +196,23 @@ $MAKECMD -j1 || exit 1
 echo "[+] Build process successful!"
 
 echo "[*] Installing Unicorn python bindings..."
+cd unicorn/bindings/python || exit 1
+if [ -z "$VIRTUAL_ENV" ]; then
+  echo "[*] Info: Installing python unicornafl using --user"
+  THREADS=$CORES $PYTHONBIN setup.py install --user --force --prefix=|| exit 1
+else
+  echo "[*] Info: Installing python unicornafl to virtualenv: $VIRTUAL_ENV"
+  THREADS=$CORES $PYTHONBIN setup.py install --force || exit 1
+fi
+cd ../../../
+echo "[*] Installing Unicornafl python bindings..."
 cd bindings/python || exit 1
 if [ -z "$VIRTUAL_ENV" ]; then
   echo "[*] Info: Installing python unicornafl using --user"
-  $PYTHONBIN setup.py install --user --force --prefix=|| exit 1
+  THREADS=$CORES $PYTHONBIN setup.py install --user --force --prefix=|| exit 1
 else
   echo "[*] Info: Installing python unicornafl to virtualenv: $VIRTUAL_ENV"
-  $PYTHONBIN setup.py install --force || exit 1
+  THREADS=$CORES $PYTHONBIN setup.py install --force || exit 1
 fi
 echo '[*] If needed, you can (re)install the bindings from `./unicornafl/bindings/python` using `python setup.py install`'
 
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index 4e4ea129..52b98f41 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -62,8 +62,11 @@ extern unsigned int  *__afl_fuzz_len;
 extern unsigned char *__afl_fuzz_ptr;
 
 // libFuzzer interface is thin, so we don't include any libFuzzer headers.
-int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+__attribute__((weak)) int LLVMFuzzerTestOneInput(const uint8_t *Data,
+                                                 size_t         Size);
 __attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
+int                       LLVMFuzzerRunDriver(int *argc, char ***argv,
+                                              int (*callback)(const uint8_t *data, size_t size));
 
 // Default nop ASan hooks for manual posisoning when not linking the ASan
 // runtime
@@ -245,7 +248,7 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
 
 }
 
-int main(int argc, char **argv) {
+__attribute__((weak)) int main(int argc, char **argv) {
 
   if (argc < 2 || strncmp(argv[1], "-h", 2) == 0)
     printf(
@@ -265,6 +268,16 @@ int main(int argc, char **argv) {
         "===================================================================\n",
         argv[0], argv[0]);
 
+  return LLVMFuzzerRunDriver(&argc, &argv, LLVMFuzzerTestOneInput);
+
+}
+
+int LLVMFuzzerRunDriver(int *argcp, char ***argvp,
+                        int (*callback)(const uint8_t *data, size_t size)) {
+
+  int    argc = *argcp;
+  char **argv = *argvp;
+
   if (getenv("AFL_GDB")) {
 
     char cmd[64];
@@ -352,7 +365,7 @@ int main(int argc, char **argv) {
         }
 
         prev_length = length;
-        LLVMFuzzerTestOneInput(__afl_fuzz_ptr, length);
+        (void)callback(__afl_fuzz_ptr, length);
 
       }
 
diff --git a/utils/analysis_scripts/queue2csv.sh b/utils/analysis_scripts/queue2csv.sh
index 2528b438..47141efe 100755
--- a/utils/analysis_scripts/queue2csv.sh
+++ b/utils/analysis_scripts/queue2csv.sh
@@ -92,14 +92,14 @@ mkdir "$DIR" || exit 1
 
 if [ -n "$3" -a -s "$DIR/../edges.txt" ]; then
 
-  cat "$DIR/"* | sed 's/:.*//' | sort -n | uniq -c | egrep '^[ \t]*1 ' | awk '{print$2}' > $DIR/../unique.txt
+  cat "$DIR/"* | sed 's/:.*//' | sort -n | uniq -c | grep -E '^[ \t]*1 ' | awk '{print$2}' > $DIR/../unique.txt
 
   if [ -s "$DIR/../unique.txt" ]; then
 
     ls "$DIR/id:"* | grep -v ",sync:" |sed 's/.*\/id:/id:/g' | while read file; do
 
       CNT=$(sed 's/:.*//' "$DIR/$file" | tee "$DIR/../tmp.txt" | wc -l)
-      DIFF=$(diff -u "$DIR/../tmp.txt" "$DIR/../unique.txt" | egrep '^-[0-9]' | wc -l)
+      DIFF=$(diff -u "$DIR/../tmp.txt" "$DIR/../unique.txt" | grep -E '^-[0-9]' | wc -l)
       UNIQUE=$(($CNT - $DIFF))
       sed -i "s/;UNIQUE$file/;$UNIQUE/" "$DIR/../queue.csv" "$2"
 
diff --git a/utils/libdislocator/libdislocator.so.c b/utils/libdislocator/libdislocator.so.c
index 149b910e..a6d8ecfd 100644
--- a/utils/libdislocator/libdislocator.so.c
+++ b/utils/libdislocator/libdislocator.so.c
@@ -304,7 +304,8 @@ static void *__dislocator_alloc(size_t len) {
 /* The "user-facing" wrapper for calloc(). This just checks for overflows and
    displays debug messages if requested. */
 
-void *calloc(size_t elem_len, size_t elem_cnt) {
+__attribute__((malloc)) __attribute__((alloc_size(1, 2))) void *calloc(
+    size_t elem_len, size_t elem_cnt) {
 
   void *ret;
 
@@ -339,7 +340,8 @@ void *calloc(size_t elem_len, size_t elem_cnt) {
    memory (unlike calloc(), malloc() is not guaranteed to return zeroed
    memory). */
 
-void *malloc(size_t len) {
+__attribute__((malloc)) __attribute__((alloc_size(1))) void *malloc(
+    size_t len) {
 
   void *ret;
 
@@ -398,7 +400,7 @@ void free(void *ptr) {
 /* Realloc is pretty straightforward, too. We forcibly reallocate the buffer,
    move data, and then free (aka mprotect()) the original one. */
 
-void *realloc(void *ptr, size_t len) {
+__attribute__((alloc_size(2))) void *realloc(void *ptr, size_t len) {
 
   void *ret;
 
@@ -450,7 +452,8 @@ int posix_memalign(void **ptr, size_t align, size_t len) {
 
 /* just the non-posix fashion */
 
-void *memalign(size_t align, size_t len) {
+__attribute__((malloc)) __attribute__((alloc_size(2))) void *memalign(
+    size_t align, size_t len) {
 
   void *ret = NULL;
 
@@ -466,7 +469,8 @@ void *memalign(size_t align, size_t len) {
 
 /* sort of C11 alias of memalign only more severe, alignment-wise */
 
-void *aligned_alloc(size_t align, size_t len) {
+__attribute__((malloc)) __attribute__((alloc_size(2))) void *aligned_alloc(
+    size_t align, size_t len) {
 
   void *ret = NULL;
 
@@ -484,7 +488,8 @@ void *aligned_alloc(size_t align, size_t len) {
 
 /* specific BSD api mainly checking possible overflow for the size */
 
-void *reallocarray(void *ptr, size_t elem_len, size_t elem_cnt) {
+__attribute__((alloc_size(2, 3))) void *reallocarray(void *ptr, size_t elem_len,
+                                                     size_t elem_cnt) {
 
   const size_t elem_lim = 1UL << (sizeof(size_t) * 4);
   const size_t elem_tot = elem_len * elem_cnt;
diff --git a/utils/libtokencap/libtokencap.so.c b/utils/libtokencap/libtokencap.so.c
index 5dcb8f4c..07d81d59 100644
--- a/utils/libtokencap/libtokencap.so.c
+++ b/utils/libtokencap/libtokencap.so.c
@@ -378,7 +378,8 @@ __attribute__((hot)) int strcmp(const char *str1, const char *str2) {
 
 #undef strncmp
 
-__attribute__((hot)) int strncmp(const char *str1, const char *str2, size_t len) {
+__attribute__((hot)) int strncmp(const char *str1, const char *str2,
+                                 size_t len) {
 
   if (__tokencap_is_ro(str1)) __tokencap_dump(str1, len, 1);
   if (__tokencap_is_ro(str2)) __tokencap_dump(str2, len, 1);
@@ -428,7 +429,8 @@ __attribute__((hot)) int strcasecmp(const char *str1, const char *str2) {
 
 #undef strncasecmp
 
-__attribute__((hot)) int strncasecmp(const char *str1, const char *str2, size_t len) {
+__attribute__((hot)) int strncasecmp(const char *str1, const char *str2,
+                                     size_t len) {
 
   if (__tokencap_is_ro(str1)) __tokencap_dump(str1, len, 1);
   if (__tokencap_is_ro(str2)) __tokencap_dump(str2, len, 1);
@@ -454,7 +456,8 @@ __attribute__((hot)) int strncasecmp(const char *str1, const char *str2, size_t
 
 #undef memcmp
 
-__attribute__((hot)) int memcmp(const void *mem1, const void *mem2, size_t len) {
+__attribute__((hot)) int memcmp(const void *mem1, const void *mem2,
+                                size_t len) {
 
   if (__tokencap_is_ro(mem1)) __tokencap_dump(mem1, len, 0);
   if (__tokencap_is_ro(mem2)) __tokencap_dump(mem2, len, 0);
@@ -537,7 +540,8 @@ __attribute__((hot)) char *strstr(const char *haystack, const char *needle) {
 
 #undef strcasestr
 
-__attribute__((hot)) char *strcasestr(const char *haystack, const char *needle) {
+__attribute__((hot)) char *strcasestr(const char *haystack,
+                                      const char *needle) {
 
   if (__tokencap_is_ro(haystack))
     __tokencap_dump(haystack, strlen(haystack), 1);
@@ -566,8 +570,8 @@ __attribute__((hot)) char *strcasestr(const char *haystack, const char *needle)
 
 #undef memmem
 
-__attribute__((hot)) void *memmem(const void *haystack, size_t haystack_len, const void *needle,
-             size_t needle_len) {
+__attribute__((hot)) void *memmem(const void *haystack, size_t haystack_len,
+                                  const void *needle, size_t needle_len) {
 
   if (__tokencap_is_ro(haystack)) __tokencap_dump(haystack, haystack_len, 1);