From 33e6c9ae08ee73278397642cdd4b090c0f780f6e Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Wed, 20 Sep 2023 11:03:23 +0200 Subject: [PATCH] junit: Only create `.cifuzz-corpus` if it is the generated corpus If users add custom corpus directories, the first of those will be used as the generated corpus instead of the default `.cifuzz-corpus` directory. We now no longer create this directory if it is going to stay empty because it isn't used as the generated corpus directory. --- .../jazzer/junit/FuzzTestExecutor.java | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/code_intelligence/jazzer/junit/FuzzTestExecutor.java b/src/main/java/com/code_intelligence/jazzer/junit/FuzzTestExecutor.java index ee30fb534..7537a7fd8 100644 --- a/src/main/java/com/code_intelligence/jazzer/junit/FuzzTestExecutor.java +++ b/src/main/java/com/code_intelligence/jazzer/junit/FuzzTestExecutor.java @@ -112,7 +112,12 @@ public static FuzzTestExecutor prepare(ExtensionContext context, String maxDurat && corpusFilesOrDirs.stream().map(Paths::get).allMatch(Files::isRegularFile)) { javaSeedsDir = Optional.empty(); } else { - javaSeedsDir = Optional.of(addInputAndSeedDirs(context, libFuzzerArgs)); + // Only create the default generated corpus directory if it is used as the generated corpus + // directory, i.e., if the user didn't provide any custom corpus directories that come before + // it on the libFuzzer command line. + boolean createDefaultGeneratedCorpusDir = corpusFilesOrDirs.isEmpty(); + javaSeedsDir = + Optional.of(addInputAndSeedDirs(context, libFuzzerArgs, createDefaultGeneratedCorpusDir)); } libFuzzerArgs.add("-max_total_time=" + durationStringToSeconds(maxDuration)); @@ -169,7 +174,8 @@ private static Optional translateJUnitTimeoutToLibFuzzerFlag(ExtensionCo * * @return the temporary Java seed corpus directory */ - private static Path addInputAndSeedDirs(ExtensionContext context, List libFuzzerArgs) + private static Path addInputAndSeedDirs( + ExtensionContext context, List libFuzzerArgs, boolean createDefaultGeneratedCorpusDir) throws IOException { Class fuzzTestClass = context.getRequiredTestClass(); Method fuzzTestMethod = context.getRequiredTestMethod(); @@ -184,20 +190,25 @@ private static Path addInputAndSeedDirs(ExtensionContext context, List l // The path is specified relative to the current working directory, which with JUnit is the // project directory. Path generatedCorpusDir = baseDir.resolve(generatedCorpusPath(fuzzTestClass, fuzzTestMethod)); - Files.createDirectories(generatedCorpusDir); - String absoluteCorpusDir = generatedCorpusDir.toAbsolutePath().toString(); - - // Even if support for long paths (+260 characters) is enabled on Windows, - // libFuzzer does not work properly. This can be circumvented by prepending "\\?\" to the path, - // see: - // https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry - // Error message: "GetFileAttributesA() failed for (Error code: 3)." - // https://github.com/llvm/llvm-project/blob/release/17.x/compiler-rt/lib/fuzzer/FuzzerIOWindows.cpp#L65 - if (Utils.isWindows()) { - absoluteCorpusDir = "\\\\?\\" + absoluteCorpusDir; + if (createDefaultGeneratedCorpusDir) { + Files.createDirectories(generatedCorpusDir); } + if (Files.exists(generatedCorpusDir)) { + String absoluteCorpusDir = generatedCorpusDir.toAbsolutePath().toString(); + + // Even if support for long paths (+260 characters) is enabled on Windows, + // libFuzzer does not work properly. This can be circumvented by prepending "\\?\" to the + // path, + // see: + // https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry + // Error message: "GetFileAttributesA() failed for (Error code: 3)." + // https://github.com/llvm/llvm-project/blob/release/17.x/compiler-rt/lib/fuzzer/FuzzerIOWindows.cpp#L65 + if (Utils.isWindows()) { + absoluteCorpusDir = "\\\\?\\" + absoluteCorpusDir; + } - libFuzzerArgs.add(absoluteCorpusDir); + libFuzzerArgs.add(absoluteCorpusDir); + } // We can only emit findings into the source tree version of the inputs directory, not e.g. the // copy under Maven's target directory. If it doesn't exist, collect the inputs in the current