diff options
author | Fabian Meumertzheim <fabian@meumertzhe.im> | 2022-08-17 10:20:45 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2022-08-17 11:39:25 +0200 |
commit | 8c4f8830a5e69421d7ab835a5409bc41efca61b8 (patch) | |
tree | 116bcdada26c271cd0dcf89763b2c19296ca9ae6 | |
parent | a9b21fbf119ab42003dad9d2810cfa99f3f97b02 (diff) | |
download | jazzer-api-8c4f8830a5e69421d7ab835a5409bc41efca61b8.tar.gz |
driver: Fix driver crash when not supplying -seed
The reduce function was misused - prev was always the first CLI
argument, not an empty Optional.
4 files changed, 76 insertions, 25 deletions
diff --git a/bazel/tools/java/com/code_intelligence/jazzer/tools/FuzzTargetTestWrapper.java b/bazel/tools/java/com/code_intelligence/jazzer/tools/FuzzTargetTestWrapper.java index f4ca0ce7..107d8526 100644 --- a/bazel/tools/java/com/code_intelligence/jazzer/tools/FuzzTargetTestWrapper.java +++ b/bazel/tools/java/com/code_intelligence/jazzer/tools/FuzzTargetTestWrapper.java @@ -23,13 +23,13 @@ import java.net.URLClassLoader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; @@ -48,7 +48,7 @@ public class FuzzTargetTestWrapper { boolean verifyCrashReproducer; boolean expectCrash; Set<String> expectedFindings; - Stream<String> arguments; + List<String> arguments; try { runfiles = Runfiles.create(); driverActualPath = lookUpRunfile(runfiles, args[0]); @@ -60,8 +60,11 @@ public class FuzzTargetTestWrapper { expectedFindings = Arrays.stream(args[6].split(",")).filter(s -> !s.isEmpty()).collect(Collectors.toSet()); // Map all files/dirs to real location - arguments = Arrays.stream(args).skip(7).map( - arg -> arg.startsWith("-") ? arg : lookUpRunfileWithFallback(runfiles, arg)); + arguments = + Arrays.stream(args) + .skip(7) + .map(arg -> arg.startsWith("-") ? arg : lookUpRunfileWithFallback(runfiles, arg)) + .collect(Collectors.toList()); } catch (IOException | ArrayIndexOutOfBoundsException e) { e.printStackTrace(); System.exit(1); @@ -77,13 +80,16 @@ public class FuzzTargetTestWrapper { // 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)), - arguments) - .collect(Collectors.toList()); + List<String> command = new ArrayList<>(); + command.add(driverActualPath); + command.add(String.format("-artifact_prefix=%s/", outputDir)); + command.add(String.format("--reproducer_path=%s", outputDir)); + command.add(String.format("--cp=%s", jarActualPath)); + if (System.getenv("JAZZER_NO_EXPLICIT_SEED") == null) { + command.add("-seed=2735196724"); + } + command.addAll(arguments); + processBuilder.inheritIO(); if (JAZZER_CI) { // Make JVM error reports available in test outputs. diff --git a/driver/src/main/java/com/code_intelligence/jazzer/driver/Driver.java b/driver/src/main/java/com/code_intelligence/jazzer/driver/Driver.java index 75dec5e5..45e7b72e 100644 --- a/driver/src/main/java/com/code_intelligence/jazzer/driver/Driver.java +++ b/driver/src/main/java/com/code_intelligence/jazzer/driver/Driver.java @@ -70,20 +70,17 @@ public class Driver { // occurrence of a "-seed" argument as that is the one that is used by libFuzzer. If none is // set, generate one and pass it to libFuzzer so that a fuzzing run can be reproduced simply by // setting the seed printed by libFuzzer. - String seed = - args.stream() - .reduce( - (prev, cur) -> cur.startsWith("-seed=") ? cur.substring("-seed=".length()) : prev) - .orElseGet(() -> { - String newSeed = Integer.toUnsignedString(new SecureRandom().nextInt()); - // Only add the -seed argument to the command line if not running in a mode - // that spawns subprocesses. These would inherit the same seed, which might - // make them less effective. - if (!spawnsSubprocesses) { - args.add("-seed=" + newSeed); - } - return newSeed; - }); + String seed = args.stream().reduce( + null, (prev, cur) -> cur.startsWith("-seed=") ? cur.substring("-seed=".length()) : prev); + if (seed == null) { + seed = Integer.toUnsignedString(new SecureRandom().nextInt()); + // Only add the -seed argument to the command line if not running in a mode + // that spawns subprocesses. These would inherit the same seed, which might + // make them less effective. + if (!spawnsSubprocesses) { + args.add("-seed=" + seed); + } + } System.setProperty("jazzer.seed", seed); if (args.stream().noneMatch(arg -> arg.startsWith("-rss_limit_mb="))) { diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel index ba2a8f6d..c32d0b6a 100644 --- a/tests/BUILD.bazel +++ b/tests/BUILD.bazel @@ -223,3 +223,17 @@ java_fuzz_target_test( ], target_class = "com.example.SeedFuzzer", ) + +java_fuzz_target_test( + name = "NoSeedFuzzer", + timeout = "short", + srcs = ["src/test/java/com/example/NoSeedFuzzer.java"], + env = { + "JAZZER_NO_EXPLICIT_SEED": "1", + }, + expect_crash = False, + fuzzer_args = [ + "-runs=0", + ], + target_class = "com.example.NoSeedFuzzer", +) diff --git a/tests/src/test/java/com/example/NoSeedFuzzer.java b/tests/src/test/java/com/example/NoSeedFuzzer.java new file mode 100644 index 00000000..bf1c1103 --- /dev/null +++ b/tests/src/test/java/com/example/NoSeedFuzzer.java @@ -0,0 +1,34 @@ +/* + * Copyright 2022 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. + */ + +package com.example; + +import com.code_intelligence.jazzer.api.Jazzer; + +public class NoSeedFuzzer { + public static void fuzzerInitialize() { + // Verify that the seed was randomly generated and not taken to be the fixed + // one set in FuzzTargetTestWrapper. This has a 1 / INT_MAX chance to be + // flaky, which is acceptable. + if (Jazzer.SEED == (int) 2735196724L) { + System.err.println( + "Jazzer.SEED should not equal the fixed seed set in FuzzTargetTestWrapper"); + System.exit(1); + } + } + + public static void fuzzerTestOneInput(byte[] data) {} +} |