Age | Commit message (Collapse) | Author |
|
Achieved by inlining the flags into jvm_tooling, which is the only
remaining consumer of these flags.
|
|
Inline the remaining single constant into jvm_tooling.cpp.
|
|
By using LLVMFuzzerRunDriver, we can remove the LibfuzzerDriver class
and replace it by:
* a real main function that preprocesses arguments for libFuzzer and
starts a JVM;
* everything else turned into a proper library with no dependency on our
custom JVM class.
This will allow us to turn everything except the main function into a
JNI shared library, opening up the possibility to launch Jazzer from an
already running JVM.
|
|
This decouples jvm_tooling from libfuzzer_callbacks.
|
|
Test uses of JVM methods have been replaced with the equivalent standard
JNI function.
|
|
This is mostly a faithful Java rewrite of the original native code,
with a few changes believed not to cause any serious backwards
compatibility concerns:
* Emit an empty line to stderr rather than stdout before the Java
exception. DEDUP_TOKEN does not have to appear at the beginning of a
line to be picked up by libFuzzer, so this seems more consistent.
* Simplify the logic around dedup tokens to also emit them with hooks
set to false, but not by default.
* Do not emit the escape character when splitting a list-valued argument
on a separator - this appeared to be a design bug.
* Use the same "split on unescaped separator" function for all
splitting.
The native tests have been replaced by a single comprehensive Java test.
|
|
The new argument can be used to selectively disable both custom and and
built-in hooks.
Also mentions the OS-dependent separator in agent flag descriptions.
|
|
Fixes https://github.com/google/oss-fuzz/issues/7507
|
|
Java agent jars are automatically added to the system class loader,
which means that an explicit class path entry for them is both redundant
and potentially confusing.
|
|
|
|
This reduces the amount of JNI code and enables us to use JavaCritical
to further optimize the callback invocations.
|
|
|
|
Drastically reduces the amount of JNI code and idiomatically ensures
that initialization happens when needed.
|
|
The seed comes with an appropriate Javadoc warning describing
appropriate and inappropriate use cases.
|
|
This will make it easier to add another modification in a follow-up
commit.
Also replaces a number of non-idiomatic usages of string references or
string_view references with pass-by-value string_views.
|
|
This commit moves almost all coverage map logic into the Java class
with the aim of making it easier to replace the particular
implementation of the coverage map and reducing the amount of JNI code.
This is almost a pure refactoring, but also makes the allocations of
fake instructions and libFuzzer PC entries dynamic. This both slightly
reduces the constant memory footprint of the fuzzer and further
improves the encapsulation of the Java CoverageMap implementation as the
native code no longer has to know the maximum size of the map.
|
|
The only mechanism to specify JVM arguments currently supported by
Jazzer is the --jvm_args argument, which has a syntax that differs
between OSes and may require shell quoting.
This commit makes Jazzer honor the JAVA_OPTS environment variable, which
is used by many popular Java tools to specify arguments to the JVMs they
invoke.
|
|
This allows us to get rid of the libFuzzer patch to quote argv, which
breaks Windows and would have to be turned into a conditional patch
otherwise.
With this change, all argument separators use the same syntax as the
java executable on any given platform.
Collisions of ':' as an argument separator and a classpath separator
should be rare as we have our own argument to pass in the classpath.
This commit implements a rudimentary escaping mechanism to handle the
cases where this should be an issue:
* \<separator> results in a literal <separator> and no split
* \\ results in a literal backlash not interpreted as an escape
character for a subsequent <separator>
This is a breaking change, but we should rather break this now that we
haven't committed to a version 1.0 yet. The only breakage I am aware of
is easily fixed:
https://github.com/google/oss-fuzz/blob/0c1d5231de61b4166281b4d5685aa66e9f4948a8/projects/kryo/build.sh#L48
|
|
This masked failing tests in the CI.
Along the way, improve the error message.
|
|
https://docs.oracle.com/en/java/javase/11/gctuning/available-collectors.html#GUID-414C9D95-297E-4EE3-B0D9-36F158A83393
|
|
When libFuzzer without a sanitizer times out, this prints the current
stack traces of all JVM threads, e.g.:
==1235420== ERROR: libFuzzer: timeout after 3 seconds
Stack traces of all JVM threads:
Thread[Signal Dispatcher,9,system]
Thread[Notification Thread,9,system]
Thread[Reference Handler,10,system]
at java.base@15.0.3/java.lang.ref.Reference.waitForReferencePendingList(Native Method)
at java.base@15.0.3/java.lang.ref.Reference.processPendingReferences(Reference.java:241)
at java.base@15.0.3/java.lang.ref.Reference$ReferenceHandler.run(Reference.java:213)
Thread[Finalizer,8,system]
at java.base@15.0.3/java.lang.Object.wait(Native Method)
at java.base@15.0.3/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
at java.base@15.0.3/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:176)
at java.base@15.0.3/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170)
Thread[main,5,main]
at com.code_intelligence.jazzer.runtime.TraceDataFlowNativeCallbacks.traceCmpInt(Native Method)
at app//com.example.ExampleFuzzer.fuzzerTestOneInput(ExampleFuzzer.java:28)
Thread[Common-Cleaner,8,InnocuousThreadGroup]
at java.base@15.0.3/java.lang.Object.wait(Native Method)
at java.base@15.0.3/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)
at java.base@15.0.3/jdk.internal.ref.CleanerImpl.run(CleanerImpl.java:148)
at java.base@15.0.3/java.lang.Thread.run(Thread.java:832)
at java.base@15.0.3/jdk.internal.misc.InnocuousThread.run(InnocuousThread.java:134)
SUMMARY: libFuzzer: timeout
Unexpected exit code: 70
|
|
The -Xmx setting does not account for the following additional heap
usage that is included in the RSS limit maintained by libFuzzer:
- Metaspace, which contains Java class metadata and is on the order of
25 MB for the Jazzer examples.
- Jazzer coverage counters
By lowering the default -Xmx setting, we make it less likely that
a target crashes with a libFuzzer OOM.
|
|
Local JNI references are cleaned up only when the stack they were
created on returns to the JVM, not on any return to the JVM. Since we
are using the Java Invocation API to launch the JVM, we thus have to
explicitly delete all local references that are created in functions
that were not called from a Java method.
For more information, see
https://stackoverflow.com/a/42333173/14712674
https://www.ibm.com/docs/en/sdk-java-technology/8?topic=collector-jni-transitions
|
|
The native callbacks in the driver should be registered as early as
possible since they may already be needed during agent startup (e.g.,
if a JDK-internal class is to be instrumented).
|
|
With --dump_classes_dir=<dir>, all classes that are instrumented by the
agent at runtime will be dumped into a subdirectory of <dir> according
to their internal class name.
|
|
|
|
In certain situations, such as OSS-Fuzz coverage reports, additional
JVM args need to be specified on the command line after --jvm_args has
already been used. Specifying --jvm_args again overrides the previous
arguments rather than appending to them.
This commit adds an additional flag for adding JVM args that will be
emitted after the flags specified in --jvm_args.
|
|
If Jazzer is imported as an external workspace from another Bazel
workspace, the runfiles path of the agent is
../jazzer/agent/jazzer_agent_deploy.jar rather than
agent/jazzer_agent_deploy.jar. Since the first path applies more
generally, we switch to it, but perform a check for a Bazel env variable
to prevent loading agents from potentially untrusted sibling dirs.
|
|
libFuzzer defaults to an rss_limit_mb of 2048, but we start the JVM with
-Xmx4096m. This can lead to libFuzzer OOM reports when a single
allocation in Java exceeds 2 GB but still fits into the JVM heap.
This is solved by letting the JVM heap size default to slightly less
than 2 GB.
This change is not fully backwards compatible, but will only cause
targets to crash more often than they used to.
|
|
|
|
|
|
Not all findings can easily be reported as uncaught exceptions, e.g.
exceptions raised in a hook might be caught and swallowed by library
code.
This change adds a global variable in the Java runtime that is checked
by the fuzzer after every invocation of the fuzz target. If it contains
a finding (represented as a Throwable), it is reported by Jazzer.
|
|
|
|
Instead of parsing and modifying the stack trace in the driver, a
preprocessing step in Kotlin now adds the severity markers.
It also performs basic deduplication of StackOverflowErrors.
|
|
Catches and clears the exception in a single place, passing it to the
pretty printing routines as an argument.
This fixes issues in which the Java utility methods did not operate
correctly as there was still an exception on the stack.
|
|
|
|
|
|
When run with e.g. the -fork flag, libFuzzer delegates the fuzzing to
multiple child processes running concurrently. As each of these
processes runs its own JVM with its own instance of the Jazzer agent,
different ranges of coverage IDs may be assigned to the same class
depending on when it is discovered by that fuzzer process. Since
libFuzzer collates the coverage counter buffers, this leads to
misreported coverage and unnecessarily large corpora.
This commit adds a coverage ID generation strategy that uses a lockable
temporary file as a means to synchronize the IDs between multiple
processes. This requires injecting new command-line arguments into
libFuzzer, building on the previous commit.
One of the example fuzz targets is set to be fuzzed in fork mode, which
provides test coverage for the new feature.
|
|
|