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