Skip to content

Commit

Permalink
[fuzzing] per-target binary for integration with google oss-fuzz
Browse files Browse the repository at this point in the history
Google OSS-Fuzz project (google allow open source projects to be fuzzed by them) requires
that each fuzzer be its own binary.
To avoid having to maintain additional files,
and having to have to add a new binary file everytime one adds a fuzzer,
this intelligently creates a binary based on an env variable.

How does it work?

1. a build file retrieves an environment variable telling it what fuzzer to create
2. it generates a file in `OUT_DIR` that contains the name of the fuzzer
3. that file is included in the binary code, and used to figure out what's the target

Check the README for more information.

Closes: diem#2721
Approved by: sunshowers
  • Loading branch information
mimoo authored and bors-libra committed Feb 27, 2020
1 parent 460001f commit 82993d8
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 0 deletions.
26 changes: 26 additions & 0 deletions testsuite/libra-fuzzer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,29 @@ cargo run --bin investigate -- -i artifacts/compiled_module/crash-5d7f403f

This is helpful to investigate and debug a binary in order to find the root cause
of a bug.

### Google OSS-Fuzz Integration

To integrate our fuzzers with [Google OSS-Fuzz](https://github.com/google/oss-fuzz) project,
we need to have one binary per fuzzer.
For this, build.rs can create a fuzzer binary based on an environement variable.
Use it as such:

```sh
FUZZ_TARGET="consensus_proposal" cargo build --manifest-path fuzz/Cargo.toml --bin fuzzer_builder
```

Note that you might want to add more flags [[1]](https://github.com/rust-fuzz/cargo-fuzz/blob/2243de096b15b79b719ce7489f014d7d8ce197ee/src/project.rs#L153)[[2]](https://github.com/rust-fuzz/cargo-fuzz/blob/2243de096b15b79b719ce7489f014d7d8ce197ee/src/project.rs#L174).

For example for MacOS:

```sh
cd fuzz
ASAN_OPTIONS=detect_odr_violation=0 RUSTC_BOOTSTRAP=1 RUSTFLAGS="--cfg fuzzing -Cpasses=sancov -Cllvm-args=-sanitizer-coverage-level=4 -Cllvm-args=-sanitizer-coverage-trace-compares -Cllvm-args=-sanitizer-coverage-inline-8bit-counters -Cllvm-args=-sanitizer-coverage-trace-geps -Cllvm-args=-sanitizer-coverage-prune-blocks=0 -Cllvm-args=-sanitizer-coverage-pc-table -Clink-dead-code -Zsanitizer=address -Cdebug-assertions" FUZZ_TARGET="vm_value" cargo build --verbose --target x86_64-apple-darwin --bin fuzzer_builder
```

### Troubleshooting

#### linking with CC failed

Are you on MacOS? Have you checked that Xcode is up-to-date?
6 changes: 6 additions & 0 deletions testsuite/libra-fuzzer/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ once_cell = "1.3.1"
name = "fuzz_runner"
path = "fuzz_targets/fuzz_runner.rs"
test = false

# used for integration with Google OSS-Fuzz (see README)
[[bin]]
name = "fuzzer_builder"
path = "google-oss-fuzz/fuzzer_builder.rs"
test = false
29 changes: 29 additions & 0 deletions testsuite/libra-fuzzer/fuzz/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use std::{env, fs::File, io::prelude::*, path::PathBuf};

fn main() {
// needed to build different binaries based on env var
println!("cargo:rerun-if-env-changed=SINGLE_FUZZ_TARGET");
println!("cargo:rerun-if-env-changed=RUSTFLAGS");
let fuzz_target = match env::var("SINGLE_FUZZ_TARGET") {
Ok(x) => x,
// default value for build to work
Err(_) => "vm_value".to_string(),
};

// fuzzer file to write
let fuzzer_content = format!(
"const FUZZ_TARGET: &str = \"{fuzz_target}\";",
fuzz_target = fuzz_target,
);

// path of file to create (OUT_DIR/fuzzer.rs)
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let out_path = out_path.join("fuzzer.rs");

// write to file
let mut file = File::create(out_path).unwrap();
file.write_all(fuzzer_content.as_bytes()).unwrap();
}
15 changes: 15 additions & 0 deletions testsuite/libra-fuzzer/fuzz/google-oss-fuzz/fuzzer_builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

#![no_main]

use libfuzzer_sys::fuzz_target;
use libra_fuzzer::FuzzTarget;

// contains FUZZ_TARGET
include!(concat!(env!("OUT_DIR"), "/fuzzer.rs"));

fuzz_target!(|data: &[u8]| {
let fuzzer = FuzzTarget::by_name(FUZZ_TARGET).unwrap();
fuzzer.fuzz(data);
});

0 comments on commit 82993d8

Please sign in to comment.