aboutsummaryrefslogtreecommitdiff
path: root/driver/libfuzzer_driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'driver/libfuzzer_driver.cpp')
-rw-r--r--driver/libfuzzer_driver.cpp187
1 files changed, 0 insertions, 187 deletions
diff --git a/driver/libfuzzer_driver.cpp b/driver/libfuzzer_driver.cpp
deleted file mode 100644
index 57beef58..00000000
--- a/driver/libfuzzer_driver.cpp
+++ /dev/null
@@ -1,187 +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.
-
-#include "libfuzzer_driver.h"
-
-#include <rules_jni.h>
-
-#include <algorithm>
-#include <filesystem>
-#include <fstream>
-#include <random>
-#include <string>
-#include <vector>
-
-#include "absl/strings/match.h"
-#include "absl/strings/str_format.h"
-#include "fuzz_target_runner.h"
-#include "gflags/gflags.h"
-#include "glog/logging.h"
-#include "jvm_tooling.h"
-
-using namespace std::string_literals;
-
-// Defined by glog
-DECLARE_bool(log_prefix);
-
-// Defined in libfuzzer_callbacks.cpp
-DECLARE_bool(fake_pcs);
-
-// Defined in jvm_tooling.cpp
-DECLARE_string(id_sync_file);
-
-// Defined in fuzz_target_runner.cpp
-DECLARE_string(coverage_report);
-
-// This symbol is defined by sanitizers if linked into Jazzer or in
-// sanitizer_symbols.cpp if no sanitizer is used.
-extern "C" void __sanitizer_set_death_callback(void (*)());
-
-// 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)()) {
- jazzer::AbstractLibfuzzerDriver::libfuzzer_print_crashing_input_ = callback;
- __sanitizer_set_death_callback(callback);
-}
-
-namespace {
-char *additional_arg;
-std::vector<char *> modified_argv;
-
-std::string GetNewTempFilePath() {
- auto temp_dir = std::filesystem::temp_directory_path();
-
- std::string temp_filename_suffix(32, '\0');
- std::random_device rng;
- std::uniform_int_distribution<short> dist(0, 'z' - 'a');
- std::generate_n(temp_filename_suffix.begin(), temp_filename_suffix.length(),
- [&rng, &dist] { return static_cast<char>('a' + dist(rng)); });
-
- auto temp_path = temp_dir / ("jazzer-" + temp_filename_suffix);
- if (std::filesystem::exists(temp_path))
- throw std::runtime_error("Random temp file path exists: " +
- temp_path.string());
- return temp_path.string();
-}
-} // namespace
-
-namespace jazzer {
-// A libFuzzer-registered callback that outputs the crashing input, but does
-// not include a stack trace.
-void (*AbstractLibfuzzerDriver::libfuzzer_print_crashing_input_)() = nullptr;
-
-AbstractLibfuzzerDriver::AbstractLibfuzzerDriver(
- int *argc, char ***argv, const std::string &usage_string) {
- gflags::SetUsageMessage(usage_string);
- // Disable glog log prefixes to mimic libFuzzer output.
- FLAGS_log_prefix = false;
- google::InitGoogleLogging((*argv)[0]);
- rules_jni_init((*argv)[0]);
-
- auto argv_start = *argv;
- auto argv_end = *argv + *argc;
-
- if (std::find(argv_start, argv_end, "-use_value_profile=1"s) != argv_end) {
- FLAGS_fake_pcs = true;
- }
-
- // All libFuzzer flags start with a single dash, our arguments all start with
- // a double dash. We can thus filter out the arguments meant for gflags by
- // taking only those with a leading double dash.
- std::vector<char *> our_args = {*argv_start};
- std::copy_if(
- argv_start, argv_end, std::back_inserter(our_args),
- [](const auto arg) { return absl::StartsWith(std::string(arg), "--"); });
- int our_argc = our_args.size();
- char **our_argv = our_args.data();
- // Let gflags consume its flags, but keep them in the argument list in case
- // libFuzzer forwards the command line (e.g. with -jobs or -minimize_crash).
- gflags::ParseCommandLineFlags(&our_argc, &our_argv, false);
-
- if (std::any_of(argv_start, argv_end, [](const std::string_view &arg) {
- return absl::StartsWith(arg, "-fork=") ||
- absl::StartsWith(arg, "-jobs=") ||
- absl::StartsWith(arg, "-merge=");
- })) {
- if (!FLAGS_coverage_report.empty()) {
- LOG(WARNING) << "WARN: --coverage_report does not support parallel "
- "fuzzing and has been disabled";
- FLAGS_coverage_report = "";
- }
- if (FLAGS_id_sync_file.empty()) {
- // Create an empty temporary file used for coverage ID synchronization and
- // pass its path to the agent in every child process. This requires adding
- // the argument to argv for it to be picked up by libFuzzer, which then
- // forwards it to child processes.
- FLAGS_id_sync_file = GetNewTempFilePath();
- std::string new_arg =
- absl::StrFormat("--id_sync_file=%s", FLAGS_id_sync_file);
- // This argument can be accessed by libFuzzer at any (later) time and thus
- // cannot be safely freed by us.
- additional_arg = strdup(new_arg.c_str());
- modified_argv = std::vector<char *>(argv_start, argv_end);
- modified_argv.push_back(additional_arg);
- // Terminate modified_argv.
- modified_argv.push_back(nullptr);
- // Modify argv and argc for libFuzzer. modified_argv must not be changed
- // after this point.
- *argc += 1;
- *argv = modified_argv.data();
- argv_start = *argv;
- argv_end = *argv + *argc;
- }
- // Creates the file, truncating it if it exists.
- std::ofstream touch_file(FLAGS_id_sync_file, std::ios_base::trunc);
-
- auto cleanup_fn = [] {
- try {
- std::filesystem::remove(std::filesystem::path(FLAGS_id_sync_file));
- } catch (...) {
- // We should not throw exceptions during shutdown.
- }
- };
- std::atexit(cleanup_fn);
- }
-
- initJvm(*argv_start);
-}
-
-void AbstractLibfuzzerDriver::initJvm(const std::string &executable_path) {
- jvm_ = std::make_unique<jazzer::JVM>(executable_path);
-}
-
-LibfuzzerDriver::LibfuzzerDriver(int *argc, char ***argv)
- : AbstractLibfuzzerDriver(argc, argv, getUsageString()) {
- // the FuzzTargetRunner can only be initialized after the fuzzer callbacks
- // have been registered otherwise link errors would occur
- runner_ = std::make_unique<jazzer::FuzzTargetRunner>(*jvm_);
-}
-
-std::string LibfuzzerDriver::getUsageString() {
- return R"(Test java fuzz targets using libFuzzer. Usage:
- jazzer --cp=<java_class_path> --target_class=<fuzz_target_class> <libfuzzer_arguments...>)";
-}
-
-RunResult LibfuzzerDriver::TestOneInput(const uint8_t *data,
- const std::size_t size) {
- // pass the fuzzer input to the java fuzz target
- return runner_->Run(data, size);
-}
-
-void LibfuzzerDriver::DumpReproducer(const uint8_t *data, std::size_t size) {
- return runner_->DumpReproducer(data, size);
-}
-
-} // namespace jazzer