FUZZING
The COCONUT SVSM includes several fuzzing harnesses to find bugs in security-critical interfaces. These do not currently provide coverage of all interesting interfaces, so contributions are welcome.
At the moment, fuzzing is done through cargo-fuzz. You may find a complete tutorial for this tool on the rust-fuzz website.
Requirements
- Rust nightly toolchain (
rustup toolchain install nightly
) - cargo
- cargo-fuzz (
cargo install cargo-fuzz
) - LLVM C toolchain (
clang
andlld
)
Running a harness
To get a list of harnesses, simply run the list
subcommand:
cargo fuzz list
To build a harness you may use the build
subcommand. You may also use
the run
subcommand, as detailed a few lines below.
Since cargo-fuzz
relies on clang's libFuzzer,
and there are extra compilation flags that need to be set, one must
specify the clang linker, as well as use the nightly Rust toolchain.
Additionally, you might need to strip dead code to avoid build errors.
The following will build all harnesses:
RUSTFLAGS="-Clinker=clang -Clink-arg=-fuse-ld=lld" cargo +nightly fuzz build --strip-dead-code
As mentioned before, you may run a specific harness, building it if
needed, by using the run
subcommand and specifying its name. The
following will run the fw_meta
fuzzer:
RUSTFLAGS="-Clinker=clang -Clink-arg=-fuse-ld=lld" cargo +nightly fuzz run fw_meta --strip-dead-code
The generated test cases, as well as any found crashes, will be placed
under the fuzz/
subdirectory.
Developing a harness
You may add a new harness via the add
subcommand:
cargo fuzz add my_harness
After that, you may run your harness normally:
RUSTFLAGS="-Clinker=clang -Clink-arg=-fuse-ld=lld" cargo +nightly fuzz run my_harness --strip-dead-code
The main file with a basic template will be placed under
fuzz/fuzz_targets/my_harness.rs
. The main code of your harness should
be placed inside the fuzz_target!()
macro. For more information refer
to the libfuzzer-sys
documentation.
When a fuzzer is built, the fuzzing
cfg item is defined. This might be
useful to conditionally compile code, although it is advised that you
do not rely on this feature too often.
For example, the following code disables the SVSM allocator during fuzzing and tests:
#[cfg_attr(not(any(test, doctest, fuzzing)), global_allocator)]
pub static mut ALLOCATOR: SvsmAllocator = SvsmAllocator::new();