{"id":19933739,"url":"https://github.com/bazel-contrib/rules_fuzzing","last_synced_at":"2025-03-01T11:44:07.984Z","repository":{"id":36995412,"uuid":"268120512","full_name":"bazel-contrib/rules_fuzzing","owner":"bazel-contrib","description":"Bazel Starlark extensions for defining fuzz tests in Bazel projects","archived":false,"fork":false,"pushed_at":"2025-02-18T17:49:48.000Z","size":350,"stargazers_count":88,"open_issues_count":33,"forks_count":22,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-02-24T17:14:13.417Z","etag":null,"topics":["bazel","fuzzing"],"latest_commit_sha":null,"homepage":"","language":"Starlark","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bazel-contrib.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":"docs/code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"bazel-rules-authors-sig"}},"created_at":"2020-05-30T16:43:44.000Z","updated_at":"2025-02-18T17:47:58.000Z","dependencies_parsed_at":"2024-03-10T13:27:30.386Z","dependency_job_id":"93d37a39-ac01-4282-8b46-2c02be6471bd","html_url":"https://github.com/bazel-contrib/rules_fuzzing","commit_stats":null,"previous_names":["bazel-contrib/rules_fuzzing"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_fuzzing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_fuzzing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_fuzzing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bazel-contrib%2Frules_fuzzing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bazel-contrib","download_url":"https://codeload.github.com/bazel-contrib/rules_fuzzing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241361398,"owners_count":19950379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bazel","fuzzing"],"created_at":"2024-11-12T23:14:43.496Z","updated_at":"2025-03-01T11:44:07.954Z","avatar_url":"https://github.com/bazel-contrib.png","language":"Starlark","funding_links":["https://opencollective.com/bazel-rules-authors-sig"],"categories":["Starlark"],"sub_categories":[],"readme":"# Bazel Rules for Fuzz Tests\n\nThis repository contains [Bazel](https://bazel.build/) [Starlark extensions](https://docs.bazel.build/versions/master/skylark/concepts.html) for defining fuzz tests in Bazel projects.\n\n[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.\n\nThe rule library currently provides support for C++ and Java fuzz tests. Support for additional languages may be added in the future.\n\n## Features at a glance\n\n* C++ and Java fuzzing, with several fuzzing engines supported out of the box:\n  * C++: [libFuzzer][libfuzzer-doc] and [Honggfuzz][honggfuzz-doc]\n  * Java: [Jazzer][jazzer-doc]\n* Multiple sanitizer configurations:\n  * [Address Sanitizer][asan-doc]\n  * [Memory Sanitizer][msan-doc]\n  * [Undefined Behavior Sanitizer][ubsan-doc]\n* Corpora and dictionaries.\n* Simple \"bazel run/test\" commands to build and run the fuzz tests.\n  * No need to understand the details of each fuzzing engine.\n  * No need to explicitly manage its corpus or dictionary.\n* Out-of-the-box [OSS-Fuzz](https://github.com/google/oss-fuzz) support that [substantially simplifies][bazel-oss-fuzz] the project integration effort.\n* Regression testing support, useful in continuous integration.\n* Customization options:\n  * Defining additional fuzzing engines.\n  * Customizing the behavior of the fuzz test rule.\n\nContributions are welcome! Please read the [contribution guidelines](/docs/contributing.md).\n\n## Getting started\n\nThis section will walk you through the steps to set up fuzzing in your Bazel project and write your first fuzz test. We assume Bazel [is installed](https://docs.bazel.build/versions/main/install.html) on your machine.\n\n### Prerequisites\n\nThe fuzzing rules have been tested on Bazel 4.0.0 or later. Check your Bazel version by running `bazel --version`.\n\nC++ fuzzing requires a Clang compiler. The libFuzzer engine requires at least Clang 6.0. In addition, the Honggfuzz engine requires the `libunwind-dev` and `libblocksruntime-dev` packages:\n\n```sh\n$ sudo apt-get install clang libunwind-dev libblocksruntime-dev\n```\n\nJava fuzzing requires Clang and the LLD linker:\n\n```sh\n$ sudo apt-get install clang lld\n```\n\n### Configuring the WORKSPACE\n\nAdd the following to your `WORKSPACE` file:\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nhttp_archive(\n    name = \"rules_fuzzing\",\n    sha256 = \"23bb074064c6f488d12044934ab1b0631e8e6898d5cf2f6bde087adb01111573\",\n    strip_prefix = \"rules_fuzzing-0.3.1\",\n    urls = [\"https://github.com/bazelbuild/rules_fuzzing/archive/v0.3.1.zip\"],\n)\n\nload(\"@rules_fuzzing//fuzzing:repositories.bzl\", \"rules_fuzzing_dependencies\")\n\nrules_fuzzing_dependencies()\n\nload(\"@rules_fuzzing//fuzzing:init.bzl\", \"rules_fuzzing_init\")\n\nrules_fuzzing_init()\n\nload(\"@fuzzing_py_deps//:requirements.bzl\", \"install_deps\")\n\ninstall_deps()\n```\n\n\u003e 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).\n\n\n### Configuring the .bazelrc file\n\nIt is best to create command shorthands for the fuzzing configurations you will use during development. In our case, let's create a configuration for libFuzzer + Address Sanitizer. In your `.bazelrc` file, add the following:\n\n```\n# Force the use of Clang for C++ builds.\nbuild --action_env=CC=clang\nbuild --action_env=CXX=clang++\n\n# Define the --config=asan-libfuzzer configuration.\nbuild:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine=@rules_fuzzing//fuzzing/engines:libfuzzer\nbuild:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=libfuzzer\nbuild:asan-libfuzzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan\n```\n\nExamples for other combinations of fuzzing engine and sanitizer can be found in the [User Guide](/docs/guide.md#configuring-the-bazelrc-file).\n\n### Defining a C++ fuzz test\n\nA C++ fuzz test is specified using a [`cc_fuzz_test` rule](/docs/cc-fuzzing-rules.md#cc_fuzz_test). In the most basic form, a fuzz test requires a source file that implements the fuzz driver entry point.\n\nLet's create a fuzz test that exhibits a buffer overflow. Create a `fuzz_test.cc` file in your workspace root, as follows:\n\n```cpp\n#include \u003ccstddef\u003e\n#include \u003ccstdint\u003e\n#include \u003ccstdio\u003e\n\nvoid TriggerBufferOverflow(const uint8_t *data, size_t size) {\n  if (size \u003e= 3 \u0026\u0026 data[0] == 'F' \u0026\u0026 data[1] == 'U' \u0026\u0026 data[2] == 'Z' \u0026\u0026\n      data[size] == 'Z') {\n    fprintf(stderr, \"BUFFER OVERFLOW!\\n\");\n  }\n}\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {\n  TriggerBufferOverflow(data, size);\n  return 0;\n}\n```\n\nLet's now define its build target in the `BUILD` file:\n\n```python\nload(\"@rules_fuzzing//fuzzing:cc_defs.bzl\", \"cc_fuzz_test\")\n\ncc_fuzz_test(\n    name = \"fuzz_test\",\n    srcs = [\"fuzz_test.cc\"],\n)\n```\n\n### Running the fuzz test\n\nYou can now build and run the fuzz test. For each fuzz test `\u003cname\u003e` defined, the framework automatically generates a launcher tool `\u003cname\u003e_run` that will build and run the fuzz test according to the configuration specified:\n\n```sh\n$ bazel run --config=asan-libfuzzer //:fuzz_test_run\n```\n\nOur libFuzzer test will start running and immediately discover the buffer overflow issue in the code:\n\n```\nINFO: Seed: 2957541205\nINFO: Loaded 1 modules   (8 inline 8-bit counters): 8 [0x5aab10, 0x5aab18),\nINFO: Loaded 1 PC tables (8 PCs): 8 [0x5aab18,0x5aab98),\nINFO:      755 files found in /tmp/fuzzing/corpus\nINFO:        0 files found in fuzz_test_corpus\nINFO: -max_len is not provided; libFuzzer will not generate inputs larger than 35982 bytes\nINFO: seed corpus: files: 755 min: 1b max: 35982b total: 252654b rss: 35Mb\n#756    INITED cov: 6 ft: 7 corp: 4/10b exec/s: 0 rss: 47Mb\n=================================================================\n==724294==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000047a74 at pc 0x0000005512d9 bp 0x7fff3049d270 sp 0x7fff3049d268\n```\n\nThe crash is saved under `/tmp/fuzzing/artifacts` and can be further inspected.\n\n### Java fuzzing\n\nYou can write `java_fuzz_test`s through the [Jazzer][jazzer-doc] fuzzing engine.\n\nTo use Jazzer, it is convenient to also define a `.bazelrc` configuration, similar to the C++ libFuzzer one above:\n\n```\n# Force the use of Clang for all builds (Jazzer requires at least Clang 9).\nbuild --action_env=CC=clang\nbuild --action_env=CXX=clang++\n\n# Define --config=jazzer for Jazzer without sanitizer (Java only).\nbuild:jazzer --@rules_fuzzing//fuzzing:java_engine=@rules_fuzzing//fuzzing/engines:jazzer\nbuild:jazzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=jazzer\nbuild:jazzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=none\n\n# Define --config=asan-jazzer for Jazzer + ASAN.\nbuild:asan-jazzer --@rules_fuzzing//fuzzing:java_engine=@rules_fuzzing//fuzzing/engines:jazzer\nbuild:asan-jazzer --@rules_fuzzing//fuzzing:cc_engine_instrumentation=jazzer\nbuild:asan-jazzer --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan\n```\n\nA 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)`.\n\nCreate the `src/com/example/JavaFuzzTest.java` file in your workspace root, as follows:\n\n```java\npackage com.example;\n\npublic class JavaFuzzTest {\n    public static void fuzzerTestOneInput(byte[] data) {\n        if (data.length \u003e= 3 \u0026\u0026 data[0] == 'F' \u0026\u0026 data[1] == 'U' \u0026\u0026\n            data[2] == 'Z' \u0026\u0026 data[data.length] == 'Z') {\n            throw new IllegalStateException(\n                \"ArrayIndexOutOfBoundException thrown above\");\n        }\n    }\n}\n```\n\nYou should now define the corresponding target in the `BUILD` file, which looks very much like a regular `java_binary`:\n\n```python\nload(\"@rules_fuzzing//fuzzing:java_defs.bzl\", \"java_fuzz_test\")\n\njava_fuzz_test(\n    name = \"JavaFuzzTest\",\n    srcs = [\"src/com/example/JavaFuzzTest.java\"],\n    # target_class is not needed if using the Maven directory layout.\n    # target_class = \"com.example.JavaFuzzTest\",\n)\n```\n\nYou can now start the fuzzer using the Jazzer engine by running:\n\n```sh\n$ bazel run --config=jazzer //:JavaFuzzTest_run\n```\n\nJazzer will quickly hit an `ArrayIndexOutOfBoundsException`:\n\n```\nINFO: Instrumented com.example.JavaFuzzTest (took 98 ms, size +96%)\nINFO: Seed: 4010526312\nINFO: Loaded 1 modules   (512 inline 8-bit counters): 512 [0x7fae23acd800, 0x7fae23acda00),\nINFO: Loaded 1 PC tables (512 PCs): 512 [0x7fae226c9800,0x7fae226cb800),\nINFO:       16 files found in /tmp/fuzzing/corpus\nINFO:        0 files found in test/JavaFuzzTest_corpus\nINFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes\nINFO: seed corpus: files: 16 min: 1b max: 19b total: 210b rss: 199Mb\n#18     INITED cov: 3 ft: 3 corp: 2/5b exec/s: 0 rss: 200Mb\n...\n#6665   REDUCE cov: 5 ft: 5 corp: 4/10b lim: 63 exec/s: 0 rss: 202Mb L: 3/3 MS: 3 ChangeBit-ChangeBit-EraseBytes-\n\n== Java Exception: java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3\n    at com.example.JavaFuzzTest.fuzzerTestOneInput(JavaFuzzTest.java:5)\n```\n\n### OSS-Fuzz integration\n\nOnce you wrote and tested the fuzz test, you should run it on continuous fuzzing infrastructure so it starts generating tests and finding new crashes in your code.\n\nThe C++ and Java fuzzing rules provide out-of-the-box support for [OSS-Fuzz](https://github.com/google/oss-fuzz), free continuous fuzzing infrastructure from Google for open source projects. Read its [Bazel project guide][bazel-oss-fuzz] for detailed instructions.\n\n## Where to go from here?\n\nCongratulations, you have built and run your first fuzz test with the Bazel rules!\n\nCheck out the [`examples/`](examples/) directory, which showcases additional features. Read the [User Guide](/docs/guide.md) for detailed usage instructions.\n\n\u003c!-- Links --\u003e\n\n[asan-doc]: https://clang.llvm.org/docs/AddressSanitizer.html\n[bazel-oss-fuzz]: https://google.github.io/oss-fuzz/getting-started/new-project-guide/bazel/\n[honggfuzz-doc]: https://github.com/google/honggfuzz\n[libfuzzer-doc]: https://llvm.org/docs/LibFuzzer.html\n[jazzer-doc]: https://github.com/CodeIntelligenceTesting/jazzer\n[msan-doc]: https://clang.llvm.org/docs/MemorySanitizer.html\n[ubsan-doc]: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbazel-contrib%2Frules_fuzzing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbazel-contrib%2Frules_fuzzing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbazel-contrib%2Frules_fuzzing/lists"}