diff options
author | Fabian Meumertzheim <meumertzheim@code-intelligence.com> | 2023-10-15 09:42:11 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2023-10-18 11:04:54 +0200 |
commit | b6c967c3ba82031901b6fd80cc2352ab33537dd9 (patch) | |
tree | 8c7fb4e3ada84c1cf713a6ab6bde7d5b21bc4bf5 | |
parent | 52e1a52ef597ac682c8c5e9bcba6fa8369a69478 (diff) | |
download | jazzer-api-b6c967c3ba82031901b6fd80cc2352ab33537dd9.tar.gz |
mutator: Remove invalid inputs check
The check generates a warning for essentially all our tests and doesn't
seem to be easy to make more precise.
8 files changed, 4 insertions, 157 deletions
diff --git a/examples/junit/src/test/java/com/example/MutatorFuzzTest.java b/examples/junit/src/test/java/com/example/MutatorFuzzTest.java index f3644791..741dc8d3 100644 --- a/examples/junit/src/test/java/com/example/MutatorFuzzTest.java +++ b/examples/junit/src/test/java/com/example/MutatorFuzzTest.java @@ -17,7 +17,6 @@ package com.example; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import com.code_intelligence.jazzer.driver.FuzzTargetRunner; import com.code_intelligence.jazzer.junit.FuzzTest; @@ -39,7 +38,6 @@ class MutatorFuzzTest { // FuzzTargetRunner values are not set in JUnit engine tests. String jazzerFuzz = System.getenv("JAZZER_FUZZ"); if (jazzerFuzz != null && !jazzerFuzz.isEmpty()) { - assertTrue(FuzzTargetRunner.invalidCorpusFilesPresent()); assertEquals(FuzzTargetRunner.mutatorDebugString(), "Arguments[Nullable<List<String>>]"); } } diff --git a/src/main/java/com/code_intelligence/jazzer/driver/FuzzTargetRunner.java b/src/main/java/com/code_intelligence/jazzer/driver/FuzzTargetRunner.java index 3d99dcc5..6967b34f 100644 --- a/src/main/java/com/code_intelligence/jazzer/driver/FuzzTargetRunner.java +++ b/src/main/java/com/code_intelligence/jazzer/driver/FuzzTargetRunner.java @@ -99,8 +99,6 @@ public final class FuzzTargetRunner { private static final int LIBFUZZER_CONTINUE = 0; private static final int LIBFUZZER_RETURN_FROM_DRIVER = -2; - private static boolean invalidCorpusFileWarningShown = false; - // Keep these options used in runOne (and thus the critical path) in static final fields so that // they can be constant-folded by the JIT. private static final Set<Long> ignoredTokens = @@ -206,18 +204,7 @@ public final class FuzzTargetRunner { // call to our custom mutator and skip the read entirely. // 2. Implement a InputStream backed by Unsafe to avoid the copyToArray overhead. byte[] buf = copyToArray(dataPtr, dataLength); - boolean readExactly = mutator.read(new ByteArrayInputStream(buf)); - - // All inputs constructed by the mutator framework can be read exactly, existing corpus files - // may not be valid for the current fuzz target anymore, though. In this case, print a warning - // once. - if (!(invalidCorpusFileWarningShown || readExactly || isFixedLibFuzzerInput(buf))) { - invalidCorpusFileWarningShown = true; - Log.warn( - "Some files in the seed corpus do not match the fuzz target signature. This indicates" - + " that they were generated with a different signature and may cause issues" - + " reproducing previous findings."); - } + mutator.read(new ByteArrayInputStream(buf)); data = null; argument = null; } else if (useFuzzedDataProvider) { @@ -361,13 +348,6 @@ public final class FuzzTargetRunner { return LIBFUZZER_CONTINUE; } - private static boolean isFixedLibFuzzerInput(byte[] input) { - // Detect special libFuzzer inputs which can not be processed by the mutator framework. - // libFuzzer always uses an empty input, and one with a single line feed (10) to indicate - // end of initial corpus file processing. - return input.length == 0 || (input.length == 1 && input[0] == 10); - } - // Called via JNI, being passed data from LLVMFuzzerCustomMutator. @SuppressWarnings("unused") private static int mutateOne(long data, int size, int maxSize, int seed) { @@ -586,14 +566,6 @@ public final class FuzzTargetRunner { } /** - * Returns whether the current mutator has detected invalid corpus files. If no mutator is used, - * returns false. - */ - public static boolean invalidCorpusFilesPresent() { - return mutator != null && invalidCorpusFileWarningShown; - } - - /** * Disables libFuzzer's fuzz target exit detection until the next call to {@link #runOne}. * * <p>Calling {@link System#exit} after having called this method will not trigger libFuzzer's diff --git a/src/main/java/com/code_intelligence/jazzer/junit/SeedArgumentsProvider.java b/src/main/java/com/code_intelligence/jazzer/junit/SeedArgumentsProvider.java index 30d97a14..f76d079d 100644 --- a/src/main/java/com/code_intelligence/jazzer/junit/SeedArgumentsProvider.java +++ b/src/main/java/com/code_intelligence/jazzer/junit/SeedArgumentsProvider.java @@ -84,12 +84,6 @@ class SeedArgumentsProvider implements ArgumentsProvider { + "To start fuzzing, run a test with the environment variable JAZZER_FUZZ" + " set to a non-empty value."); } - if (!serializer.allReadsValid()) { - extensionContext.publishReportEntry( - "Some files in the seed corpus do not match the fuzz target signature.\n" - + "This indicates that they were generated with a different signature and" - + " may cause issues reproducing previous findings."); - } }); } diff --git a/src/main/java/com/code_intelligence/jazzer/junit/SeedSerializer.java b/src/main/java/com/code_intelligence/jazzer/junit/SeedSerializer.java index 55d51ae6..67d04762 100644 --- a/src/main/java/com/code_intelligence/jazzer/junit/SeedSerializer.java +++ b/src/main/java/com/code_intelligence/jazzer/junit/SeedSerializer.java @@ -29,10 +29,6 @@ import java.util.Optional; interface SeedSerializer { Object[] read(byte[] bytes); - default boolean allReadsValid() { - return true; - } - // Implementations can assume that the argument array contains valid arguments for the method that // this instance has been constructed for. byte[] write(Object[] args) throws UnsupportedOperationException; @@ -95,7 +91,6 @@ final class FuzzedDataProviderSeedSerializer implements SeedSerializer { final class ArgumentsMutatorSeedSerializer implements SeedSerializer { private final ArgumentsMutator mutator; - private boolean allReadsValid; public ArgumentsMutatorSeedSerializer(ArgumentsMutator mutator) { this.mutator = mutator; @@ -103,16 +98,11 @@ final class ArgumentsMutatorSeedSerializer implements SeedSerializer { @Override public Object[] read(byte[] bytes) { - allReadsValid &= mutator.read(new ByteArrayInputStream(bytes)); + mutator.read(new ByteArrayInputStream(bytes)); return mutator.getArguments(); } @Override - public boolean allReadsValid() { - return allReadsValid; - } - - @Override public byte[] write(Object[] args) { ByteArrayOutputStream out = new ByteArrayOutputStream(); mutator.writeAny(out, args); diff --git a/src/main/java/com/code_intelligence/jazzer/mutation/ArgumentsMutator.java b/src/main/java/com/code_intelligence/jazzer/mutation/ArgumentsMutator.java index 55d1b57c..f8e323e9 100644 --- a/src/main/java/com/code_intelligence/jazzer/mutation/ArgumentsMutator.java +++ b/src/main/java/com/code_intelligence/jazzer/mutation/ArgumentsMutator.java @@ -17,7 +17,6 @@ package com.code_intelligence.jazzer.mutation; import static com.code_intelligence.jazzer.mutation.mutator.Mutators.validateAnnotationUsage; -import static com.code_intelligence.jazzer.mutation.support.InputStreamSupport.extendWithReadExactly; import static com.code_intelligence.jazzer.mutation.support.Preconditions.require; import static com.code_intelligence.jazzer.mutation.support.StreamSupport.toArrayOrEmpty; import static java.lang.String.format; @@ -31,7 +30,6 @@ import com.code_intelligence.jazzer.mutation.combinator.MutatorCombinators; import com.code_intelligence.jazzer.mutation.combinator.ProductMutator; import com.code_intelligence.jazzer.mutation.engine.SeededPseudoRandom; import com.code_intelligence.jazzer.mutation.mutator.Mutators; -import com.code_intelligence.jazzer.mutation.support.InputStreamSupport.ReadExactlyInputStream; import com.code_intelligence.jazzer.mutation.support.Preconditions; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -116,15 +114,12 @@ public final class ArgumentsMutator { } /** - * @return if the given input stream was consumed exactly * @throws UncheckedIOException if the underlying InputStream throws */ - public boolean read(ByteArrayInputStream data) { + public void read(ByteArrayInputStream data) { try { - ReadExactlyInputStream is = extendWithReadExactly(data); - arguments = productMutator.readExclusive(is); + arguments = productMutator.readExclusive(data); argumentsExposed = false; - return is.isConsumedExactly(); } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/src/main/java/com/code_intelligence/jazzer/mutation/support/InputStreamSupport.java b/src/main/java/com/code_intelligence/jazzer/mutation/support/InputStreamSupport.java index e0902428..2d9f4abd 100644 --- a/src/main/java/com/code_intelligence/jazzer/mutation/support/InputStreamSupport.java +++ b/src/main/java/com/code_intelligence/jazzer/mutation/support/InputStreamSupport.java @@ -193,64 +193,5 @@ public final class InputStreamSupport { } } - /** - * Wraps a given stream with the functionality to detect if it was read exactly. To do so, the - * stream must provide an accurate implementation of {@link InputStream#available()}, hence it's - * restricted to {@link ByteArrayInputStream} for now. - * - * @return {@code stream} extended that detects if it was consumed exactly - */ - public static ReadExactlyInputStream extendWithReadExactly(ByteArrayInputStream stream) { - return new ReadExactlyInputStream(requireNonNull(stream)); - } - - public static final class ReadExactlyInputStream extends InputStream { - private final InputStream stream; - private boolean eof; - - private ReadExactlyInputStream(InputStream stream) { - this.stream = stream; - this.eof = false; - } - - public boolean isConsumedExactly() { - try { - // Forwards availability check to the underlying ByteInputStream, - // which is accurate for the number of available bytes. - return !eof && available() == 0; - } catch (IOException e) { - return false; - } - } - - @Override - public int read() throws IOException { - int res = stream.read(); - if (res == -1) { - eof = true; - } - return res; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - int read = stream.read(b, off, len); - if (read < len) { - eof = true; - } - return read; - } - - @Override - public int available() throws IOException { - return stream.available(); - } - - @Override - public void close() throws IOException { - stream.close(); - } - } - private InputStreamSupport() {} } diff --git a/src/test/java/com/code_intelligence/jazzer/junit/MutatorTest.java b/src/test/java/com/code_intelligence/jazzer/junit/MutatorTest.java index 13ab8073..60d96567 100644 --- a/src/test/java/com/code_intelligence/jazzer/junit/MutatorTest.java +++ b/src/test/java/com/code_intelligence/jazzer/junit/MutatorTest.java @@ -35,14 +35,11 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import org.assertj.core.api.Condition; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.junit.platform.engine.reporting.ReportEntry; import org.junit.platform.testkit.engine.EngineExecutionResults; import org.junit.platform.testkit.engine.EngineTestKit; -import org.junit.platform.testkit.engine.Event; import org.junit.rules.TemporaryFolder; public class MutatorTest { @@ -97,15 +94,6 @@ public class MutatorTest { event(type(STARTED), container(ENGINE)), event(type(STARTED), container(uniqueIdSubstrings(ENGINE, CLAZZ))), event(type(STARTED), container(uniqueIdSubstrings(ENGINE, CLAZZ, LIFECYCLE_FUZZ))), - // Invalid corpus input warning - event( - type(REPORTING_ENTRY_PUBLISHED), - container(uniqueIdSubstrings(ENGINE, CLAZZ, LIFECYCLE_FUZZ)), - new Condition<>( - Event.byPayload( - ReportEntry.class, - (it) -> it.getKeyValuePairs().values().contains(INVALID_SIGNATURE_ENTRY)), - "has invalid signature entry reporting entry")), event( type(FINISHED), container(uniqueIdSubstrings(ENGINE, CLAZZ, LIFECYCLE_FUZZ)), @@ -173,10 +161,6 @@ public class MutatorTest { event( type(REPORTING_ENTRY_PUBLISHED), container(uniqueIdSubstrings(ENGINE, CLAZZ, LIFECYCLE_FUZZ))), - // Invalid corpus input warning - event( - type(REPORTING_ENTRY_PUBLISHED), - container(uniqueIdSubstrings(ENGINE, CLAZZ, LIFECYCLE_FUZZ))), event(type(FINISHED), container(uniqueIdSubstrings(ENGINE, CLAZZ, LIFECYCLE_FUZZ))), event( type(FINISHED), diff --git a/src/test/java/com/code_intelligence/jazzer/mutation/support/InputStreamSupportTest.java b/src/test/java/com/code_intelligence/jazzer/mutation/support/InputStreamSupportTest.java index 29963f4f..13087fbb 100644 --- a/src/test/java/com/code_intelligence/jazzer/mutation/support/InputStreamSupportTest.java +++ b/src/test/java/com/code_intelligence/jazzer/mutation/support/InputStreamSupportTest.java @@ -17,13 +17,11 @@ package com.code_intelligence.jazzer.mutation.support; import static com.code_intelligence.jazzer.mutation.support.InputStreamSupport.cap; -import static com.code_intelligence.jazzer.mutation.support.InputStreamSupport.extendWithReadExactly; import static com.code_intelligence.jazzer.mutation.support.InputStreamSupport.extendWithZeros; import static com.code_intelligence.jazzer.mutation.support.InputStreamSupport.infiniteZeros; import static com.code_intelligence.jazzer.mutation.support.InputStreamSupport.readAllBytes; import static com.google.common.truth.Truth.assertThat; -import com.code_intelligence.jazzer.mutation.support.InputStreamSupport.ReadExactlyInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -118,29 +116,4 @@ class InputStreamSupportTest { assertThat(readAllBytes(input)).isEqualTo(bytes); } - - @Test - @SuppressWarnings("ResultOfMethodCallIgnored") - void testReadExactly() throws IOException { - ReadExactlyInputStream ce = extendWithReadExactly(new ByteArrayInputStream(new byte[] {0, 1})); - assertThat(ce.isConsumedExactly()).isFalse(); - ce.read(); - assertThat(ce.isConsumedExactly()).isFalse(); - ce.read(); - assertThat(ce.isConsumedExactly()).isTrue(); - ce.read(); - assertThat(ce.isConsumedExactly()).isFalse(); - } - - @Test - @SuppressWarnings("ResultOfMethodCallIgnored") - void testReadExactly_readBytes() throws IOException { - ReadExactlyInputStream ce = - extendWithReadExactly(new ByteArrayInputStream(new byte[] {0, 1, 2})); - assertThat(ce.isConsumedExactly()).isFalse(); - ce.read(new byte[3]); - assertThat(ce.isConsumedExactly()).isTrue(); - ce.read(new byte[1]); - assertThat(ce.isConsumedExactly()).isFalse(); - } } |