1# Copyright 2021 Code Intelligence GmbH 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15def java_fuzz_target_test( 16 name, 17 target_class = None, 18 target_method = None, 19 deps = [], 20 runtime_deps = [], 21 hook_jar = None, 22 data = [], 23 launcher_variant = "java", 24 tags = [], 25 fuzzer_args = [], 26 srcs = [], 27 size = None, 28 timeout = None, 29 env = None, 30 env_inherit = None, 31 verify_crash_input = True, 32 verify_crash_reproducer = True, 33 # Superset of the findings the fuzzer is expected to find. Since fuzzing runs are not 34 # deterministic across OSes, pinpointing the exact set of findings is difficult. 35 allowed_findings = [], 36 # By default, expect a crash iff allowed_findings isn't empty. 37 expect_crash = None, 38 **kwargs): 39 if target_class: 40 fuzzer_args = fuzzer_args + ["--target_class=" + target_class] 41 if target_method: 42 fuzzer_args = fuzzer_args + ["--target_method=" + target_method] 43 if expect_crash == None: 44 expect_crash = len(allowed_findings) != 0 45 46 target_name = name + "_target" 47 target_deploy_jar = target_name + "_deploy.jar" 48 49 # Deps can only be specified on java_binary targets with sources, which 50 # excludes e.g. Kotlin libraries wrapped into java_binary via runtime_deps. 51 deps = deps + ["//deploy:jazzer-api"] if srcs else [] 52 native.java_binary( 53 name = target_name, 54 srcs = srcs, 55 create_executable = False, 56 visibility = ["//visibility:private"], 57 deps = deps, 58 runtime_deps = runtime_deps, 59 testonly = True, 60 tags = tags, 61 **kwargs 62 ) 63 64 if launcher_variant == "java": 65 # With the Java driver, we expect fuzz targets to depend on Jazzer 66 # rather than have the launcher start a JVM with Jazzer on the class 67 # path. 68 native.java_import( 69 name = target_name + "_import", 70 jars = [target_deploy_jar], 71 testonly = True, 72 tags = tags, 73 ) 74 target_with_driver_name = target_name + "_driver" 75 native.java_binary( 76 name = target_with_driver_name, 77 runtime_deps = [ 78 target_name + "_import", 79 "//src/main/java/com/code_intelligence/jazzer:jazzer_import", 80 ], 81 main_class = "com.code_intelligence.jazzer.Jazzer", 82 testonly = True, 83 tags = tags, 84 ) 85 86 if launcher_variant == "native": 87 driver = "//launcher:jazzer" 88 elif launcher_variant == "java": 89 driver = target_with_driver_name 90 else: 91 fail("Invalid launcher variant: " + launcher_variant) 92 93 native.java_test( 94 name = name, 95 runtime_deps = [ 96 "//bazel/tools/java:fuzz_target_test_wrapper", 97 ], 98 jvm_flags = [ 99 # Use the same memory settings for reproducers as those suggested by Jazzer when 100 # encountering an OutOfMemoryError. 101 "-Xmx1620m", 102 # Ensure that reproducers can be compiled even if they contain UTF-8 characters. 103 "-Dfile.encoding=UTF-8", 104 ], 105 size = size or "enormous", 106 timeout = timeout or "moderate", 107 # args are shell tokenized and thus quotes are required in the case where arguments 108 # are empty. 109 args = [ 110 "$(rlocationpath %s)" % driver, 111 "$(rlocationpath //deploy:jazzer-api)", 112 "$(rlocationpath %s)" % target_deploy_jar, 113 "$(rlocationpath %s)" % hook_jar if hook_jar else "''", 114 str(verify_crash_input), 115 str(verify_crash_reproducer), 116 str(expect_crash), 117 str(launcher_variant == "java"), 118 "'" + ",".join(allowed_findings) + "'", 119 ] + fuzzer_args, 120 data = [ 121 target_deploy_jar, 122 "//deploy:jazzer-api", 123 driver, 124 ] + data + ([hook_jar] if hook_jar else []), 125 env = env, 126 env_inherit = env_inherit, 127 main_class = "com.code_intelligence.jazzer.tools.FuzzTargetTestWrapper", 128 use_testrunner = False, 129 tags = tags, 130 ) 131