From 73d78b88790b501f119801c4f68463180b76e1d9 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Thu, 10 Jun 2021 16:57:42 +0200 Subject: [infra][jvm] Add Jazzer UBSan support (#5898) * [infra][jvm] Add Jazzer UBSan support * [java-example] Reenable and plant UB * [docs] Mention support for Java UBSan in docs Also adds a link to the java-example build.sh to the docs. --- docs/getting-started/new-project-guide/jvm_lang.md | 9 +++++++-- infra/base-images/base-builder/Dockerfile | 4 ++-- infra/base-images/base-builder/compile | 12 +++++++++--- infra/base-images/base-runner/coverage | 2 +- projects/java-example/ExampleFuzzerNative.cpp | 12 +++++++++--- projects/java-example/build.sh | 2 +- projects/java-example/project.yaml | 3 ++- 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/docs/getting-started/new-project-guide/jvm_lang.md b/docs/getting-started/new-project-guide/jvm_lang.md index 9cc3ef3e9..74130cb62 100644 --- a/docs/getting-started/new-project-guide/jvm_lang.md +++ b/docs/getting-started/new-project-guide/jvm_lang.md @@ -50,8 +50,9 @@ language: jvm ``` The only supported fuzzing engine is libFuzzer (`libfuzzer`). So far the only -supported sanitizer is AddressSanitizer (`address`), which needs to be -specified explicitly even for pure Java projects. +supported sanitizers are AddressSanitizer (`address`) and +UndefinedBehaviorSanitizer (`undefined`). For pure Java projects, specify +just `address`: ```yaml fuzzing_engines: @@ -141,6 +142,10 @@ LD_LIBRARY_PATH=\"$JVM_LD_LIBRARY_PATH\":\$this_dir \ done ``` +The [java-example](https://github.com/google/oss-fuzz/blob/master/projects/java-example/build.sh) +project contains an example of a `build.sh` for Java projects with native +libraries. + ## FuzzedDataProvider Jazzer provides a `FuzzedDataProvider` that can simplify the task of creating a diff --git a/infra/base-images/base-builder/Dockerfile b/infra/base-images/base-builder/Dockerfile index 40b993165..cf6d45639 100644 --- a/infra/base-images/base-builder/Dockerfile +++ b/infra/base-images/base-builder/Dockerfile @@ -120,8 +120,8 @@ RUN cd $SRC/ && \ git clone --depth=1 https://github.com/CodeIntelligenceTesting/jazzer && \ cd jazzer && \ bazel build --java_runtime_version=localjdk_15 -c opt --cxxopt="-stdlib=libc++" --linkopt=-lc++ \ - //agent:jazzer_agent_deploy.jar //driver:jazzer_driver //driver:jazzer_driver_asan //agent:jazzer_api_deploy.jar && \ - cp bazel-bin/agent/jazzer_agent_deploy.jar bazel-bin/driver/jazzer_driver bazel-bin/driver/jazzer_driver_asan /usr/local/bin/ && \ + //agent:jazzer_agent_deploy.jar //driver:jazzer_driver //driver:jazzer_driver_asan //driver:jazzer_driver_ubsan //agent:jazzer_api_deploy.jar && \ + cp bazel-bin/agent/jazzer_agent_deploy.jar bazel-bin/driver/jazzer_driver bazel-bin/driver/jazzer_driver_asan bazel-bin/driver/jazzer_driver_ubsan /usr/local/bin/ && \ cp bazel-bin/agent/jazzer_api_deploy.jar $JAZZER_API_PATH && \ rm -rf ~/.cache/bazel ~/.cache/bazelisk && \ rm -rf $SRC/jazzer diff --git a/infra/base-images/base-builder/compile b/infra/base-images/base-builder/compile index 6882e1790..eeb160fe1 100755 --- a/infra/base-images/base-builder/compile +++ b/infra/base-images/base-builder/compile @@ -27,8 +27,8 @@ if [ "$FUZZING_LANGUAGE" = "jvm" ]; then echo "ERROR: JVM projects can be fuzzed with libFuzzer engine only." exit 1 fi - if [ "$SANITIZER" != "address" ] && [ "$SANITIZER" != "coverage" ]; then - echo "ERROR: JVM projects can be fuzzed with AddressSanitizer only." + if [ "$SANITIZER" != "address" ] && [ "$SANITIZER" != "coverage" ] && [ "$SANITIZER" != "undefined" ]; then + echo "ERROR: JVM projects can be fuzzed with AddressSanitizer and UndefinedBehaviorSanitizer only." exit 1 fi if [ "$ARCHITECTURE" != "x86_64" ]; then @@ -136,7 +136,13 @@ cp $(which llvm-symbolizer) $OUT/ # Copy Jazzer to $OUT if needed. if [ "$FUZZING_LANGUAGE" = "jvm" ]; then - cp $(which jazzer_agent_deploy.jar) $(which jazzer_driver) $(which jazzer_driver_asan) $OUT/ + cp $(which jazzer_agent_deploy.jar) $(which jazzer_driver) $OUT/ + jazzer_driver_with_sanitizer=$OUT/jazzer_driver_with_sanitizer + if [ "$SANITIZER" = "address" ]; then + cp $(which jazzer_driver_asan) $jazzer_driver_with_sanitizer + elif [ "$SANITIZER" = "undefined" ]; then + cp $(which jazzer_driver_ubsan) $jazzer_driver_with_sanitizer + fi fi echo "---------------------------------------------------------------" diff --git a/infra/base-images/base-runner/coverage b/infra/base-images/base-runner/coverage index 31356cf9b..785689c7f 100755 --- a/infra/base-images/base-runner/coverage +++ b/infra/base-images/base-runner/coverage @@ -24,7 +24,7 @@ else -e 'llvm-symbolizer' \ -e 'jazzer_agent_deploy.jar' \ -e 'jazzer_driver' \ - -e 'jazzer_driver_asan')" + -e 'jazzer_driver_with_sanitizer')" fi DUMPS_DIR="$OUT/dumps" diff --git a/projects/java-example/ExampleFuzzerNative.cpp b/projects/java-example/ExampleFuzzerNative.cpp index 0e37aee5d..565f75cf9 100644 --- a/projects/java-example/ExampleFuzzerNative.cpp +++ b/projects/java-example/ExampleFuzzerNative.cpp @@ -16,15 +16,21 @@ #include "ExampleFuzzerNative.h" +#include #include // simple function containing a crash that requires coverage and string compare // instrumentation for the fuzzer to find -void parseInternal(const std::string &input) { +__attribute__((optnone)) void parseInternal(const std::string &input) { + constexpr int bar = std::numeric_limits::max() - 5; + // Crashes with UBSan. + if (bar + input[0] == 300) { + return; + } if (input[0] == 'a' && input[1] == 'b' && input[5] == 'c') { if (input.find("secret_in_native_library") != std::string::npos) { - // BOOM - *(char *)0xFF = 2; + // Crashes with ASan. + [[maybe_unused]] char foo = input[input.size() + 2]; } } } diff --git a/projects/java-example/build.sh b/projects/java-example/build.sh index e92675654..4cfb1683c 100755 --- a/projects/java-example/build.sh +++ b/projects/java-example/build.sh @@ -31,7 +31,7 @@ for fuzzer in $(find $SRC -name '*Fuzzer.java' -or -name '*FuzzerNative.java'); cp $SRC/$fuzzer_basename.class $OUT/ if [[ $fuzzer_basename == *FuzzerNative ]]; then - driver=jazzer_driver_asan + driver=jazzer_driver_with_sanitizer else driver=jazzer_driver fi diff --git a/projects/java-example/project.yaml b/projects/java-example/project.yaml index 956ff71bc..53ca28f32 100644 --- a/projects/java-example/project.yaml +++ b/projects/java-example/project.yaml @@ -1,5 +1,5 @@ homepage: "https://github.com/CodeIntelligenceTesting/jazzer" -disabled: true +disabled: false language: jvm primary_contact: "meumertzheim@code-intelligence.com" fuzzing_engines: @@ -7,3 +7,4 @@ fuzzing_engines: main_repo: "https://github.com/CodeIntelligenceTesting/jazzer" sanitizers: - address + - undefined -- cgit v1.2.3