diff options
Diffstat (limited to 'launcher/jazzer_main.cpp')
-rw-r--r-- | launcher/jazzer_main.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/launcher/jazzer_main.cpp b/launcher/jazzer_main.cpp new file mode 100644 index 00000000..d2c6e294 --- /dev/null +++ b/launcher/jazzer_main.cpp @@ -0,0 +1,109 @@ +// 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. + +/* + * Jazzer's native main function, which starts a JVM suitably configured for + * fuzzing and passes control to the Java part of the driver. + */ + +#include <rules_jni.h> + +#include <algorithm> +#include <iostream> +#include <memory> +#include <vector> + +#include "absl/strings/str_split.h" +#include "jvm_tooling.h" + +namespace { +const std::string kJazzerClassName = "com/code_intelligence/jazzer/Jazzer"; + +void StartLibFuzzer(std::unique_ptr<jazzer::JVM> jvm, + std::vector<std::string> argv) { + JNIEnv &env = jvm->GetEnv(); + jclass runner = env.FindClass(kJazzerClassName.c_str()); + if (runner == nullptr) { + env.ExceptionDescribe(); + exit(1); + } + jmethodID startDriver = env.GetStaticMethodID(runner, "main", "([[B)V"); + if (startDriver == nullptr) { + env.ExceptionDescribe(); + exit(1); + } + jclass byteArrayClass = env.FindClass("[B"); + if (byteArrayClass == nullptr) { + env.ExceptionDescribe(); + exit(1); + } + jobjectArray args = env.NewObjectArray(argv.size(), byteArrayClass, nullptr); + if (args == nullptr) { + env.ExceptionDescribe(); + exit(1); + } + for (jsize i = 0; i < argv.size(); ++i) { + jint len = argv[i].size(); + jbyteArray arg = env.NewByteArray(len); + if (arg == nullptr) { + env.ExceptionDescribe(); + exit(1); + } + // startDriver expects UTF-8 encoded strings that are not null-terminated. + env.SetByteArrayRegion(arg, 0, len, + reinterpret_cast<const jbyte *>(argv[i].data())); + if (env.ExceptionCheck()) { + env.ExceptionDescribe(); + exit(1); + } + env.SetObjectArrayElement(args, i, arg); + if (env.ExceptionCheck()) { + env.ExceptionDescribe(); + exit(1); + } + env.DeleteLocalRef(arg); + } + env.CallStaticVoidMethod(runner, startDriver, args); + // Should not return. + if (env.ExceptionCheck()) { + env.ExceptionDescribe(); + } + exit(1); +} +} // namespace + +int main(int argc, char **argv) { + rules_jni_init(argv[0]); + + for (int i = 1; i < argc; ++i) { + const std::string &arg = argv[i]; + std::vector<std::string> split = + absl::StrSplit(arg, absl::MaxSplits('=', 1)); + if (split.size() < 2) { + continue; + } + if (split[0] == "--cp") { + FLAGS_cp = split[1]; + } else if (split[0] == "--jvm_args") { + FLAGS_jvm_args = split[1]; + } else if (split[0] == "--additional_jvm_args") { + FLAGS_additional_jvm_args = split[1]; + } else if (split[0] == "--agent_path") { + FLAGS_agent_path = split[1]; + } + } + + StartLibFuzzer(std::unique_ptr<jazzer::JVM>(new jazzer::JVM()), + std::vector<std::string>(argv + 1, argv + argc)); +} |