aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Meumertzheim <fabian@meumertzhe.im>2021-03-22 14:49:05 +0100
committerFabian Meumertzheim <fabian@meumertzhe.im>2021-03-22 14:57:55 +0100
commitf938920a37042376e56c7ac771886565bcfe8b5e (patch)
treec07b7a79e35e0999b59d81d563da948ec542666e
parent71ac55c6fc9d808bcc8a8e8d895f7f20141bec86 (diff)
downloadjazzer-api-f938920a37042376e56c7ac771886565bcfe8b5e.tar.gz
Revert "Do not intercept JVM-internal C stdlib calls (#45)"
This reverts commit 71ac55c6fc9d808bcc8a8e8d895f7f20141bec86.
-rw-r--r--BUILD.bazel1
-rw-r--r--WORKSPACE.bazel27
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt1
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt2
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel1
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/instrumentor/Instrumentor.kt1
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/runtime/NativeLibHooks.java35
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceDataFlowNativeCallbacks.java2
-rw-r--r--bazel/fuzz_target.bzl8
-rwxr-xr-xbazel/fuzz_target_test_wrapper.sh1
-rw-r--r--driver/BUILD.bazel17
-rw-r--r--driver/fuzz_target_runner.cpp2
-rw-r--r--driver/libfuzzer_callbacks.cpp115
-rw-r--r--driver/libfuzzer_driver.cpp18
-rw-r--r--driver/libfuzzer_fuzz_target.cpp31
-rw-r--r--driver/sanitizer_symbols_for_tests.cpp2
-rw-r--r--examples/BUILD.bazel1
-rw-r--r--third_party/BUILD.bazel3
-rw-r--r--third_party/jni/BUILD.bazel2
-rw-r--r--third_party/libFuzzer-make-interceptors-configurable.patch109
-rw-r--r--third_party/libFuzzer-pass-death-callback-to-jazzer.patch28
-rw-r--r--third_party/libFuzzer.BUILD21
22 files changed, 52 insertions, 376 deletions
diff --git a/BUILD.bazel b/BUILD.bazel
index 3f81fdd2..8c30be59 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -2,6 +2,7 @@ load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "define_kt_toolchain")
load("@io_bazel_rules_kotlin//kotlin/internal:opts.bzl", "kt_javac_options", "kt_kotlinc_options")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
+load("@rules_jvm_external//:defs.bzl", "java_export")
kt_kotlinc_options(
name = "kotlinc_options",
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel
index d54cdba4..c6a0f0cb 100644
--- a/WORKSPACE.bazel
+++ b/WORKSPACE.bazel
@@ -14,14 +14,8 @@ http_archive(
],
)
-# bazelbuild/rules_python
-http_archive(
- name = "rules_python",
- sha256 = "b6d46438523a3ec0f3cead544190ee13223a52f6a6765a29eae7b7cc24cc83a0",
- url = "https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz",
-)
-
# bazelbuild/bazel-skylib
+
http_archive(
name = "bazel_skylib",
sha256 = "ebdf850bfef28d923a2cc67ddca86355a449b5e4f38b0a70e584dc24e5984aa6",
@@ -84,6 +78,7 @@ http_archive(
urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/%s/rules_kotlin_release.tgz" % rules_kotlin_version],
)
+load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains")
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories")
kotlin_repositories()
@@ -149,6 +144,8 @@ rules_pkg_version = "0.3.0"
rules_pkg_sha = "6b5969a7acd7b60c02f816773b06fcf32fbe8ba0c7919ccdc2df4f8fb923804a"
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
http_archive(
name = "rules_pkg",
sha256 = rules_pkg_sha,
@@ -163,6 +160,7 @@ load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
rules_pkg_dependencies()
# bazelbuild/rules_foreign_cc
+
rules_foreign_cc_commit = "da99da47a0befc3dfbf65739190cd374f836f21d"
http_archive(
@@ -177,6 +175,7 @@ load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependen
rules_foreign_cc_dependencies()
# libjpeg_turbo
+
http_archive(
name = "libjpeg_turbo",
build_file = "//third_party:libjpeg_turbo.BUILD",
@@ -186,6 +185,7 @@ http_archive(
)
# JaCoCo
+
jacoco_commit = "178d49870056b8a1f8ea6915e804d28b0dda5609"
jacoco_sha = "da48fb5ae4ec3ffc659d4de18232aedea99476935f4ce4b0605f2d6aa1dc2553"
@@ -200,16 +200,3 @@ http_archive(
strip_prefix = "jacoco-%s" % jacoco_commit,
url = "https://github.com/jacoco/jacoco/archive/178d49870056b8a1f8ea6915e804d28b0dda5609.tar.gz",
)
-
-# libFuzzer
-http_archive(
- name = "libFuzzer",
- build_file = "//third_party:libFuzzer.BUILD",
- patches = [
- "//third_party:libFuzzer-make-interceptors-configurable.patch",
- "//third_party:libFuzzer-pass-death-callback-to-jazzer.patch",
- ],
- sha256 = "a78949f86fc9852f51b11ceb3e6c2c61bb6e4ebb073198cebddc82451f708adf",
- strip_prefix = "llvm-project-llvmorg-12.0.0-rc3",
- url = "https://github.com/llvm/llvm-project/archive/llvmorg-12.0.0-rc3.tar.gz",
-)
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt b/agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt
index 47ebab3c..43e8a488 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt
+++ b/agent/src/main/java/com/code_intelligence/jazzer/agent/Agent.kt
@@ -69,7 +69,6 @@ fun premain(agentArgs: String?, instrumentation: Instrumentation) {
"div" -> setOf(InstrumentationType.DIV)
"gep" -> setOf(InstrumentationType.GEP)
"indir" -> setOf(InstrumentationType.INDIR)
- "native" -> setOf(InstrumentationType.NATIVE)
"all" -> InstrumentationType.values().toSet()
else -> {
println("WARN: Skipping unknown instrumentation type $it")
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt b/agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt
index 35ee3959..0e304f45 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt
+++ b/agent/src/main/java/com/code_intelligence/jazzer/agent/RuntimeInstrumentor.kt
@@ -18,7 +18,6 @@ import com.code_intelligence.jazzer.instrumentor.ClassInstrumentor
import com.code_intelligence.jazzer.instrumentor.Hook
import com.code_intelligence.jazzer.instrumentor.InstrumentationType
import com.code_intelligence.jazzer.instrumentor.loadHooks
-import com.code_intelligence.jazzer.runtime.NativeLibHooks
import com.code_intelligence.jazzer.runtime.TraceCmpHooks
import com.code_intelligence.jazzer.runtime.TraceDivHooks
import com.code_intelligence.jazzer.runtime.TraceIndirHooks
@@ -82,7 +81,6 @@ internal class RuntimeInstrumentor(
InstrumentationType.CMP -> TraceCmpHooks::class.java
InstrumentationType.DIV -> TraceDivHooks::class.java
InstrumentationType.INDIR -> TraceIndirHooks::class.java
- InstrumentationType.NATIVE -> NativeLibHooks::class.java
else -> null
}
}
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel b/agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel
index ee16b40c..d68ec102 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel
+++ b/agent/src/main/java/com/code_intelligence/jazzer/generated/BUILD.bazel
@@ -1,4 +1,3 @@
-load("@rules_java//java:defs.bzl", "java_binary", "java_library")
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")
java_binary(
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/instrumentor/Instrumentor.kt b/agent/src/main/java/com/code_intelligence/jazzer/instrumentor/Instrumentor.kt
index 78793842..50904e61 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/instrumentor/Instrumentor.kt
+++ b/agent/src/main/java/com/code_intelligence/jazzer/instrumentor/Instrumentor.kt
@@ -23,7 +23,6 @@ enum class InstrumentationType {
DIV,
GEP,
INDIR,
- NATIVE,
}
internal interface Instrumentor {
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/runtime/NativeLibHooks.java b/agent/src/main/java/com/code_intelligence/jazzer/runtime/NativeLibHooks.java
deleted file mode 100644
index 495cad7c..00000000
--- a/agent/src/main/java/com/code_intelligence/jazzer/runtime/NativeLibHooks.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2021 Code Intelligence GmbH
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.code_intelligence.jazzer.runtime;
-
-import com.code_intelligence.jazzer.api.HookType;
-import com.code_intelligence.jazzer.api.MethodHook;
-import java.lang.invoke.MethodHandle;
-
-@SuppressWarnings("unused")
-final public class NativeLibHooks {
- @MethodHook(type = HookType.BEFORE, targetClassName = "java.lang.Runtime",
- targetMethod = "loadLibrary", targetMethodDescriptor = "(Ljava/lang/String;)V")
- @MethodHook(type = HookType.BEFORE, targetClassName = "java.lang.System",
- targetMethod = "loadLibrary", targetMethodDescriptor = "(Ljava/lang/String;)V")
- @MethodHook(type = HookType.BEFORE, targetClassName = "java.lang.Runtime", targetMethod = "load",
- targetMethodDescriptor = "(Ljava/lang/String;)V")
- @MethodHook(type = HookType.BEFORE, targetClassName = "java.lang.System", targetMethod = "load",
- targetMethodDescriptor = "(Ljava/lang/String;)V")
- public static void
- loadLibraryHook(MethodHandle method, Object thisObject, Object[] arguments, int hookId) {
- TraceDataFlowNativeCallbacks.handleLibraryLoad();
- }
-}
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceDataFlowNativeCallbacks.java b/agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceDataFlowNativeCallbacks.java
index f779cec6..147386ae 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceDataFlowNativeCallbacks.java
+++ b/agent/src/main/java/com/code_intelligence/jazzer/runtime/TraceDataFlowNativeCallbacks.java
@@ -73,6 +73,4 @@ final public class TraceDataFlowNativeCallbacks {
// as the stack layout required for the call can't be achieved without local variables.
return Long.compare(arg1, arg2);
}
-
- public static native void handleLibraryLoad();
}
diff --git a/bazel/fuzz_target.bzl b/bazel/fuzz_target.bzl
index 9f2fe2d5..04cf32e3 100644
--- a/bazel/fuzz_target.bzl
+++ b/bazel/fuzz_target.bzl
@@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@rules_java//java:defs.bzl", "java_binary")
-
def java_fuzz_target_test(
name,
target_class,
@@ -31,12 +29,14 @@ def java_fuzz_target_test(
"Jazzer-Fuzz-Target-Class: %s" % target_class,
]
if hook_classes:
- deploy_manifest_lines.append("Jazzer-Hook-Classes: %s" % ":".join(hook_classes))
+ deploy_manifest_lines += [
+ "Jazzer-Hook-Classes: %s" % ":".join(hook_classes),
+ ]
# Deps can only be specified on java_binary targets with sources, which
# excludes e.g. Kotlin libraries wrapped into java_binary via runtime_deps.
target_deps = deps + ["//agent/src/main/java/com/code_intelligence/jazzer/api"] if srcs else []
- java_binary(
+ native.java_binary(
name = target_name,
srcs = srcs,
visibility = ["//visibility:private"],
diff --git a/bazel/fuzz_target_test_wrapper.sh b/bazel/fuzz_target_test_wrapper.sh
index 061ed3ae..7a2a9f7f 100755
--- a/bazel/fuzz_target_test_wrapper.sh
+++ b/bazel/fuzz_target_test_wrapper.sh
@@ -24,6 +24,5 @@ if [ $exit_code -eq 77 ] || [ $exit_code -eq 76 ]
then
exit 0
else
- echo "Unexpected exit code: $exit_code"
exit 1
fi
diff --git a/driver/BUILD.bazel b/driver/BUILD.bazel
index 599fcac0..2c17b947 100644
--- a/driver/BUILD.bazel
+++ b/driver/BUILD.bazel
@@ -1,4 +1,9 @@
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
+load(
+ "@bazel_tools//tools/jdk:default_java_toolchain.bzl",
+ "java_runtime_files",
+)
+load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
cc_library(
name = "sanitizer_hooks_with_pc",
@@ -42,9 +47,6 @@ cc_library(
"signal_handler.h",
"utils.h",
],
- linkopts = [
- "-ldl",
- ],
visibility = ["//visibility:public"],
deps = [
":sanitizer_hooks_with_pc",
@@ -62,10 +64,13 @@ cc_binary(
data = [
"//agent:jazzer_agent_deploy.jar",
],
+ linkopts = [
+ "-Wl,--wrap=__sanitizer_set_death_callback",
+ "-fsanitize=fuzzer",
+ ],
visibility = ["//visibility:public"],
deps = [
":jvm_tooling_lib",
- "@libFuzzer",
],
)
@@ -76,12 +81,12 @@ cc_binary(
"//agent:jazzer_agent_deploy.jar",
],
linkopts = [
- "-fsanitize=address",
+ "-Wl,--wrap=__sanitizer_set_death_callback",
+ "-fsanitize=fuzzer,address",
],
visibility = ["//visibility:public"],
deps = [
":jvm_tooling_lib",
- "@libFuzzer",
],
)
diff --git a/driver/fuzz_target_runner.cpp b/driver/fuzz_target_runner.cpp
index 0d83264d..ae3602e0 100644
--- a/driver/fuzz_target_runner.cpp
+++ b/driver/fuzz_target_runner.cpp
@@ -166,7 +166,7 @@ FuzzTargetRunner::FuzzTargetRunner(
LOG(ERROR) << "Invalid dedup token (expected up to 16 hex digits): '"
<< str_token << "'";
// Don't let libFuzzer print a crash stack trace.
- _Exit(1);
+ std::quick_exit(1);
}
}
}
diff --git a/driver/libfuzzer_callbacks.cpp b/driver/libfuzzer_callbacks.cpp
index 398d69d8..d1c754af 100644
--- a/driver/libfuzzer_callbacks.cpp
+++ b/driver/libfuzzer_callbacks.cpp
@@ -14,14 +14,10 @@
#include "libfuzzer_callbacks.h"
-#include <fstream>
+#include <algorithm>
#include <iostream>
-#include <utility>
-#include <vector>
-#include "absl/strings/match.h"
#include "absl/strings/str_format.h"
-#include "absl/strings/str_split.h"
#include "glog/logging.h"
#include "sanitizer_hooks_with_pc.h"
#include "third_party/jni/jni.h"
@@ -176,106 +172,6 @@ void JNICALL libfuzzerPcIndirCallback(JNIEnv &env, jclass cls, jint caller_id,
static_cast<uintptr_t>(callee_id));
}
-bool is_using_native_libraries = false;
-std::vector<std::pair<uintptr_t, uintptr_t>> ignore_for_interception_ranges;
-
-extern "C" [[maybe_unused]] bool __sanitizer_weak_is_relevant_pc(
- void *caller_pc) {
- // If the fuzz target is not using native libraries, calls to strcmp, memcmp,
- // etc. should never be intercepted. The values reported if they were at best
- // duplicate the values received from our bytecode instrumentation and at
- // worst pollute the table of recent compares with string internal to the JDK.
- if (!is_using_native_libraries) return false;
- // If the fuzz target is using native libraries, intercept calls only if they
- // don't originate from those address ranges that are known to belong to the
- // JDK.
- bool should_intercept = std::none_of(
- ignore_for_interception_ranges.cbegin(),
- ignore_for_interception_ranges.cend(), [caller_pc](const auto &range) {
- uintptr_t start;
- uintptr_t end;
- std::tie(start, end) = range;
- auto address = reinterpret_cast<uintptr_t>(caller_pc);
- return start <= address && address <= end;
- });
- if (should_intercept) {
- std::cout << " PC: " << caller_pc << std::endl;
- }
- return should_intercept;
-}
-
-/**
- * Adds the address ranges of executable segmentes of the library lib_name to
- * the ignorelist for C standard library function interception (strcmp, memcmp,
- * ...).
- */
-void ignoreLibraryForInterception(const std::string &lib_name) {
- const auto num_address_ranges = ignore_for_interception_ranges.size();
- std::ifstream loaded_libs("/proc/self/maps");
- std::string line;
- while (std::getline(loaded_libs, line)) {
- if (!absl::StrContains(line, lib_name)) continue;
- // clang-format off
- // A typical line looks as follows:
- // 7f15356c9000-7f1536367000 r-xp 0020d000 fd:01 19275673 /usr/lib/jvm/java-15-openjdk-amd64/lib/server/libjvm.so
- // clang-format on
- std::vector<std::string_view> parts =
- absl::StrSplit(line, ' ', absl::SkipEmpty());
- if (parts.size() != 6) {
- std::cout << "ERROR: Invalid format for /proc/self/maps\n"
- << line << std::endl;
- exit(1);
- }
- // Skip non-executable address ranges.
- if (!absl::StrContains(parts[1], 'x')) continue;
- std::string_view range_str = parts[0];
- std::vector<std::string> range = absl::StrSplit(range_str, '-');
- if (range.size() != 2) {
- std::cout
- << "ERROR: Unexpected address range format in /proc/self/maps line: "
- << range_str << std::endl;
- exit(1);
- }
- std::size_t pos;
- auto start = std::stoull(range[0], &pos, 16);
- if (pos != range[0].size()) {
- std::cout
- << "ERROR: Unexpected address range format in /proc/self/maps line: "
- << range_str << std::endl;
- exit(1);
- }
- auto end = std::stoull(range[1], &pos, 16);
- if (pos != range[0].size()) {
- std::cout
- << "ERROR: Unexpected address range format in /proc/self/maps line: "
- << range_str << std::endl;
- exit(1);
- }
- ignore_for_interception_ranges.emplace_back(start, end);
- }
- const auto num_code_segments =
- ignore_for_interception_ranges.size() - num_address_ranges;
- LOG(INFO) << "added " << num_code_segments
- << " code segment of native library " << lib_name
- << " to interceptor ignorelist";
-}
-
-const std::vector<std::string> kLibrariesToIgnoreForInterception = {
- // The driver executable itself can be treated just like a library.
- "jazzer_driver", "libinstrument.so", "libjava.so",
- "libjimage.so", "libjli.so", "libjvm.so",
- "libnet.so", "libverify.so", "libzip.so",
-};
-
-void JNICALL handleLibraryLoad(JNIEnv &env, jclass cls) {
- if (is_using_native_libraries) return;
- LOG(INFO) << "detected a native library load, enabling interception for libc "
- "functions";
- is_using_native_libraries = true;
- for (const auto &lib_name : kLibrariesToIgnoreForInterception)
- ignoreLibraryForInterception(lib_name);
-}
-
void registerCallback(JNIEnv &env, const char *java_hooks_class_name,
const JNINativeMethod *methods, int num_methods) {
auto java_hooks_class = env.FindClass(java_hooks_class_name);
@@ -367,15 +263,6 @@ bool registerFuzzerCallbacks(JNIEnv &env) {
sizeof(indir_methods) / sizeof(indir_methods[0]));
}
- {
- JNINativeMethod native_methods[]{{(char *)"handleLibraryLoad",
- (char *)"()V",
- (void *)(&handleLibraryLoad)}};
-
- registerCallback(env, kLibfuzzerTraceDataFlowHooksClass, native_methods,
- sizeof(native_methods) / sizeof(native_methods[0]));
- }
-
return env.ExceptionCheck();
}
diff --git a/driver/libfuzzer_driver.cpp b/driver/libfuzzer_driver.cpp
index 4d51104e..2accc40d 100644
--- a/driver/libfuzzer_driver.cpp
+++ b/driver/libfuzzer_driver.cpp
@@ -14,8 +14,6 @@
#include "libfuzzer_driver.h"
-#include <dlfcn.h>
-
#include <algorithm>
#include <filesystem>
#include <fstream>
@@ -50,16 +48,13 @@ DECLARE_bool(fake_pcs);
// Defined in jvm_tooling.cpp
DECLARE_string(id_sync_file);
-// We apply a patch to libFuzzer to make it call this function instead of
-// __sanitizer_set_death_callback to pass us the death callback.
-extern "C" [[maybe_unused]] void __jazzer_set_death_callback(
- void (*callback)()) {
+extern "C" void __real___sanitizer_set_death_callback(void (*callback)());
+
+// We use the linker opt -Wl,--wrap=__sanitizer_set_death_callback to wrap the
+// symbol defined by sanitizers_common to receive libFuzzer's death callback.
+extern "C" void __wrap___sanitizer_set_death_callback(void (*callback)()) {
jazzer::AbstractLibfuzzerDriver::libfuzzer_print_crashing_input_ = callback;
- void *sanitizer_set_death_callback =
- dlsym(RTLD_NEXT, "__sanitizer_set_death_callback");
- if (sanitizer_set_death_callback != nullptr)
- reinterpret_cast<void (*)(void (*)())>(sanitizer_set_death_callback)(
- callback);
+ __real___sanitizer_set_death_callback(callback);
}
namespace {
@@ -153,6 +148,7 @@ AbstractLibfuzzerDriver::AbstractLibfuzzerDriver(
}
};
std::atexit(cleanup_fn);
+ std::at_quick_exit(cleanup_fn);
}
initJvm(*argv_start);
diff --git a/driver/libfuzzer_fuzz_target.cpp b/driver/libfuzzer_fuzz_target.cpp
index 8bbed9a1..7f921321 100644
--- a/driver/libfuzzer_fuzz_target.cpp
+++ b/driver/libfuzzer_fuzz_target.cpp
@@ -50,7 +50,10 @@ extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
<< std::endl;
}
gLibfuzzerDriver = std::make_unique<Driver>(argc, argv);
+ // Run even if we use std::quick_exit to prevent libFuzzer stack trace
+ // printing.
std::atexit(&driver_cleanup);
+ std::at_quick_exit(&driver_cleanup);
return 0;
}
@@ -59,19 +62,23 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, const size_t size) {
auto result = gLibfuzzerDriver->TestOneInput(data, size);
if (result != jazzer::RunResult::kOk) {
// Fuzzer triggered an exception or assertion in Java code. Skip the
- // uninformative libFuzzer stack trace.
- std::cerr << "== libFuzzer crashing input ==\n";
- Driver::libfuzzer_print_crashing_input_();
- // DumpReproducer needs to be called after libFuzzer printed its final
- // stats as otherwise it would report incorrect coverage.
- gLibfuzzerDriver->DumpReproducer(data, size);
- if (result == jazzer::RunResult::kDumpAndContinue) {
- // Continue fuzzing after printing the crashing input.
- return 0;
+ // uninformative libFuzzer stack trace if possible.
+ if (Driver::libfuzzer_print_crashing_input_ != nullptr) {
+ std::cerr << "== libFuzzer crashing input ==\n";
+ Driver::libfuzzer_print_crashing_input_();
+ // DumpReproducer needs to be called after libFuzzer printed its final
+ // stats as otherwise it would report incorrect coverage.
+ gLibfuzzerDriver->DumpReproducer(data, size);
+ if (result == jazzer::RunResult::kDumpAndContinue) {
+ // Continue fuzzing after printing the crashing input.
+ return 0;
+ }
+ // Exit directly without invoking libFuzzer's atexit hook.
+ std::quick_exit(Driver::kErrorExitCode);
+ } else {
+ // libFuzzer failed to register its death callback, exit normally.
+ std::exit(1);
}
- // Exit directly without invoking libFuzzer's atexit hook.
- driver_cleanup();
- _Exit(Driver::kErrorExitCode);
}
return 0;
}
diff --git a/driver/sanitizer_symbols_for_tests.cpp b/driver/sanitizer_symbols_for_tests.cpp
index b671ff66..fb2f6d08 100644
--- a/driver/sanitizer_symbols_for_tests.cpp
+++ b/driver/sanitizer_symbols_for_tests.cpp
@@ -34,5 +34,5 @@ void __sanitizer_cov_trace_div4(uint32_t val) {}
void __sanitizer_cov_trace_div8(uint64_t val) {}
void __sanitizer_cov_trace_gep(uintptr_t idx) {}
void __sanitizer_cov_trace_pc_indir(uintptr_t callee) {}
-void __sanitizer_set_death_callback(void (*callback)()) {}
+void __real___sanitizer_set_death_callback(void (*callback)()) {}
}
diff --git a/examples/BUILD.bazel b/examples/BUILD.bazel
index 4bc7deb8..9b5951a0 100644
--- a/examples/BUILD.bazel
+++ b/examples/BUILD.bazel
@@ -1,4 +1,3 @@
-load("@rules_java//java:defs.bzl", "java_binary")
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")
load("//bazel:fuzz_target.bzl", "java_fuzz_target_test")
diff --git a/third_party/BUILD.bazel b/third_party/BUILD.bazel
index b391ce54..fd65eb9b 100644
--- a/third_party/BUILD.bazel
+++ b/third_party/BUILD.bazel
@@ -2,8 +2,5 @@ exports_files([
"gflags-use-double-dash-args.patch",
"jacoco-make-probe-inserter-subclassable.patch",
"jacoco_internal.BUILD",
- "libFuzzer-make-interceptors-configurable.patch",
- "libFuzzer-pass-death-callback-to-jazzer.patch",
- "libFuzzer.BUILD",
"libjpeg_turbo.BUILD",
])
diff --git a/third_party/jni/BUILD.bazel b/third_party/jni/BUILD.bazel
index cda76ef0..4d5fdd00 100644
--- a/third_party/jni/BUILD.bazel
+++ b/third_party/jni/BUILD.bazel
@@ -1,5 +1,3 @@
-load("@rules_cc//cc:defs.bzl", "cc_import", "cc_library")
-
cc_library(
name = "jni",
visibility = ["//visibility:public"],
diff --git a/third_party/libFuzzer-make-interceptors-configurable.patch b/third_party/libFuzzer-make-interceptors-configurable.patch
deleted file mode 100644
index 9420c4aa..00000000
--- a/third_party/libFuzzer-make-interceptors-configurable.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-diff --git compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
-index b87798603fda..10e34ee86cce 100644
---- compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
-+++ compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
-@@ -147,11 +147,18 @@ 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)
-
-+extern "C" __attribute__((weak)) bool
-+__sanitizer_weak_is_relevant_pc(void * caller_pc) {
-+ return false;
-+}
-+
- 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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_memcmp(caller_pc, s1, s2, n, result);
- return result;
- }
-
-@@ -159,7 +166,9 @@ 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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_memcmp(caller_pc, s1, s2, n, result);
- return result;
- }
-
-@@ -167,7 +176,9 @@ 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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_strncmp(caller_pc, s1, s2, n, result);
- return result;
- }
-
-@@ -175,21 +186,27 @@ 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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_strcmp(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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_strncasecmp(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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_strcasecmp(caller_pc, s1, s2, result);
- return result;
- }
-
-@@ -197,14 +214,18 @@ 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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_strstr(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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_strcasestr(caller_pc, s1, s2, result);
- return result;
- }
-
-@@ -212,7 +233,9 @@ 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);
-+ void *caller_pc = GET_CALLER_PC();
-+ if (__sanitizer_weak_is_relevant_pc(caller_pc))
-+ __sanitizer_weak_hook_memmem(caller_pc, s1, len1, s2, len2, result);
- return result;
- }
-
diff --git a/third_party/libFuzzer-pass-death-callback-to-jazzer.patch b/third_party/libFuzzer-pass-death-callback-to-jazzer.patch
deleted file mode 100644
index 3fb9fbb0..00000000
--- a/third_party/libFuzzer-pass-death-callback-to-jazzer.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git compiler-rt/lib/fuzzer/FuzzerExtFunctions.def compiler-rt/lib/fuzzer/FuzzerExtFunctions.def
-index 51edf8444e94..e31f0040268b 100644
---- compiler-rt/lib/fuzzer/FuzzerExtFunctions.def
-+++ compiler-rt/lib/fuzzer/FuzzerExtFunctions.def
-@@ -42,7 +42,7 @@ EXT_FUNC(__sanitizer_symbolize_pc, void,
- EXT_FUNC(__sanitizer_get_module_and_offset_for_pc, int,
- (void *pc, char *module_path,
- size_t module_path_len,void **pc_offset), false);
--EXT_FUNC(__sanitizer_set_death_callback, void, (void (*)(void)), true);
-+EXT_FUNC(__jazzer_set_death_callback, void, (void (*)(void)), true);
- EXT_FUNC(__sanitizer_set_report_fd, void, (void*), false);
- EXT_FUNC(__msan_scoped_disable_interceptor_checks, void, (), false);
- EXT_FUNC(__msan_scoped_enable_interceptor_checks, void, (), false);
-diff --git compiler-rt/lib/fuzzer/FuzzerLoop.cpp compiler-rt/lib/fuzzer/FuzzerLoop.cpp
-index 149742b4c2fe..7b361423cc32 100644
---- compiler-rt/lib/fuzzer/FuzzerLoop.cpp
-+++ compiler-rt/lib/fuzzer/FuzzerLoop.cpp
-@@ -138,8 +138,8 @@ void Fuzzer::HandleMalloc(size_t Size) {
- Fuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
- FuzzingOptions Options)
- : CB(CB), Corpus(Corpus), MD(MD), Options(Options) {
-- if (EF->__sanitizer_set_death_callback)
-- EF->__sanitizer_set_death_callback(StaticDeathCallback);
-+ if (EF->__jazzer_set_death_callback)
-+ EF->__jazzer_set_death_callback(StaticDeathCallback);
- assert(!F);
- F = this;
- TPC.ResetMaps();
diff --git a/third_party/libFuzzer.BUILD b/third_party/libFuzzer.BUILD
deleted file mode 100644
index 4bd464a4..00000000
--- a/third_party/libFuzzer.BUILD
+++ /dev/null
@@ -1,21 +0,0 @@
-# Based on https://github.com/llvm/llvm-project/blob/llvmorg-11.1.0/compiler-rt/lib/fuzzer/build.sh
-LIB_FUZZER_PATH = "compiler-rt/lib/fuzzer"
-
-cc_library(
- name = "libFuzzer",
- srcs = glob([
- LIB_FUZZER_PATH + "/*.cpp",
- ]),
- hdrs = glob([
- LIB_FUZZER_PATH + "/*.h",
- LIB_FUZZER_PATH + "/*.def",
- ]),
- copts = [
- "-g",
- "-O2",
- "-fno-omit-frame-pointer",
- "-std=c++11",
- ],
- alwayslink = True,
- visibility = ["//visibility:public"],
-)