diff options
author | Fabian Meumertzheim <meumertzheim@code-intelligence.com> | 2021-08-02 11:50:56 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2021-10-18 10:29:07 +0200 |
commit | 7907a8b9c9b49968adce6623f586240e010da801 (patch) | |
tree | a14736ac52ffce88410d581da9c0ff73fcf0ec61 | |
parent | 27b15be5fd30af5f3b64ab6451fb26c417681221 (diff) | |
download | jazzer-api-7907a8b9c9b49968adce6623f586240e010da801.tar.gz |
Extract FuzzedDataProvider into a stand-alone cc_library
-rw-r--r-- | driver/BUILD.bazel | 18 | ||||
-rw-r--r-- | driver/fuzz_target_runner.cpp | 3 | ||||
-rw-r--r-- | driver/fuzzed_data_provider.cpp | 71 | ||||
-rw-r--r-- | driver/fuzzed_data_provider.h | 18 | ||||
-rw-r--r-- | driver/java_reproducer.cpp | 79 | ||||
-rw-r--r-- | driver/java_reproducer.h | 32 |
6 files changed, 140 insertions, 81 deletions
diff --git a/driver/BUILD.bazel b/driver/BUILD.bazel index 2dfcc84d..f15a2ddd 100644 --- a/driver/BUILD.bazel +++ b/driver/BUILD.bazel @@ -24,11 +24,26 @@ cc_test( ) cc_library( + name = "fuzzed_data_provider", + srcs = [ + "fuzzed_data_provider.cpp", + ], + hdrs = [ + "fuzzed_data_provider.h", + ], + deps = [ + "@bazel_tools//tools/jdk:jni", + "@com_google_absl//absl/strings:str_format", + ], +) + +cc_library( name = "jvm_tooling_lib", srcs = [ "coverage_tracker.cpp", "fuzz_target_runner.cpp", - "fuzzed_data_provider.cpp", + "java_reproducer.cpp", + "java_reproducer.h", "java_reproducer_templates.h", "jvm_tooling.cpp", "libfuzzer_callbacks.cpp", @@ -58,6 +73,7 @@ cc_library( ], visibility = ["//visibility:public"], deps = [ + ":fuzzed_data_provider", ":sanitizer_hooks_with_pc", "@bazel_tools//tools/cpp/runfiles", "@com_google_absl//absl/strings", diff --git a/driver/fuzz_target_runner.cpp b/driver/fuzz_target_runner.cpp index 909c4d9c..0bdaedf5 100644 --- a/driver/fuzz_target_runner.cpp +++ b/driver/fuzz_target_runner.cpp @@ -31,6 +31,7 @@ #include "fuzzed_data_provider.h" #include "gflags/gflags.h" #include "glog/logging.h" +#include "java_reproducer.h" #include "java_reproducer_templates.h" #include "utils.h" @@ -175,7 +176,7 @@ FuzzTargetRunner::FuzzTargetRunner( if (FLAGS_hooks && !FLAGS_coverage_report.empty()) { CoverageTracker::RecordInitialCoverage(env); } - SetUpFuzzedDataProvider(jvm_); + SetUpFuzzedDataProvider(jvm_.GetEnv()); // Parse a comma-separated list of hex dedup tokens. std::vector<std::string> str_ignore_tokens = diff --git a/driver/fuzzed_data_provider.cpp b/driver/fuzzed_data_provider.cpp index 110e8b1d..03a6a5e8 100644 --- a/driver/fuzzed_data_provider.cpp +++ b/driver/fuzzed_data_provider.cpp @@ -45,8 +45,6 @@ #include "fuzzed_data_provider.h" -#include <jni.h> - #include <algorithm> #include <cstdint> #include <string> @@ -54,15 +52,9 @@ #include <vector> #include "absl/strings/str_format.h" -#include "jvm_tooling.h" namespace { -const char kFuzzedDataProviderImplClass[] = - "com/code_intelligence/jazzer/runtime/FuzzedDataProviderImpl"; -const char kRecordingFuzzedDataProviderClass[] = - "com/code_intelligence/jazzer/runtime/RecordingFuzzedDataProvider"; - const uint8_t *gDataPtr = nullptr; std::size_t gRemainingBytes = 0; @@ -703,10 +695,13 @@ const jint kNumFuzzedDataMethods = namespace jazzer { -void SetUpFuzzedDataProvider(const JVM &jvm) { - auto &env = jvm.GetEnv(); +void SetUpFuzzedDataProvider(JNIEnv &env) { jclass fuzzed_data_provider_class = - jvm.FindClass(kFuzzedDataProviderImplClass); + env.FindClass(kFuzzedDataProviderImplClass); + if (env.ExceptionCheck()) { + env.ExceptionDescribe(); + throw std::runtime_error("failed to find FuzzedDataProviderImpl class"); + } env.RegisterNatives(fuzzed_data_provider_class, kFuzzedDataMethods, kNumFuzzedDataMethods); if (env.ExceptionCheck()) { @@ -720,58 +715,4 @@ void FeedFuzzedDataProvider(const uint8_t *data, std::size_t size) { gDataPtr = data; gRemainingBytes = size; } - -jobject GetFuzzedDataProviderJavaObject(const JVM &jvm) { - static jobject java_object = nullptr; - if (java_object == nullptr) { - jclass java_class = jvm.FindClass(kFuzzedDataProviderImplClass); - jmethodID java_constructor = jvm.GetMethodID(java_class, "<init>", "()V"); - jobject local_ref = jvm.GetEnv().NewObject(java_class, java_constructor); - // We leak a global reference here as it will be used until JVM exit. - java_object = jvm.GetEnv().NewGlobalRef(local_ref); - } - return java_object; -} - -jobject GetRecordingFuzzedDataProviderJavaObject(const JVM &jvm) { - auto &env = jvm.GetEnv(); - jclass java_class = jvm.FindClass(kRecordingFuzzedDataProviderClass); - jmethodID java_make_proxy = jvm.GetStaticMethodID( - java_class, "makeFuzzedDataProviderProxy", - "()Lcom/code_intelligence/jazzer/api/FuzzedDataProvider;", true); - jobject local_ref = env.CallStaticObjectMethod(java_class, java_make_proxy); - if (env.ExceptionCheck()) { - env.ExceptionDescribe(); - exit(1); - } - // This global reference is deleted in SerializeRecordingFuzzedDataProvider. - jobject global_ref = env.NewGlobalRef(local_ref); - env.DeleteLocalRef(local_ref); - return global_ref; -} - -std::string SerializeRecordingFuzzedDataProvider(const JVM &jvm, - jobject recorder) { - auto &env = jvm.GetEnv(); - jclass java_class = jvm.FindClass(kRecordingFuzzedDataProviderClass); - jmethodID java_serialize = - jvm.GetStaticMethodID(java_class, "serializeFuzzedDataProviderProxy", - "(Lcom/code_intelligence/jazzer/api/" - "FuzzedDataProvider;)Ljava/lang/String;", - true); - auto serialized_recorder = - (jstring)env.CallStaticObjectMethod(java_class, java_serialize, recorder); - env.DeleteLocalRef(java_class); - env.DeleteGlobalRef(recorder); - if (env.ExceptionCheck()) { - env.ExceptionDescribe(); - exit(1); - } - const char *serialized_recorder_cstr = - env.GetStringUTFChars(serialized_recorder, nullptr); - std::string out(serialized_recorder_cstr); - env.ReleaseStringUTFChars(serialized_recorder, serialized_recorder_cstr); - env.DeleteLocalRef(serialized_recorder); - return out; -} } // namespace jazzer diff --git a/driver/fuzzed_data_provider.h b/driver/fuzzed_data_provider.h index 66976240..9b8faf78 100644 --- a/driver/fuzzed_data_provider.h +++ b/driver/fuzzed_data_provider.h @@ -30,25 +30,15 @@ #include <utility> #include <vector> -#include "jvm_tooling.h" - namespace jazzer { +constexpr char kFuzzedDataProviderImplClass[] = + "com/code_intelligence/jazzer/runtime/FuzzedDataProviderImpl"; + // Registers the native methods in FuzzedDataProvider. -void SetUpFuzzedDataProvider(const JVM &jvm); +void SetUpFuzzedDataProvider(JNIEnv &env); // Feed the FuzzedDataProvider with a new data buffer. The buffer is accessed // by native code and not copied into the JVM, so this is cheap to call. void FeedFuzzedDataProvider(const uint8_t *data, std::size_t size); - -// Gets the single global reference to a Java FuzzedDataProvider object. The -// object itself doesn't hold any state and only exists to make the UX better by -// providing it as an argument to the fuzz target instead of relying on static -// calls. -jobject GetFuzzedDataProviderJavaObject(const JVM &jvm); - -jobject GetRecordingFuzzedDataProviderJavaObject(const JVM &jvm); - -std::string SerializeRecordingFuzzedDataProvider(const JVM &jvm, - jobject recorder); } // namespace jazzer diff --git a/driver/java_reproducer.cpp b/driver/java_reproducer.cpp new file mode 100644 index 00000000..ed4c6755 --- /dev/null +++ b/driver/java_reproducer.cpp @@ -0,0 +1,79 @@ +// 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 "java_reproducer.h" + +#include "fuzzed_data_provider.h" +#include "jvm_tooling.h" + +namespace { +const char kRecordingFuzzedDataProviderClass[] = + "com/code_intelligence/jazzer/runtime/RecordingFuzzedDataProvider"; +} + +namespace jazzer { +jobject GetFuzzedDataProviderJavaObject(const JVM &jvm) { + static jobject java_object = nullptr; + if (java_object == nullptr) { + jclass java_class = jvm.FindClass(kFuzzedDataProviderImplClass); + jmethodID java_constructor = jvm.GetMethodID(java_class, "<init>", "()V"); + jobject local_ref = jvm.GetEnv().NewObject(java_class, java_constructor); + // We leak a global reference here as it will be used until JVM exit. + java_object = jvm.GetEnv().NewGlobalRef(local_ref); + } + return java_object; +} + +jobject GetRecordingFuzzedDataProviderJavaObject(const JVM &jvm) { + auto &env = jvm.GetEnv(); + jclass java_class = jvm.FindClass(kRecordingFuzzedDataProviderClass); + jmethodID java_make_proxy = jvm.GetStaticMethodID( + java_class, "makeFuzzedDataProviderProxy", + "()Lcom/code_intelligence/jazzer/api/FuzzedDataProvider;", true); + jobject local_ref = env.CallStaticObjectMethod(java_class, java_make_proxy); + if (env.ExceptionCheck()) { + env.ExceptionDescribe(); + exit(1); + } + // This global reference is deleted in SerializeRecordingFuzzedDataProvider. + jobject global_ref = env.NewGlobalRef(local_ref); + env.DeleteLocalRef(local_ref); + return global_ref; +} + +std::string SerializeRecordingFuzzedDataProvider(const JVM &jvm, + jobject recorder) { + auto &env = jvm.GetEnv(); + jclass java_class = jvm.FindClass(kRecordingFuzzedDataProviderClass); + jmethodID java_serialize = + jvm.GetStaticMethodID(java_class, "serializeFuzzedDataProviderProxy", + "(Lcom/code_intelligence/jazzer/api/" + "FuzzedDataProvider;)Ljava/lang/String;", + true); + auto serialized_recorder = + (jstring)env.CallStaticObjectMethod(java_class, java_serialize, recorder); + env.DeleteLocalRef(java_class); + env.DeleteGlobalRef(recorder); + if (env.ExceptionCheck()) { + env.ExceptionDescribe(); + exit(1); + } + const char *serialized_recorder_cstr = + env.GetStringUTFChars(serialized_recorder, nullptr); + std::string out(serialized_recorder_cstr); + env.ReleaseStringUTFChars(serialized_recorder, serialized_recorder_cstr); + env.DeleteLocalRef(serialized_recorder); + return out; +} +} // namespace jazzer diff --git a/driver/java_reproducer.h b/driver/java_reproducer.h new file mode 100644 index 00000000..b3202b14 --- /dev/null +++ b/driver/java_reproducer.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#pragma once + +#include "jvm_tooling.h" + +namespace jazzer { +// Gets the single global reference to a Java FuzzedDataProvider object. The +// object itself doesn't hold any state and only exists to make the UX better by +// providing it as an argument to the fuzz target instead of relying on static +// calls. +jobject GetFuzzedDataProviderJavaObject(const JVM &jvm); + +jobject GetRecordingFuzzedDataProviderJavaObject(const JVM &jvm); + +std::string SerializeRecordingFuzzedDataProvider(const JVM &jvm, + jobject recorder); +} // namespace jazzer |