From 380051868a7531830d94d312f0f11b0e19e3284f Mon Sep 17 00:00:00 2001
From: van Hauser <vh@thc.org>
Date: Thu, 10 Sep 2020 15:26:46 +0200
Subject: add libfuzzer custom mutator, minor enhancements and fixes

---
 custom_mutators/libfuzzer/FuzzerFlags.def | 197 ++++++++++++++++++++++++++++++
 1 file changed, 197 insertions(+)
 create mode 100644 custom_mutators/libfuzzer/FuzzerFlags.def

(limited to 'custom_mutators/libfuzzer/FuzzerFlags.def')

diff --git a/custom_mutators/libfuzzer/FuzzerFlags.def b/custom_mutators/libfuzzer/FuzzerFlags.def
new file mode 100644
index 00000000..c9a787e0
--- /dev/null
+++ b/custom_mutators/libfuzzer/FuzzerFlags.def
@@ -0,0 +1,197 @@
+//===- FuzzerFlags.def - Run-time flags -------------------------*- C++ -* ===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Flags. FUZZER_FLAG_INT/FUZZER_FLAG_STRING macros should be defined at the
+// point of inclusion. We are not using any flag parsing library for better
+// portability and independence.
+//===----------------------------------------------------------------------===//
+FUZZER_FLAG_INT(verbosity, 1, "Verbosity level.")
+FUZZER_FLAG_UNSIGNED(seed, 0, "Random seed. If 0, seed is generated.")
+FUZZER_FLAG_INT(runs, -1,
+            "Number of individual test runs (-1 for infinite runs).")
+FUZZER_FLAG_INT(max_len, 0, "Maximum length of the test input. "
+    "If 0, libFuzzer tries to guess a good value based on the corpus "
+    "and reports it. ")
+FUZZER_FLAG_INT(len_control, 100, "Try generating small inputs first, "
+  "then try larger inputs over time.  Specifies the rate at which the length "
+  "limit is increased (smaller == faster).  If 0, immediately try inputs with "
+  "size up to max_len. Default value is 0, if LLVMFuzzerCustomMutator is used.")
+FUZZER_FLAG_STRING(seed_inputs, "A comma-separated list of input files "
+  "to use as an additional seed corpus. Alternatively, an \"@\" followed by "
+  "the name of a file containing the comma-separated list.")
+FUZZER_FLAG_INT(keep_seed, 0, "If 1, keep seed inputs in the corpus even if "
+  "they do not produce new coverage. When used with |reduce_inputs==1|, the "
+  "seed inputs will never be reduced. This option can be useful when seeds are"
+  "not properly formed for the fuzz target but still have useful snippets.")
+FUZZER_FLAG_INT(cross_over, 1, "If 1, cross over inputs.")
+FUZZER_FLAG_INT(cross_over_uniform_dist, 0, "Experimental. If 1, use a "
+  "uniform probability distribution when choosing inputs to cross over with. "
+  "Some of the inputs in the corpus may never get chosen for mutation "
+  "depending on the input mutation scheduling policy. With this flag, all "
+  "inputs, regardless of the input mutation scheduling policy, can be chosen "
+  "as an input to cross over with. This can be particularly useful with "
+  "|keep_seed==1|; all the initial seed inputs, even though they do not "
+  "increase coverage because they are not properly formed, will still be "
+  "chosen as an input to cross over with.")
+
+FUZZER_FLAG_INT(mutate_depth, 5,
+            "Apply this number of consecutive mutations to each input.")
+FUZZER_FLAG_INT(reduce_depth, 0, "Experimental/internal. "
+                "Reduce depth if mutations lose unique features")
+FUZZER_FLAG_INT(shuffle, 1, "Shuffle inputs at startup")
+FUZZER_FLAG_INT(prefer_small, 1,
+    "If 1, always prefer smaller inputs during the corpus shuffle.")
+FUZZER_FLAG_INT(
+    timeout, 1200,
+    "Timeout in seconds (if positive). "
+    "If one unit runs more than this number of seconds the process will abort.")
+FUZZER_FLAG_INT(error_exitcode, 77, "When libFuzzer itself reports a bug "
+  "this exit code will be used.")
+FUZZER_FLAG_INT(timeout_exitcode, 70, "When libFuzzer reports a timeout "
+  "this exit code will be used.")
+FUZZER_FLAG_INT(max_total_time, 0, "If positive, indicates the maximal total "
+                                   "time in seconds to run the fuzzer.")
+FUZZER_FLAG_INT(help, 0, "Print help.")
+FUZZER_FLAG_INT(fork, 0, "Experimental mode where fuzzing happens "
+                "in a subprocess")
+FUZZER_FLAG_INT(ignore_timeouts, 1, "Ignore timeouts in fork mode")
+FUZZER_FLAG_INT(ignore_ooms, 1, "Ignore OOMs in fork mode")
+FUZZER_FLAG_INT(ignore_crashes, 0, "Ignore crashes in fork mode")
+FUZZER_FLAG_INT(merge, 0, "If 1, the 2-nd, 3-rd, etc corpora will be "
+  "merged into the 1-st corpus. Only interesting units will be taken. "
+  "This flag can be used to minimize a corpus.")
+FUZZER_FLAG_STRING(stop_file, "Stop fuzzing ASAP if this file exists")
+FUZZER_FLAG_STRING(merge_inner, "internal flag")
+FUZZER_FLAG_STRING(merge_control_file,
+                   "Specify a control file used for the merge process. "
+                   "If a merge process gets killed it tries to leave this file "
+                   "in a state suitable for resuming the merge. "
+                   "By default a temporary file will be used."
+                   "The same file can be used for multistep merge process.")
+FUZZER_FLAG_INT(minimize_crash, 0, "If 1, minimizes the provided"
+  " crash input. Use with -runs=N or -max_total_time=N to limit "
+  "the number attempts."
+  " Use with -exact_artifact_path to specify the output."
+  " Combine with ASAN_OPTIONS=dedup_token_length=3 (or similar) to ensure that"
+  " the minimized input triggers the same crash."
+  )
+FUZZER_FLAG_INT(cleanse_crash, 0, "If 1, tries to cleanse the provided"
+  " crash input to make it contain fewer original bytes."
+  " Use with -exact_artifact_path to specify the output."
+  )
+FUZZER_FLAG_INT(minimize_crash_internal_step, 0, "internal flag")
+FUZZER_FLAG_STRING(features_dir, "internal flag. Used to dump feature sets on disk."
+  "Every time a new input is added to the corpus, a corresponding file in the features_dir"
+  " is created containing the unique features of that input."
+  " Features are stored in binary format.")
+FUZZER_FLAG_STRING(mutation_graph_file, "Saves a graph (in DOT format) to"
+  " mutation_graph_file. The graph contains a vertex for each input that has"
+  " unique coverage; directed edges are provided between parents and children"
+  " where the child has unique coverage, and are recorded with the type of"
+  " mutation that caused the child.")
+FUZZER_FLAG_INT(use_counters, 1, "Use coverage counters")
+FUZZER_FLAG_INT(use_memmem, 1,
+                "Use hints from intercepting memmem, strstr, etc")
+FUZZER_FLAG_INT(use_value_profile, 0,
+                "Experimental. Use value profile to guide fuzzing.")
+FUZZER_FLAG_INT(use_cmp, 1, "Use CMP traces to guide mutations")
+FUZZER_FLAG_INT(shrink, 0, "Experimental. Try to shrink corpus inputs.")
+FUZZER_FLAG_INT(reduce_inputs, 1,
+  "Try to reduce the size of inputs while preserving their full feature sets")
+FUZZER_FLAG_UNSIGNED(jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
+                          " this number of jobs in separate worker processes"
+                          " with stdout/stderr redirected to fuzz-JOB.log.")
+FUZZER_FLAG_UNSIGNED(workers, 0,
+            "Number of simultaneous worker processes to run the jobs."
+            " If zero, \"min(jobs,NumberOfCpuCores()/2)\" is used.")
+FUZZER_FLAG_INT(reload, 1,
+                "Reload the main corpus every <N> seconds to get new units"
+                " discovered by other processes. If 0, disabled")
+FUZZER_FLAG_INT(report_slow_units, 10,
+    "Report slowest units if they run for more than this number of seconds.")
+FUZZER_FLAG_INT(only_ascii, 0,
+                "If 1, generate only ASCII (isprint+isspace) inputs.")
+FUZZER_FLAG_STRING(dict, "Experimental. Use the dictionary file.")
+FUZZER_FLAG_STRING(artifact_prefix, "Write fuzzing artifacts (crash, "
+                                    "timeout, or slow inputs) as "
+                                    "$(artifact_prefix)file")
+FUZZER_FLAG_STRING(exact_artifact_path,
+                   "Write the single artifact on failure (crash, timeout) "
+                   "as $(exact_artifact_path). This overrides -artifact_prefix "
+                   "and will not use checksum in the file name. Do not "
+                   "use the same path for several parallel processes.")
+FUZZER_FLAG_INT(print_pcs, 0, "If 1, print out newly covered PCs.")
+FUZZER_FLAG_INT(print_funcs, 2, "If >=1, print out at most this number of "
+                                "newly covered functions.")
+FUZZER_FLAG_INT(print_final_stats, 0, "If 1, print statistics at exit.")
+FUZZER_FLAG_INT(print_corpus_stats, 0,
+  "If 1, print statistics on corpus elements at exit.")
+FUZZER_FLAG_INT(print_coverage, 0, "If 1, print coverage information as text"
+                                   " at exit.")
+FUZZER_FLAG_INT(dump_coverage, 0, "Deprecated.")
+FUZZER_FLAG_INT(handle_segv, 1, "If 1, try to intercept SIGSEGV.")
+FUZZER_FLAG_INT(handle_bus, 1, "If 1, try to intercept SIGBUS.")
+FUZZER_FLAG_INT(handle_abrt, 1, "If 1, try to intercept SIGABRT.")
+FUZZER_FLAG_INT(handle_ill, 1, "If 1, try to intercept SIGILL.")
+FUZZER_FLAG_INT(handle_fpe, 1, "If 1, try to intercept SIGFPE.")
+FUZZER_FLAG_INT(handle_int, 1, "If 1, try to intercept SIGINT.")
+FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.")
+FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.")
+FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.")
+FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.")
+FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; "
+    "if 2, close stderr; if 3, close both. "
+    "Be careful, this will also close e.g. stderr of asan.")
+FUZZER_FLAG_INT(detect_leaks, 1, "If 1, and if LeakSanitizer is enabled "
+    "try to detect memory leaks during fuzzing (i.e. not only at shut down).")
+FUZZER_FLAG_INT(purge_allocator_interval, 1, "Purge allocator caches and "
+    "quarantines every <N> seconds. When rss_limit_mb is specified (>0), "
+    "purging starts when RSS exceeds 50% of rss_limit_mb. Pass "
+    "purge_allocator_interval=-1 to disable this functionality.")
+FUZZER_FLAG_INT(trace_malloc, 0, "If >= 1 will print all mallocs/frees. "
+    "If >= 2 will also print stack traces.")
+FUZZER_FLAG_INT(rss_limit_mb, 2048, "If non-zero, the fuzzer will exit upon"
+    "reaching this limit of RSS memory usage.")
+FUZZER_FLAG_INT(malloc_limit_mb, 0, "If non-zero, the fuzzer will exit "
+    "if the target tries to allocate this number of Mb with one malloc call. "
+    "If zero (default) same limit as rss_limit_mb is applied.")
+FUZZER_FLAG_STRING(exit_on_src_pos, "Exit if a newly found PC originates"
+    " from the given source location. Example: -exit_on_src_pos=foo.cc:123. "
+    "Used primarily for testing libFuzzer itself.")
+FUZZER_FLAG_STRING(exit_on_item, "Exit if an item with a given sha1 sum"
+    " was added to the corpus. "
+    "Used primarily for testing libFuzzer itself.")
+FUZZER_FLAG_INT(ignore_remaining_args, 0, "If 1, ignore all arguments passed "
+                "after this one. Useful for fuzzers that need to do their own "
+                "argument parsing.")
+FUZZER_FLAG_STRING(focus_function, "Experimental. "
+     "Fuzzing will focus on inputs that trigger calls to this function. "
+     "If -focus_function=auto and -data_flow_trace is used, libFuzzer "
+     "will choose the focus functions automatically.")
+FUZZER_FLAG_INT(entropic, 0, "Experimental. Enables entropic power schedule.")
+FUZZER_FLAG_INT(entropic_feature_frequency_threshold, 0xFF, "Experimental. If "
+     "entropic is enabled, all features which are observed less often than "
+     "the specified value are considered as rare.")
+FUZZER_FLAG_INT(entropic_number_of_rarest_features, 100, "Experimental. If "
+     "entropic is enabled, we keep track of the frequencies only for the "
+     "Top-X least abundant features (union features that are considered as "
+     "rare).")
+FUZZER_FLAG_INT(entropic_scale_per_exec_time, 0, "Experimental. If 1, "
+     "the Entropic power schedule gets scaled based on the input execution "
+     "time. Inputs with lower execution time get scheduled more (up to 30x). "
+     "Note that, if 1, fuzzer stops from being deterministic even if a "
+     "non-zero random seed is given.")
+
+FUZZER_FLAG_INT(analyze_dict, 0, "Experimental")
+FUZZER_DEPRECATED_FLAG(use_clang_coverage)
+FUZZER_FLAG_STRING(data_flow_trace, "Experimental: use the data flow trace")
+FUZZER_FLAG_STRING(collect_data_flow,
+                   "Experimental: collect the data flow trace")
+
+FUZZER_FLAG_INT(create_missing_dirs, 0, "Automatically attempt to create "
+     "directories for arguments that would normally expect them to already "
+     "exist (i.e. artifact_prefix, exact_artifact_path, features_dir, corpus)")
-- 
cgit 1.4.1


From 207cbd5cf7c1956969f42e89bfcb9a0ab451e351 Mon Sep 17 00:00:00 2001
From: van Hauser <vh@thc.org>
Date: Mon, 21 Sep 2020 15:47:10 +0200
Subject: fix and update libfuzzer custom mutator

---
 custom_mutators/libfuzzer/FuzzerDriver.cpp         |  19 +-
 .../libfuzzer/FuzzerExtFunctionsDlsym.cpp          |   4 +-
 .../libfuzzer/FuzzerExtFunctionsWeak.cpp           |   7 +-
 .../libfuzzer/FuzzerExtFunctionsWindows.cpp        |  23 +-
 custom_mutators/libfuzzer/FuzzerFlags.def          |   5 +-
 custom_mutators/libfuzzer/FuzzerInterceptors.cpp   | 290 +++++++++++++++++++++
 custom_mutators/libfuzzer/FuzzerLoop.cpp           |   2 +-
 custom_mutators/libfuzzer/FuzzerMain.cpp           |  26 ++
 custom_mutators/libfuzzer/FuzzerMutate.cpp         |  19 +-
 custom_mutators/libfuzzer/FuzzerMutate.h           |   5 +-
 custom_mutators/libfuzzer/FuzzerOptions.h          |   2 +-
 custom_mutators/libfuzzer/Makefile                 |  54 ++--
 custom_mutators/libfuzzer/README.md                |   2 +-
 custom_mutators/libfuzzer/libfuzzer.cpp            |   2 +-
 14 files changed, 387 insertions(+), 73 deletions(-)
 create mode 100644 custom_mutators/libfuzzer/FuzzerInterceptors.cpp
 create mode 100644 custom_mutators/libfuzzer/FuzzerMain.cpp

(limited to 'custom_mutators/libfuzzer/FuzzerFlags.def')

diff --git a/custom_mutators/libfuzzer/FuzzerDriver.cpp b/custom_mutators/libfuzzer/FuzzerDriver.cpp
index 6468a02e..c79278bd 100644
--- a/custom_mutators/libfuzzer/FuzzerDriver.cpp
+++ b/custom_mutators/libfuzzer/FuzzerDriver.cpp
@@ -77,7 +77,7 @@ struct {
 } Flags;
 
 static const FlagDescription FlagDescriptions[]{
-
+\
 #define FUZZER_DEPRECATED_FLAG(Name) \
   {#Name, "Deprecated; don't use", 0, nullptr, nullptr, nullptr},
 #define FUZZER_FLAG_INT(Name, Default, Description) \
@@ -941,23 +941,12 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
   Options.EntropicNumberOfRarestFeatures =
       (size_t)Flags.entropic_number_of_rarest_features;
   Options.EntropicScalePerExecTime = Flags.entropic_scale_per_exec_time;
-  if (Options.Entropic) {
-
-    if (!Options.FocusFunction.empty()) {
-
-      Printf(
-          "ERROR: The parameters `--entropic` and `--focus_function` cannot "
-          "be used together.\n");
-      exit(1);
-
-    }
-
+  if (!Options.FocusFunction.empty())
+    Options.Entropic = false;  // FocusFunction overrides entropic scheduling.
+  if (Options.Entropic)
     Printf("INFO: Running with entropic power schedule (0x%X, %d).\n",
            Options.EntropicFeatureFrequencyThreshold,
            Options.EntropicNumberOfRarestFeatures);
-
-  }
-
   struct EntropicOptions Entropic;
   Entropic.Enabled = Options.Entropic;
   Entropic.FeatureFrequencyThreshold =
diff --git a/custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp b/custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp
index 4a4d58fc..8009b237 100644
--- a/custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp
+++ b/custom_mutators/libfuzzer/FuzzerExtFunctionsDlsym.cpp
@@ -45,8 +45,8 @@ namespace fuzzer {
 
 ExternalFunctions::ExternalFunctions() {
 \
-  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME =
-      GetFnPtr < decltype(ExternalFunctions::NAME)>(#NAME, WARN)
+  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
+    this->NAME = GetFnPtr<decltype(ExternalFunctions::NAME)>(#NAME, WARN)
 
   #include "FuzzerExtFunctions.def"
 
diff --git a/custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp b/custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp
index caf1a7ef..c7a1d05e 100644
--- a/custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp
+++ b/custom_mutators/libfuzzer/FuzzerExtFunctionsWeak.cpp
@@ -46,9 +46,10 @@ namespace fuzzer {
 
 ExternalFunctions::ExternalFunctions() {
 \
-  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME = ::NAME;
-  CheckFnPtr(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(::NAME)),
-  #NAME, WARN);
+  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                         \
+    this->NAME = ::NAME;                                                      \
+    CheckFnPtr(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(::NAME)), \
+               #NAME, WARN);
 
   #include "FuzzerExtFunctions.def"
 
diff --git a/custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp b/custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp
index 630f352d..a727220a 100644
--- a/custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp
+++ b/custom_mutators/libfuzzer/FuzzerExtFunctionsWindows.cpp
@@ -45,16 +45,15 @@ using namespace fuzzer;
   #endif  // LIBFUZZER_MSVC
 
 extern "C" {
-
-  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)
-RETURN_TYPE NAME##Def FUNC_SIG {
-
-  Printf("ERROR: Function \"%s\" not defined.\n", #NAME);
-  exit(1);
-
-}
-
-EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
+\
+  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)         \
+    RETURN_TYPE NAME##Def FUNC_SIG {                          \
+                                                              \
+      Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
+      exit(1);                                                \
+                                                              \
+    }                                                         \
+    EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
 
   #include "FuzzerExtFunctions.def"
 
@@ -81,8 +80,8 @@ namespace fuzzer {
 
 ExternalFunctions::ExternalFunctions() {
 \
-  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) this->NAME =
-      GetFnPtr < decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
+  #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
+    this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
 
   #include "FuzzerExtFunctions.def"
 
diff --git a/custom_mutators/libfuzzer/FuzzerFlags.def b/custom_mutators/libfuzzer/FuzzerFlags.def
index c9a787e0..4d4841b1 100644
--- a/custom_mutators/libfuzzer/FuzzerFlags.def
+++ b/custom_mutators/libfuzzer/FuzzerFlags.def
@@ -171,8 +171,9 @@ FUZZER_FLAG_INT(ignore_remaining_args, 0, "If 1, ignore all arguments passed "
 FUZZER_FLAG_STRING(focus_function, "Experimental. "
      "Fuzzing will focus on inputs that trigger calls to this function. "
      "If -focus_function=auto and -data_flow_trace is used, libFuzzer "
-     "will choose the focus functions automatically.")
-FUZZER_FLAG_INT(entropic, 0, "Experimental. Enables entropic power schedule.")
+     "will choose the focus functions automatically. Disables -entropic when "
+     "specified.")
+FUZZER_FLAG_INT(entropic, 1, "Enables entropic power schedule.")
 FUZZER_FLAG_INT(entropic_feature_frequency_threshold, 0xFF, "Experimental. If "
      "entropic is enabled, all features which are observed less often than "
      "the specified value are considered as rare.")
diff --git a/custom_mutators/libfuzzer/FuzzerInterceptors.cpp b/custom_mutators/libfuzzer/FuzzerInterceptors.cpp
new file mode 100644
index 00000000..442ab79a
--- /dev/null
+++ b/custom_mutators/libfuzzer/FuzzerInterceptors.cpp
@@ -0,0 +1,290 @@
+//===-- FuzzerInterceptors.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Intercept certain libc functions to aid fuzzing.
+// Linked only when other RTs that define their own interceptors are not linked.
+//===----------------------------------------------------------------------===//
+
+#include "FuzzerPlatform.h"
+
+#if LIBFUZZER_LINUX
+
+  #define GET_CALLER_PC() __builtin_return_address(0)
+
+  #define PTR_TO_REAL(x) real_##x
+  #define REAL(x) __interception::PTR_TO_REAL(x)
+  #define FUNC_TYPE(x) x##_type
+  #define DEFINE_REAL(ret_type, func, ...)            \
+    typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
+    namespace __interception {                        \
+                                                      \
+    FUNC_TYPE(func) PTR_TO_REAL(func);                \
+                                                      \
+    }
+
+  #include <cassert>
+  #include <cstdint>
+  #include <dlfcn.h>  // for dlsym()
+
+static void *getFuncAddr(const char *name, uintptr_t wrapper_addr) {
+
+  void *addr = dlsym(RTLD_NEXT, name);
+  if (!addr) {
+
+    // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
+    // later in the library search order than the DSO that we are trying to
+    // intercept, which means that we cannot intercept this function. We still
+    // want the address of the real definition, though, so look it up using
+    // RTLD_DEFAULT.
+    addr = dlsym(RTLD_DEFAULT, name);
+
+    // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
+    // We don't want to intercept the wrapper and have it point to itself.
+    if (reinterpret_cast<uintptr_t>(addr) == wrapper_addr) addr = nullptr;
+
+  }
+
+  return addr;
+
+}
+
+static int  FuzzerInited = 0;
+static bool FuzzerInitIsRunning;
+
+static void fuzzerInit();
+
+static void ensureFuzzerInited() {
+
+  assert(!FuzzerInitIsRunning);
+  if (!FuzzerInited) { fuzzerInit(); }
+
+}
+
+static int internal_strcmp_strncmp(const char *s1, const char *s2, bool strncmp,
+                                   size_t n) {
+
+  size_t i = 0;
+  while (true) {
+
+    if (strncmp) {
+
+      if (i == n) break;
+      i++;
+
+    }
+
+    unsigned c1 = *s1;
+    unsigned c2 = *s2;
+    if (c1 != c2) return (c1 < c2) ? -1 : 1;
+    if (c1 == 0) break;
+    s1++;
+    s2++;
+
+  }
+
+  return 0;
+
+}
+
+static int internal_strncmp(const char *s1, const char *s2, size_t n) {
+
+  return internal_strcmp_strncmp(s1, s2, true, n);
+
+}
+
+static int internal_strcmp(const char *s1, const char *s2) {
+
+  return internal_strcmp_strncmp(s1, s2, false, 0);
+
+}
+
+static int internal_memcmp(const void *s1, const void *s2, size_t n) {
+
+  const uint8_t *t1 = static_cast<const uint8_t *>(s1);
+  const uint8_t *t2 = static_cast<const uint8_t *>(s2);
+  for (size_t i = 0; i < n; ++i, ++t1, ++t2)
+    if (*t1 != *t2) return *t1 < *t2 ? -1 : 1;
+  return 0;
+
+}
+
+static size_t internal_strlen(const char *s) {
+
+  size_t i = 0;
+  while (s[i])
+    i++;
+  return i;
+
+}
+
+static char *internal_strstr(const char *haystack, const char *needle) {
+
+  // This is O(N^2), but we are not using it in hot places.
+  size_t len1 = internal_strlen(haystack);
+  size_t len2 = internal_strlen(needle);
+  if (len1 < len2) return nullptr;
+  for (size_t pos = 0; pos <= len1 - len2; pos++) {
+
+    if (internal_memcmp(haystack + pos, needle, len2) == 0)
+      return const_cast<char *>(haystack) + pos;
+
+  }
+
+  return nullptr;
+
+}
+
+extern "C" {
+
+// Weak hooks forward-declared to avoid dependency on
+// <sanitizer/common_interface_defs.h>.
+void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
+                                  const void *s2, size_t n, int result);
+void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
+                                   const char *s2, size_t n, int result);
+void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
+                                       const char *s2, size_t n, int result);
+void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
+                                  const char *s2, int result);
+void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
+                                      const char *s2, int result);
+void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
+                                  const char *s2, char *result);
+void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
+                                      const char *s2, char *result);
+void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
+                                  const void *s2, size_t len2, void *result);
+
+DEFINE_REAL(int, bcmp, const void *, const void *, size_t)
+DEFINE_REAL(int, memcmp, const void *, const void *, size_t)
+DEFINE_REAL(int, strncmp, const char *, const char *, size_t)
+DEFINE_REAL(int, strcmp, const char *, const char *)
+DEFINE_REAL(int, strncasecmp, const char *, const char *, size_t)
+DEFINE_REAL(int, strcasecmp, const char *, const char *)
+DEFINE_REAL(char *, strstr, const char *, const char *)
+DEFINE_REAL(char *, strcasestr, const char *, const char *)
+DEFINE_REAL(void *, memmem, const void *, size_t, const void *, size_t)
+
+ATTRIBUTE_INTERFACE int bcmp(const char *s1, const char *s2, size_t n) {
+
+  if (!FuzzerInited) return internal_memcmp(s1, s2, n);
+  int result = REAL(bcmp)(s1, s2, n);
+  __sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int memcmp(const void *s1, const void *s2, size_t n) {
+
+  if (!FuzzerInited) return internal_memcmp(s1, s2, n);
+  int result = REAL(memcmp)(s1, s2, n);
+  __sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int strncmp(const char *s1, const char *s2, size_t n) {
+
+  if (!FuzzerInited) return internal_strncmp(s1, s2, n);
+  int result = REAL(strncmp)(s1, s2, n);
+  __sanitizer_weak_hook_strncmp(GET_CALLER_PC(), s1, s2, n, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int strcmp(const char *s1, const char *s2) {
+
+  if (!FuzzerInited) return internal_strcmp(s1, s2);
+  int result = REAL(strcmp)(s1, s2);
+  __sanitizer_weak_hook_strcmp(GET_CALLER_PC(), s1, s2, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int strncasecmp(const char *s1, const char *s2, size_t n) {
+
+  ensureFuzzerInited();
+  int result = REAL(strncasecmp)(s1, s2, n);
+  __sanitizer_weak_hook_strncasecmp(GET_CALLER_PC(), s1, s2, n, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE int strcasecmp(const char *s1, const char *s2) {
+
+  ensureFuzzerInited();
+  int result = REAL(strcasecmp)(s1, s2);
+  __sanitizer_weak_hook_strcasecmp(GET_CALLER_PC(), s1, s2, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE char *strstr(const char *s1, const char *s2) {
+
+  if (!FuzzerInited) return internal_strstr(s1, s2);
+  char *result = REAL(strstr)(s1, s2);
+  __sanitizer_weak_hook_strstr(GET_CALLER_PC(), s1, s2, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE char *strcasestr(const char *s1, const char *s2) {
+
+  ensureFuzzerInited();
+  char *result = REAL(strcasestr)(s1, s2);
+  __sanitizer_weak_hook_strcasestr(GET_CALLER_PC(), s1, s2, result);
+  return result;
+
+}
+
+ATTRIBUTE_INTERFACE
+void *memmem(const void *s1, size_t len1, const void *s2, size_t len2) {
+
+  ensureFuzzerInited();
+  void *result = REAL(memmem)(s1, len1, s2, len2);
+  __sanitizer_weak_hook_memmem(GET_CALLER_PC(), s1, len1, s2, len2, result);
+  return result;
+
+}
+
+__attribute__((section(".preinit_array"),
+               used)) static void (*__local_fuzzer_preinit)(void) = fuzzerInit;
+
+}  // extern "C"
+
+static void fuzzerInit() {
+
+  assert(!FuzzerInitIsRunning);
+  if (FuzzerInited) return;
+  FuzzerInitIsRunning = true;
+
+  REAL(bcmp) = reinterpret_cast<memcmp_type>(
+      getFuncAddr("bcmp", reinterpret_cast<uintptr_t>(&bcmp)));
+  REAL(memcmp) = reinterpret_cast<memcmp_type>(
+      getFuncAddr("memcmp", reinterpret_cast<uintptr_t>(&memcmp)));
+  REAL(strncmp) = reinterpret_cast<strncmp_type>(
+      getFuncAddr("strncmp", reinterpret_cast<uintptr_t>(&strncmp)));
+  REAL(strcmp) = reinterpret_cast<strcmp_type>(
+      getFuncAddr("strcmp", reinterpret_cast<uintptr_t>(&strcmp)));
+  REAL(strncasecmp) = reinterpret_cast<strncasecmp_type>(
+      getFuncAddr("strncasecmp", reinterpret_cast<uintptr_t>(&strncasecmp)));
+  REAL(strcasecmp) = reinterpret_cast<strcasecmp_type>(
+      getFuncAddr("strcasecmp", reinterpret_cast<uintptr_t>(&strcasecmp)));
+  REAL(strstr) = reinterpret_cast<strstr_type>(
+      getFuncAddr("strstr", reinterpret_cast<uintptr_t>(&strstr)));
+  REAL(strcasestr) = reinterpret_cast<strcasestr_type>(
+      getFuncAddr("strcasestr", reinterpret_cast<uintptr_t>(&strcasestr)));
+  REAL(memmem) = reinterpret_cast<memmem_type>(
+      getFuncAddr("memmem", reinterpret_cast<uintptr_t>(&memmem)));
+
+  FuzzerInitIsRunning = false;
+  FuzzerInited = 1;
+
+}
+
+#endif
+
diff --git a/custom_mutators/libfuzzer/FuzzerLoop.cpp b/custom_mutators/libfuzzer/FuzzerLoop.cpp
index 49187b30..201883f0 100644
--- a/custom_mutators/libfuzzer/FuzzerLoop.cpp
+++ b/custom_mutators/libfuzzer/FuzzerLoop.cpp
@@ -752,7 +752,7 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U, const char *Text) {
   if (Options.Verbosity) {
 
     Printf(" L: %zd/%zd ", U.size(), Corpus.MaxInputSize());
-    MD.PrintMutationSequence();
+    MD.PrintMutationSequence(Options.Verbosity >= 2);
     Printf("\n");
 
   }
diff --git a/custom_mutators/libfuzzer/FuzzerMain.cpp b/custom_mutators/libfuzzer/FuzzerMain.cpp
new file mode 100644
index 00000000..b02c88e9
--- /dev/null
+++ b/custom_mutators/libfuzzer/FuzzerMain.cpp
@@ -0,0 +1,26 @@
+//===- FuzzerMain.cpp - main() function and flags -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// main() and flags.
+//===----------------------------------------------------------------------===//
+
+#include "FuzzerDefs.h"
+#include "FuzzerPlatform.h"
+
+extern "C" {
+
+// This function should be defined by the user.
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
+
+}  // extern "C"
+
+ATTRIBUTE_INTERFACE int main(int argc, char **argv) {
+
+  return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
+
+}
+
diff --git a/custom_mutators/libfuzzer/FuzzerMutate.cpp b/custom_mutators/libfuzzer/FuzzerMutate.cpp
index 8faf6918..eebae39b 100644
--- a/custom_mutators/libfuzzer/FuzzerMutate.cpp
+++ b/custom_mutators/libfuzzer/FuzzerMutate.cpp
@@ -17,7 +17,8 @@
 
 namespace fuzzer {
 
-const size_t Dictionary::kMaxDictSize;
+const size_t        Dictionary::kMaxDictSize;
+static const size_t kMaxMutationsToPrint = 10;
 
 static void PrintASCII(const Word &W, const char *PrintAfter) {
 
@@ -608,18 +609,24 @@ void MutationDispatcher::PrintRecommendedDictionary() {
 
 }
 
-void MutationDispatcher::PrintMutationSequence() {
+void MutationDispatcher::PrintMutationSequence(bool Verbose) {
 
   Printf("MS: %zd ", CurrentMutatorSequence.size());
-  for (auto M : CurrentMutatorSequence)
-    Printf("%s-", M.Name);
+  size_t EntriesToPrint =
+      Verbose ? CurrentMutatorSequence.size()
+              : std::min(kMaxMutationsToPrint, CurrentMutatorSequence.size());
+  for (size_t i = 0; i < EntriesToPrint; i++)
+    Printf("%s-", CurrentMutatorSequence[i].Name);
   if (!CurrentDictionaryEntrySequence.empty()) {
 
     Printf(" DE: ");
-    for (auto DE : CurrentDictionaryEntrySequence) {
+    EntriesToPrint = Verbose ? CurrentDictionaryEntrySequence.size()
+                             : std::min(kMaxMutationsToPrint,
+                                        CurrentDictionaryEntrySequence.size());
+    for (size_t i = 0; i < EntriesToPrint; i++) {
 
       Printf("\"");
-      PrintASCII(DE->GetW(), "\"-");
+      PrintASCII(CurrentDictionaryEntrySequence[i]->GetW(), "\"-");
 
     }
 
diff --git a/custom_mutators/libfuzzer/FuzzerMutate.h b/custom_mutators/libfuzzer/FuzzerMutate.h
index 3ce3159f..37fd6100 100644
--- a/custom_mutators/libfuzzer/FuzzerMutate.h
+++ b/custom_mutators/libfuzzer/FuzzerMutate.h
@@ -24,8 +24,9 @@ public:
   ~MutationDispatcher() {}
   /// Indicate that we are about to start a new sequence of mutations.
   void StartMutationSequence();
-  /// Print the current sequence of mutations.
-  void PrintMutationSequence();
+  /// Print the current sequence of mutations. Only prints the full sequence
+  /// when Verbose is true.
+  void PrintMutationSequence(bool Verbose = true);
   /// Return the current sequence of mutations.
   std::string MutationSequence();
   /// Indicate that the current sequence of mutations was successful.
diff --git a/custom_mutators/libfuzzer/FuzzerOptions.h b/custom_mutators/libfuzzer/FuzzerOptions.h
index 706e1c64..20b810b2 100644
--- a/custom_mutators/libfuzzer/FuzzerOptions.h
+++ b/custom_mutators/libfuzzer/FuzzerOptions.h
@@ -46,7 +46,7 @@ struct FuzzingOptions {
   size_t MaxNumberOfRuns = -1L;
   int ReportSlowUnits = 10;
   bool OnlyASCII = false;
-  bool Entropic = false;
+  bool Entropic = true;
   size_t EntropicFeatureFrequencyThreshold = 0xFF;
   size_t EntropicNumberOfRarestFeatures = 100;
   bool EntropicScalePerExecTime = false;
diff --git a/custom_mutators/libfuzzer/Makefile b/custom_mutators/libfuzzer/Makefile
index 34a358ac..95402f6c 100644
--- a/custom_mutators/libfuzzer/Makefile
+++ b/custom_mutators/libfuzzer/Makefile
@@ -1,81 +1,81 @@
 
-#CFLAGS = -O3 -funroll-loops -fPIC -fpermissive -std=c++11
-CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11
-CC ?= clang++
+CFLAGS = -g -O3 -funroll-loops -fPIC -fpermissive -std=c++11
+#CFLAGS = -g -O0 -fPIC -fpermissive -std=c++11
+CXX ?= clang++
 
 all: libfuzzer-mutator.so
 
 FuzzerCrossOver.o:	FuzzerCrossOver.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerDataFlowTrace.o:	FuzzerDataFlowTrace.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerDriver.o:	FuzzerDriver.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerExtFunctionsDlsym.o:	FuzzerExtFunctionsDlsym.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerExtFunctionsWeak.o:	FuzzerExtFunctionsWeak.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerExtFunctionsWindows.o:	FuzzerExtFunctionsWindows.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerExtraCounters.o:	FuzzerExtraCounters.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerFork.o:	FuzzerFork.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerIO.o:	FuzzerIO.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerIOPosix.o:	FuzzerIOPosix.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerIOWindows.o:	FuzzerIOWindows.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerLoop.o:	FuzzerLoop.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerMerge.o:	FuzzerMerge.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerMutate.o:	FuzzerMutate.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerSHA1.o:	FuzzerSHA1.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerTracePC.o:	FuzzerTracePC.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtil.o:	FuzzerUtil.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilDarwin.o:	FuzzerUtilDarwin.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilFuchsia.o:	FuzzerUtilFuchsia.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilLinux.o:	FuzzerUtilLinux.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilPosix.o:	FuzzerUtilPosix.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 FuzzerUtilWindows.o:	FuzzerUtilWindows.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 libfuzzer.o:	libfuzzer.cpp
-	$(CC) $(CFLAGS) -I../../include -I. -c $^
+	$(CXX) $(CFLAGS) -I../../include -I. -c $^
 
 libfuzzer-mutator.so:	FuzzerCrossOver.o FuzzerDataFlowTrace.o FuzzerDriver.o FuzzerExtFunctionsDlsym.o FuzzerExtFunctionsWeak.o FuzzerExtFunctionsWindows.o FuzzerExtraCounters.o FuzzerFork.o FuzzerIO.o FuzzerIOPosix.o FuzzerIOWindows.o FuzzerLoop.o FuzzerMerge.o FuzzerMutate.o FuzzerSHA1.o FuzzerTracePC.o FuzzerUtil.o FuzzerUtilDarwin.o FuzzerUtilFuchsia.o FuzzerUtilLinux.o FuzzerUtilPosix.o FuzzerUtilWindows.o libfuzzer.o
-	$(CC) $(CFLAGS) -I../../include -I. -shared -o libfuzzer-mutator.so *.o
+	$(CXX) $(CFLAGS) -I../../include -I. -shared -o libfuzzer-mutator.so *.o
 
 clean:
 	rm -f *.o *~ *.so core
diff --git a/custom_mutators/libfuzzer/README.md b/custom_mutators/libfuzzer/README.md
index a773da02..4783f2ca 100644
--- a/custom_mutators/libfuzzer/README.md
+++ b/custom_mutators/libfuzzer/README.md
@@ -21,4 +21,4 @@ are done.
 
 > Original repository: https://github.com/llvm/llvm-project
 > Path: compiler-rt/lib/fuzzer/*.{h|cpp}
-> Source commit: d4b88ac1658d681e143482336cac27c6a74b8b24
+> Source commit: df3e903655e2499968fc7af64fb5fa52b2ee79bb
diff --git a/custom_mutators/libfuzzer/libfuzzer.cpp b/custom_mutators/libfuzzer/libfuzzer.cpp
index cf41af2d..5e37df66 100644
--- a/custom_mutators/libfuzzer/libfuzzer.cpp
+++ b/custom_mutators/libfuzzer/libfuzzer.cpp
@@ -72,7 +72,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
 /* When a new queue entry is added we check if there are new dictionary
    entries to add to honggfuzz structure */
-#if ß
+#if 0
 extern "C" void afl_custom_queue_new_entry(my_mutator_t * data,
                                            const uint8_t *filename_new_queue,
                                            const uint8_t *filename_orig_queue) {
-- 
cgit 1.4.1

