Skip to content

Commit

Permalink
junit: Only create .cifuzz-corpus if it is the generated corpus
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
fmeum committed Sep 20, 2023
1 parent 7725a74 commit 5189af3
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -169,7 +174,8 @@ private static Optional<String> translateJUnitTimeoutToLibFuzzerFlag(ExtensionCo
*
* @return the temporary Java seed corpus directory
*/
private static Path addInputAndSeedDirs(ExtensionContext context, List<String> libFuzzerArgs)
private static Path addInputAndSeedDirs(
ExtensionContext context, List<String> libFuzzerArgs, boolean createDefaultGeneratedCorpusDir)
throws IOException {
Class<?> fuzzTestClass = context.getRequiredTestClass();
Method fuzzTestMethod = context.getRequiredTestMethod();
Expand All @@ -184,20 +190,25 @@ private static Path addInputAndSeedDirs(ExtensionContext context, List<String> 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 <path> (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 <path> (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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ public void fuzzingEnabled() throws IOException {
assertCrashFileExistsIn(artifactsDirectory);
assertNoCrashFileExistsIn(baseDir);
assertNoCrashFileExistsIn(explicitGeneratedCorpus);
assertNoCrashFileExistsIn(defaultGeneratedCorpus);
// Default generated corpus directory isn't used and thus should not have been created.
assertThat(Files.notExists(defaultGeneratedCorpus)).isTrue();

// Verify that corpus files are written to given corpus directory and not generated one.
assertThat(Files.list(explicitGeneratedCorpus)).isNotEmpty();
assertThat(Files.list(defaultGeneratedCorpus)).isEmpty();
}

@Test
Expand Down

0 comments on commit 5189af3

Please sign in to comment.