diff options
author | Fabian Meumertzheim <fabian@meumertzhe.im> | 2021-10-08 15:41:08 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2021-10-17 10:37:34 +0200 |
commit | 27b15be5fd30af5f3b64ab6451fb26c417681221 (patch) | |
tree | 285c944b7669e73952fb276c694ac2560acd83ac /bazel | |
parent | c470f962424801a4020cf7215dc27422949f34fd (diff) | |
download | jazzer-api-27b15be5fd30af5f3b64ab6451fb26c417681221.tar.gz |
Use rules_jni
This simplifies the libjvm location logic as well as native library
packaging. Incidentally, this fixes the libjpeg_turbo build.
In anticipation of Windows support and because it simplifies further
improvements to the fuzz target test setup, the wrapper is rewritten in
Java.
Diffstat (limited to 'bazel')
-rw-r--r-- | bazel/BUILD.bazel | 11 | ||||
-rw-r--r-- | bazel/FuzzTargetTestWrapper.java | 78 | ||||
-rw-r--r-- | bazel/cc.bzl | 23 | ||||
-rw-r--r-- | bazel/fuzz_target.bzl | 19 | ||||
-rwxr-xr-x | bazel/fuzz_target_test_wrapper.sh | 42 | ||||
-rwxr-xr-x | bazel/jazzer | 11 | ||||
-rwxr-xr-x | bazel/jazzer_wrapper.sh | 29 | ||||
-rw-r--r-- | bazel/local_jdk_libjvm.bzl | 59 |
8 files changed, 94 insertions, 178 deletions
diff --git a/bazel/BUILD.bazel b/bazel/BUILD.bazel index 9df500d6..1e2348c1 100644 --- a/bazel/BUILD.bazel +++ b/bazel/BUILD.bazel @@ -1,5 +1,6 @@ -exports_files([ - "fuzz_target_test_wrapper.sh", - "jazzer", - "jazzer_wrapper.sh", -]) +java_library( + name = "fuzz_target_test_wrapper", + srcs = ["FuzzTargetTestWrapper.java"], + visibility = ["//:__subpackages__"], + deps = ["@bazel_tools//tools/java/runfiles"], +) diff --git a/bazel/FuzzTargetTestWrapper.java b/bazel/FuzzTargetTestWrapper.java new file mode 100644 index 00000000..ef22ea0e --- /dev/null +++ b/bazel/FuzzTargetTestWrapper.java @@ -0,0 +1,78 @@ +// 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. + +import com.google.devtools.build.runfiles.Runfiles; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class FuzzTargetTestWrapper { + public static void main(String[] args) { + String driverActualPath; + String jarActualPath; + Runfiles runfiles; + try { + runfiles = Runfiles.create(); + driverActualPath = runfiles.rlocation(args[0]); + jarActualPath = runfiles.rlocation(args[1]); + } catch (IOException | ArrayIndexOutOfBoundsException e) { + e.printStackTrace(); + System.exit(1); + return; + } + + ProcessBuilder processBuilder = new ProcessBuilder(); + Map<String, String> environment = processBuilder.environment(); + // Ensure that Jazzer can find its runfiles. + environment.putAll(runfiles.getEnvVars()); + + // Crashes will be available as test outputs. These are cleared on the next run, + // so this is only useful for examples. + String outputDir = System.getenv("TEST_UNDECLARED_OUTPUTS_DIR"); + List<String> command = + Stream + .concat(Stream.of(driverActualPath, String.format("-artifact_prefix=%s/", outputDir), + String.format("--reproducer_path=%s", outputDir), "-seed=2735196724", + String.format("--cp=%s", jarActualPath)), + Arrays.stream(args).skip(2)) + .collect(Collectors.toList()); + processBuilder.inheritIO(); + processBuilder.command(command); + + try { + int exitCode = processBuilder.start().waitFor(); + // Assert that we either found a crash in Java (exit code 77) or a sanitizer crash (exit code + // 76). + if (exitCode != 76 && exitCode != 77) { + System.exit(3); + } + String[] outputFiles = new File(outputDir).list(); + if (outputFiles == null) { + System.exit(4); + } + // Verify that libFuzzer dumped a crashing input. + if (Arrays.stream(outputFiles).noneMatch(name -> name.startsWith("crash-"))) { + System.exit(5); + } + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + System.exit(2); + } + System.exit(0); + } +} diff --git a/bazel/cc.bzl b/bazel/cc.bzl index 465127cf..5785513d 100644 --- a/bazel/cc.bzl +++ b/bazel/cc.bzl @@ -72,26 +72,3 @@ def cc_17_library(name, visibility = None, **kwargs): library = library_name, visibility = visibility, ) - -# Workaround for https://github.com/bazelbuild/bazel/issues/11082 -# By explicitly setting the name of a cc_binary and selecting based on the -# platform, the resulting shared object will have the correct extension on both -# Linux and macOS. -def cc_shared_library(name, visibility = None, **kwargs): - # Linux - linux_name = "lib%s.so" % name - native.cc_binary( - name = linux_name, - linkshared = True, - visibility = visibility, - **kwargs - ) - - # macOS - osx_name = "lib%s.dylib" % name - native.cc_binary( - name = osx_name, - linkshared = True, - visibility = visibility, - **kwargs - ) diff --git a/bazel/fuzz_target.bzl b/bazel/fuzz_target.bzl index 801fa292..0b31afc2 100644 --- a/bazel/fuzz_target.bzl +++ b/bazel/fuzz_target.bzl @@ -46,33 +46,34 @@ def java_fuzz_target_test( additional_args = [] - native_libs_paths = ":".join(["$$(dirname $(rootpaths %s) | paste -sd ':' -)" % native_lib for native_lib in native_libs]) - if native_libs_paths != "": - additional_args.append("--jvm_args=-Djava.library.path=" + native_libs_paths) - if sanitizer == None: driver = "//driver:jazzer_driver" + driver_rlocation = "jazzer/driver/jazzer_driver" elif sanitizer == "address": driver = "//driver:jazzer_driver_asan" + driver_rlocation = "jazzer/driver/jazzer_driver_asan" elif sanitizer == "undefined": driver = "//driver:jazzer_driver_ubsan" + driver_rlocation = "jazzer/driver/jazzer_driver_ubsan" else: fail("Invalid sanitizer: " + sanitizer) - native.sh_test( + native.java_test( name = name, - srcs = ["//bazel:fuzz_target_test_wrapper.sh"], - size = "large", + runtime_deps = ["//bazel:fuzz_target_test_wrapper"], + size = "enormous", timeout = "moderate", args = [ - "$(rootpath %s)" % driver, - "--cp=$(rootpath :%s_deploy.jar)" % target_name, + driver_rlocation, + "jazzer/$(rootpath :%s_deploy.jar)" % target_name, ] + additional_args + fuzzer_args, data = [ ":%s_deploy.jar" % target_name, "//agent:jazzer_agent_deploy.jar", driver, ] + native_libs, + main_class = "FuzzTargetTestWrapper", + use_testrunner = False, tags = tags, visibility = visibility, ) diff --git a/bazel/fuzz_target_test_wrapper.sh b/bazel/fuzz_target_test_wrapper.sh deleted file mode 100755 index 53a46e35..00000000 --- a/bazel/fuzz_target_test_wrapper.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -# 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. - -# Crashes will be available as test outputs. These are cleared on the next run, -# so this is only useful for examples. -DEFAULT_CRASH_PREFIX="$TEST_UNDECLARED_OUTPUTS_DIR" - -# Determine the path to load libjvm.so from, either relative to the location of -# the java binary or to $JAVA_HOME, if set. -JAVA_BIN=$(readlink -f "$(which java)") -JAVA_HOME=${JAVA_HOME:-${JAVA_BIN%/bin/java}} -# The location of libjvm.so relative to the JDK differs between JDK <= 8 and 9+. -JVM_LD_LIBRARY_PATH="$JAVA_HOME/lib/server:$JAVA_HOME/lib/amd64/server" - -LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$JVM_LD_LIBRARY_PATH \ -eval "$1" -artifact_prefix="$DEFAULT_CRASH_PREFIX/" --reproducer_path="$DEFAULT_CRASH_PREFIX" -seed=2735196724 "${@:2}" -# Assert that we either found a crash in java (exit code 77) or an ASan crash -# (exit code 76). -declare -i exit_code=$? -if [ $exit_code -eq 77 ] || [ $exit_code -eq 76 ] -then - if [ "$(ls "$DEFAULT_CRASH_PREFIX/")" ]; then - exit 0 - else - exit 1 - fi -else - echo "Unexpected exit code: $exit_code" - exit 1 -fi diff --git a/bazel/jazzer b/bazel/jazzer deleted file mode 100755 index 97a0ada1..00000000 --- a/bazel/jazzer +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -# Determine the path to load libjvm.so from, either relative to the location of -# the java binary or to $JAVA_HOME, if set. -JAVA_BIN=$(readlink -f "$(which java)") -JAVA_HOME=${JAVA_HOME:-${JAVA_BIN%/bin/java}} -# The location of libjvm.so relative to the JDK differs between JDK <= 8 and 9+. -JVM_LD_LIBRARY_PATH="$JAVA_HOME/lib/server:$JAVA_HOME/lib/amd64/server" - -LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$JVM_LD_LIBRARY_PATH \ -"$(dirname "$0")/jazzer_driver" "$@" - diff --git a/bazel/jazzer_wrapper.sh b/bazel/jazzer_wrapper.sh deleted file mode 100755 index d12e1571..00000000 --- a/bazel/jazzer_wrapper.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# 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. - -# --- begin runfiles.bash initialization v2 --- -# Copy-pasted from the Bazel Bash runfiles library v2. -set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash -source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ -source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ -source "$0.runfiles/$f" 2>/dev/null || \ -source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ -source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ -{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e -# --- end runfiles.bash initialization v2 -- - -DEFAULT_CRASH_PREFIX="/tmp/jazzer" -mkdir -p $DEFAULT_CRASH_PREFIX -eval "$1" -artifact_prefix="$DEFAULT_CRASH_PREFIX/" --reproducer_path="$DEFAULT_CRASH_PREFIX" "${@:2}" diff --git a/bazel/local_jdk_libjvm.bzl b/bazel/local_jdk_libjvm.bzl deleted file mode 100644 index f1481601..00000000 --- a/bazel/local_jdk_libjvm.bzl +++ /dev/null @@ -1,59 +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. - -def _find_recursively_under_path(repository_ctx, path, basename): - result = repository_ctx.execute([ - repository_ctx.which("sh"), - "-c", - """find -L "{path}" -name "{basename}" | head -1""".format( - path = path, - basename = basename, - ), - ]) - if result.return_code != 0: - return None - file_path = result.stdout.strip() - if not file_path: - return None - return repository_ctx.path(file_path) - -LIBJVM_NAMES = [ - "libjvm.dylib", - "libjvm.so", -] - -def _local_jdk_libjvm(repository_ctx): - java_binary = str(repository_ctx.path(Label("@local_jdk//:bin/java"))) - java_home = str(repository_ctx.path(java_binary + "/../../")) - - libjvm_path = None - for libjvm_name in LIBJVM_NAMES: - libjvm_path = _find_recursively_under_path(repository_ctx, java_home, libjvm_name) - if libjvm_path != None: - break - - if libjvm_path != None: - repository_ctx.symlink(libjvm_path, libjvm_path.basename) - build_content = """ -cc_import( - name = "libjvm", - shared_library = "{libjvm}", - visibility = ["//visibility:public"], -) -""".format(libjvm = libjvm_path.basename) - repository_ctx.file("BUILD.bazel", build_content, executable = False) - -local_jdk_libjvm = repository_rule( - implementation = _local_jdk_libjvm, -) |