aboutsummaryrefslogtreecommitdiff
path: root/docs/getting-started/new-project-guide/rust_lang.md
blob: c28dd7618a1a2c43d780fd208e21911f33b7c4d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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
```