From 6c21d442e11c11d31909b702753f0c76e9d5667f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 12 Jun 2020 14:13:05 -0500 Subject: Add Rust-specific setup instructions (#3978) This is a follow-up to [this comment][1] which provides some intro docs for how to get started quickly with a Rust project, explaining `cargo fuzz` and some basic setup steps. [1]: https://github.com/google/oss-fuzz/issues/3383#issuecomment-642137449 --- .../getting-started/new-project-guide/rust_lang.md | 102 +++++++++++++++++++++ docs/getting-started/new_project_guide.md | 24 ++--- 2 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 docs/getting-started/new-project-guide/rust_lang.md diff --git a/docs/getting-started/new-project-guide/rust_lang.md b/docs/getting-started/new-project-guide/rust_lang.md new file mode 100644 index 00000000..51229903 --- /dev/null +++ b/docs/getting-started/new-project-guide/rust_lang.md @@ -0,0 +1,102 @@ +--- +layout: default +title: Integrating a Rust project +parent: Setting up a new project +grand_parent: Getting started +nav_order: 2 +permalink: /getting-started/new-project-guide/rust-lang/ +--- + +# Integrating a Rust project +{: .no_toc} + +- TOC +{:toc} +--- + +The process of integrating a project written in Rust with OSS-Fuzz is very +similar to the general [Setting up a new project]({{ site.baseurl +}}/getting-started/new-project-guide/) process. The key specifics of integrating +a Rust project are outlined below. + +## cargo-fuzz support + +Rust integration with OSS-Fuzz is expected to use [`cargo +fuzz`](https://github.com/rust-fuzz/cargo-fuzz) to build fuzzers. The `cargo +fuzz` tool will build code with required compiler flags as well as link to the +correct libFuzzer on OSS-Fuzz itself. Note that using `cargo fuzz` also makes it +quite easy to run the fuzzers locally yourself if you get a failing test case! + +## Project files + +First you'll want to follow the [setup instructions for `cargo fuzz` +itself](https://rust-fuzz.github.io/book/). Afterwards your project should have: + +* A top-level `fuzz` directory +* A `fuzz/Cargo.toml` manifest which pulls in necessary dependencies to fuzz +* Some `fuzz/fuzz_targets/*.rs` files which are the fuzz targets that will be + compiled and run on OSS-Fuzz. + +Note that you can customize this layout as well, but you'll need to edit some +the scripts below to integrate into OSS-Fuzz. + +### project.yaml + +The `language` attribute must be specified. + +```yaml +language: rust +``` + +The only supported fuzzing engine and sanitizer are `libfuzzer` and `address`, +respectively. +[Example](https://github.com/google/oss-fuzz/blob/12ef3654b3e9adfd20b5a6afdde54819ba71493d/projects/serde_json/project.yaml#L3-L6) + +```yaml +sanitizers: + - address +fuzzing_engines: + - libfuzzer +``` + +### Dockerfile + +The OSS-Fuzz builder image has the latest nightly release of Rust as well as +`cargo fuzz` pre-installed and in `PATH`. In the `Dockerfile` for your project +all you'll need to do is fetch the latest copy of your code and install any +system dependencies necessary to build your project. +[Example](https://github.com/google/oss-fuzz/blob/12ef3654b3e9adfd20b5a6afdde54819ba71493d/projects/serde_json/Dockerfile#L18-L20) + +```dockerfile +RUN git clone --depth 1 https://github.com/serde-rs/json json +``` + +### build.sh + +Here it's expected that you'll build the fuzz targets for your project and then +copy the final binaries into the output directory. +[Example](https://github.com/google/oss-fuzz/blob/12ef3654b3e9adfd20b5a6afdde54819ba71493d/projects/serde_json/build.sh#L20): + +```sh +cd $SRC/json +cargo fuzz build -O +cp fuzz/target/x86_64-unknown-linux-gnu/release/from_slice $OUT/ +``` + +Note that you likely want to pass the `-O` flag to `cargo fuzz build` which +builds fuzzers in release mode. You may also want to pass the +`--debug-assertions` flag to enable more checks while fuzzing. In this example +the `from_slice` binary is the fuzz target. + +With some bash-fu you can also automatically copy over all fuzz targets into +the output directory so when you add a fuzz target to your project it's +automatically integrated into OSS-Fuzz: + +```sh +FUZZ_TARGET_OUTPUT_DIR=target/x86_64-unknown-linux-gnu/release +for f in fuzz/fuzz_targets/*.rs +do + FUZZ_TARGET_NAME=$(basename ${f%.*}) + cp $FUZZ_TARGET_OUTPUT_DIR/$FUZZ_TARGET_NAME $OUT/ +done +``` diff --git a/docs/getting-started/new_project_guide.md b/docs/getting-started/new_project_guide.md index 7ea668fd..bcfce14f 100644 --- a/docs/getting-started/new_project_guide.md +++ b/docs/getting-started/new_project_guide.md @@ -88,10 +88,12 @@ You project's homepage. ### language -Programming language the project is written in. Most often this would be `c` or -`c++`. Other values for this attribute are documented in language specific -documentation pages (e.g. -[Integrating a Go project]({{ site.baseurl }}//getting-started/new-project-guide/go-lang/)). +Programming language the project is written in. Values you can specify include: + +* `c` +* `c++` +* [`go`]({{ site.baseurl }}//getting-started/new-project-guide/go-lang/) +* [`rust`]({{ site.baseurl }}//getting-started/new-project-guide/rust-lang/) ### primary_contact, auto_ccs {#primary} The primary contact and list of other contacts to be CCed. Each person listed gets access to ClusterFuzz, including crash reports and fuzzer statistics, and are auto-cced on new bugs filed in the OSS-Fuzz @@ -118,7 +120,7 @@ runtime dependencies are listed in the OSS-Fuzz Then, you can opt in by adding "memory" to your list of sanitizers. If your project does not build with a particular sanitizer configuration and you need some time to fix -it, you can use `sanitizers` to override the defaults temporarily. For example, to disable the +it, you can use `sanitizers` to override the defaults temporarily. For example, to disable the UndefinedBehaviourSanitizer build, just specify all supported sanitizers except "undefined". If you want to test a particular sanitizer to see what crashes it generates without filing @@ -147,7 +149,7 @@ architectures: - x86_64 - i386 ``` - + By fuzzing on i386 you might find bugs that: * Only occur in architecture-specific source code (e.g. code that contains i386 assembly). * Exist in architecture-independent source code and which only affects i386 users. @@ -197,7 +199,7 @@ In general, this script should do the following: - Build the project using your build system with the correct compiler. - Provide compiler flags as [environment variables](#Requirements). - Build your [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target) and link your project's build with libFuzzer. - + Resulting binaries should be placed in `$OUT`. Here's an example from Expat ([source](https://github.com/google/oss-fuzz/blob/master/projects/expat/build.sh)): @@ -280,7 +282,7 @@ your [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target) run in, ## Testing locally -You can build your docker image and fuzz targets locally, so you can test them before you push them to the OSS-Fuzz repository. +You can build your docker image and fuzz targets locally, so you can test them before you push them to the OSS-Fuzz repository. 1. Run the same helper script you used to create your directory structure, this time using it to build your docker image and [fuzz targets]({{ site.baseurl }}/reference/glossary/#fuzz-target): @@ -296,8 +298,8 @@ You can build your docker image and fuzz targets locally, so you can test them b **Note:** You *must* run your fuzz target binaries inside the base-runner docker container to make sure that they work properly. -2. Find failures to fix by running the `check_build` command: - +2. Find failures to fix by running the `check_build` command: + ```bash $ python infra/helper.py check_build $PROJECT_NAME ``` @@ -311,7 +313,7 @@ You can build your docker image and fuzz targets locally, so you can test them b 4. We recommend taking a look at your code coverage as a sanity check to make sure that your fuzz targets get to the code you expect. Please refer to [code coverage]({{ site.baseurl }}/advanced-topics/code-coverage/). -**Note:** Currently, we only support AddressSanitizer (address) and UndefinedBehaviorSanitizer (undefined) +**Note:** Currently, we only support AddressSanitizer (address) and UndefinedBehaviorSanitizer (undefined) configurations. MemorySanitizer is recommended, but needs to be enabled manually once you verify that all system dependencies are [instrumented](https://github.com/google/oss-fuzz/blob/master/infra/base-images/msan-builder/Dockerfile#L20). -- cgit v1.2.3