Reorganize and update the Java documentation in the README file in a … (#166)
* Reorganize and update the Java documentation in the README file in a single section. This should make it easier for readers to find all the Java-specific information.
* Fix typo.
* Remove duplicated entries.
* Fix the README Java example.
* Small clarification.
* Make Java support a bit more prominent.
* Do not hardcode clang version.
* Tweaks.
* Add more context to the WORKSPACE snippet.
* Fix typo.
* Update the User Guide with more --config examples.
diff --git a/README.md b/README.md
index a7a8562..a1d5b05 100644
--- a/README.md
+++ b/README.md
@@ -4,12 +4,14 @@
[Fuzzing](https://en.wikipedia.org/wiki/Fuzzing) is an effective technique for uncovering security and stability bugs in software. Fuzzing works by invoking the code under test (e.g., a library API) with automatically generated data, and observing its execution to discover incorrect behavior, such as memory corruption or failed invariants. Read more [here](https://github.com/google/fuzzing) about fuzzing, additional examples, best practices, and other resources.
+The rule library currently provides support for C++ and Java fuzz tests. Support for additional languages may be added in the future.
+
## Features at a glance
* Multiple fuzzing engines out of the box:
* [libFuzzer][libfuzzer-doc]
* [Honggfuzz][honggfuzz-doc]
- * [Jazzer][jazzer-doc]
+ * Java fuzzing through [Jazzer][jazzer-doc]
* Multiple sanitizer configurations:
* [Address Sanitizer][asan-doc]
* [Memory Sanitizer][msan-doc]
@@ -23,8 +25,6 @@
* Defining additional fuzzing engines
* Customizing the behavior of the fuzz test rule.
-The rule library currently provides support for C++ and Java fuzz tests. Support for additional languages may be added in the future.
-
Contributions are welcome! Please read the [contribution guidelines](/docs/contributing.md).
## Getting started
@@ -55,21 +55,11 @@
load("@rules_fuzzing//fuzzing:repositories.bzl", "rules_fuzzing_dependencies")
-# Pass jazzer = True to rules_fuzzing_dependencies for Java fuzzing support.
rules_fuzzing_dependencies()
load("@rules_fuzzing//fuzzing:init.bzl", "rules_fuzzing_init")
rules_fuzzing_init()
-
-# For Java fuzzing support, uncomment the following lines.
-# load("@jazzer//:repositories.bzl", "jazzer_dependencies")
-#
-# jazzer_dependencies()
-#
-# load("@jazzer//:init.bzl", "jazzer_init")
-#
-# jazzer_init()
```
> NOTE: Replace this snippet with the [latest release instructions](https://github.com/bazelbuild/rules_fuzzing/releases/latest). To get the latest unreleased features, you may need to change the `urls` and `sha256` attributes to fetch from `HEAD`. For more complex `WORKSPACE` files, you may also need to reconcile conflicting dependencies; read more in the [Bazel documentation](https://docs.bazel.build/versions/master/external.html).
@@ -90,7 +80,7 @@
build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
```
-Examples for other combinations of fuzzing engine and sanitizer can be found in the project's [`.bazelrc`](/.bazelrc).
+Examples for other combinations of fuzzing engine and sanitizer can be found in the [User Guide](/docs/guide.md#configuring-the-bazelrc-file).
### Defining a C++ fuzz test
@@ -152,11 +142,49 @@
The crash is saved under `/tmp/fuzzing/artifacts` and can be further inspected.
-### Defining a Java fuzz test
+### Java fuzzing
+
+You can write `java_fuzz_test`s through the [Jazzer][jazzer-doc] fuzzing engine. You will need to enable it in your WORKSPACE `rules_fuzzing_dependencies` call:
+
+```python
+load("@rules_fuzzing//fuzzing:repositories.bzl", "rules_fuzzing_dependencies")
+
+rules_fuzzing_dependencies(jazzer = True)
+
+load("@rules_fuzzing//fuzzing:init.bzl", "rules_fuzzing_init")
+
+rules_fuzzing_init()
+
+load("@jazzer//:repositories.bzl", "jazzer_dependencies")
+
+jazzer_dependencies()
+
+load("@jazzer//:init.bzl", "jazzer_init")
+
+jazzer_init()
+```
+
+To use Jazzer, it is convenient to also define a `.bazelrc` configuration, similar to the C++ libFuzzer one above:
+
+```
+# Force the use of Clang for all builds (Jazzer requires at least Clang 9).
+build --action_env=CC=clang
+build --action_env=CXX=clang++
+
+# Define --config=jazzer for Jazzer without sanitizer (Java only).
+build:jazzer --@rules_fuzzing//fuzzing:java_engine=@rules_fuzzing//fuzzing/engines:jazzer
+build:jazzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=jazzer
+build:jazzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=none
+
+# Define --config=asan-jazzer for Jazzer + ASAN.
+build:asan-jazzer --@rules_fuzzing//fuzzing:java_engine=@rules_fuzzing//fuzzing/engines:jazzer
+build:asan-jazzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=jazzer
+build:asan-jazzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
+```
A Java fuzz test is specified using a [`java_fuzz_test` rule](/docs/java-fuzzing-rules.md#java_fuzz_test). In the most basic form, a Java fuzz test consists of a single `.java` file with a class that defines a function `public static fuzzerTestOneInput(byte[] input)`.
-The Java equivalent of the C++ fuzz test above would look as follows:
+Create the `src/com/example/JavaFuzzTest.java` file in your workspace root, as follows:
```java
package com.example;
@@ -172,20 +200,20 @@
}
```
-The corresponding build target looks very much like a regular `java_binary`:
+You should now define the corresponding target in the `BUILD` file, which looks very much like a regular `java_binary`:
```python
load("@rules_fuzzing//fuzzing:java_defs.bzl", "java_fuzz_test")
java_fuzz_test(
name = "JavaFuzzTest",
- srcs = ["JavaFuzzTest.java"],
+ srcs = ["src/com/example/JavaFuzzTest.java"],
# target_class is not needed if using the Maven directory layout.
- target_class = "com.example.JavaFuzzTest",
+ # target_class = "com.example.JavaFuzzTest",
)
```
-As with the C++ fuzz tests, you can start the fuzzer ([Jazzer][jazzer-doc]) via
+You can now start the fuzzer using the Jazzer engine by running:
```sh
$ bazel run --config=jazzer //:JavaFuzzTest_run
diff --git a/docs/guide.md b/docs/guide.md
index ae9d189..f352827 100644
--- a/docs/guide.md
+++ b/docs/guide.md
@@ -161,21 +161,50 @@
//examples:re2_fuzz_test
```
-This command is clearly too verbose to be used manually, so we recommend combining these options as a `--config` setting in your project's [`.bazelrc` file][bazelrc-docs]. For the example above, we can define an `asan-libfuzzer` config setting as follows:
-
-```
-build:asan-libfuzzer --//fuzzing:cc_engine=//fuzzing/engines:libfuzzer
-build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=libfuzzer
-build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
-```
-
-To run your fuzz test, now you can simply invoke:
+This command is clearly too verbose to be used manually, so we recommend combining these options as a `--config` setting in your project's [`.bazelrc` file][bazelrc-docs]. For example, the command above can be replaced with:
```sh
$ bazel test --config=asan-libfuzzer //examples:re2_fuzz_test
```
-You can add to your `.bazelrc` file as many configurations as you need. Feel free to use the [`.bazelrc` file of this repository](/.bazelrc) as a starting point.
+For convenience, we define below the most common configurations that you can pick and choose for your own `.bazelrc` file:
+
+```
+# --config=asan-libfuzzer
+build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine=@rules_fuzzing//fuzzing/engines:libfuzzer
+build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=libfuzzer
+build:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
+
+# --config=msan-libfuzzer
+build:msan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine=@rules_fuzzing//fuzzing/engines:libfuzzer
+build:msan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=libfuzzer
+build:msan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=msan
+
+# --config=asan-honggfuzz
+build:asan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine=@rules_fuzzing//fuzzing/engines:honggfuzz
+build:asan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine_instrumentation=honggfuzz
+build:asan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
+
+# --config=msan-honggfuzz
+build:msan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine=@rules_fuzzing//fuzzing/engines:honggfuzz
+build:msan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine_instrumentation=honggfuzz
+build:msan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine_sanitizer=msan
+
+# --config=asan-replay
+build:asan-replay --@rules_fuzzing//fuzzing:cc_engine=@rules_fuzzing//fuzzing/engines:replay
+build:asan-replay --@rules_fuzzing//fuzzing:cc_engine_instrumentation=none
+build:asan-replay --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
+
+# --config=jazzer (Jazzer without sanitizer - Java only)
+build:jazzer --@rules_fuzzing//fuzzing:java_engine=@rules_fuzzing//fuzzing/engines:jazzer
+build:jazzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=jazzer
+build:jazzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=none
+
+# --config=asan-jazzer
+build:asan-jazzer --@rules_fuzzing//fuzzing:java_engine=@rules_fuzzing//fuzzing/engines:jazzer
+build:asan-jazzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=jazzer
+build:asan-jazzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
+```
## Advanced topics