A fast Rust-based safe and thead-friendly grammar-based fuzz generator

Related tags

Testing fzero_fuzzer
Overview

Intro

fzero is a grammar-based fuzzer that generates a Rust application inspired by the paper "Building Fast Fuzzers" by Rahul Gopinath and Andreas Zeller. https://arxiv.org/pdf/1911.07707.pdf

You can find the F1 fuzzer here:

https://github.com/vrthra/F1

Usage

Currently this only generates an application that does benchmarking, but with some quick hacks you could easily get the input out and feed it to an application.

Example usage

D:\dev\fzero_fuzz>cargo run --release html.json test.rs test.exe 8
    Finished release [optimized] target(s) in 0.02s
     Running `target\release\fzero.exe html.json test.rs test.exe 8`
Loaded grammar json
Converted grammar to binary format
Optimized grammar
Generated Rust source file
Created Rust binary!

D:\dev\fzero_fuzz>test.exe
MiB/sec:    1773.3719
MiB/sec:    1763.8357
MiB/sec:    1756.8917
MiB/sec:    1757.1934
MiB/sec:    1758.9417
MiB/sec:    1758.9122
MiB/sec:    1758.7352

Concept

This program takes in an input grammar specified by a JSON file. This JSON grammar representation is converted to a binary-style grammar that is intended for interpretation and optimization. A Rust application (source file) is produced by the shape of the input grammar. This then is compiled using rustc to an application for the local machine.

This doesn't have any constraints on the random number generation as it uses an infinite supply of random numbers. There is no limitation on the output size and the buffer will dynamically grow as the input is created.

Benchmarks

All tests on a single core of a Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz with a turbo clock rate of 4.3 GHz

All numbers in MiB/second.

Benchmark fzero fuzzer F1 fuzzer Speedup
html.json depth=4 5330 1295 4.11x
html.json depth=8 1760 348 5.05x
html.json depth=16 338 195 1.73x
html.json depth=32 218 175 1.25x
html.json depth=64 201 175 1.14x
json.json depth=4 97 97 1.00x
json.json depth=8 79 93 0.84x
json.json depth=16 83 89 0.93x
json.json depth=32 85 88 0.97x
json.json depth=64 85 90 0.94x

Unsafe code

This project uses a small amount of unsafe code to provide the same semantics of extend_from_slice but in a much faster way (over 4x faster). Not quite sure why it's much faster, but if you are uncomfortable with unsafe code, feel free to set SAFE_ONLY to true at the top of src/lib.rs. This will restrict this fuzzer to only generate safe code. I don't think this is necessary but who knows :)

Performance

The performance of this tool is separated into multiple categories. One is the code generation side, how long it takes for the JSON to be compiled into a Rust application. The other is the code execution speeds, which is how fast the produced application can generate inputs.

Code Generation

Code generation vastly outperforms the "Building Fast Fuzzers" paper. For example when generating the code based on the html.json grammar, the F1 fuzzer took over 25 minutes to produce the code. This fuzzer is capable of producing a Rust application in under 10 seconds.

Code execution

This project is on some performance metrics about 20-30% slower than the F1 fuzzer, but these scenarios are rare. However, in most situations we've been about to out-perform F1 by about 30-50%, and in extreme cases (html.json depth=8) we've observed over a 4x speedup.

Differences from the F1 fuzzer

The F1 fuzzer mentions a technique that will resolve to the nearest terminal tokens when stack depth is exceeded. We haven't implemented this technique but I don't think it's a huge impact on the generated inputs. This is something I will look into in the future.

Due to not using globals this can easily be scaled out to multiple threads as all random state and input generation are done in a structure.

There is no use of assembly in this project, and thus it can produce highly-performant fuzzers for any architecture or environment that Rust can compile against (pretty much identical to LLVM's target list).

You might also like...
Test for rust-based plugin system for swc

rust-dylib-test Steps Run cargo build in plugin_a Ensure that plugin_a dynamically links to runtime/common by otool -L plugin_a/target/debug/libplugin

Fixture-based test framework for Rust

Fixture-based test framework for Rust Introduction rstest uses procedural macros to help you on writing fixtures and table-based tests. To use it, add

Rewind is a snapshot-based coverage-guided fuzzer targeting Windows kernel components.
Rewind is a snapshot-based coverage-guided fuzzer targeting Windows kernel components.

Rewind is a snapshot-based coverage-guided fuzzer targeting Windows kernel components.

Black-box fuzzer that fuzzes APIs based on OpenAPI specification. Find bugs for free!
Black-box fuzzer that fuzzes APIs based on OpenAPI specification. Find bugs for free!

OpenAPI fuzzer Black-box fuzzer that fuzzes APIs based on OpenAPI specification. All you need to do is to supply URL of the API and its specification.

Playwright is a rust library to automate Chromium, Firefox and WebKit built on top of Node.js library.

🎭 Playwright for Rust Playwright is a rust library to automate Chromium, Firefox and WebKit built on top of Node.js library. Installation [dependenci

Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...
Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...

LibAFL, the fuzzer library. Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust. LibAFL is written and main

Breaking your Rust code for fun and profit

Breaking your Rust code for fun & profit this is an architecture-preview, not all components are there This is a mutation testing framework for Rust c

A series of test cases to evaluate async Rust on the nrf52840 in terms of power usage and ergonomics.

A series of test cases to evaluate async Rust on the nrf52840 in terms of power usage and ergonomics. This is an experiment that uses unstable features only available on nightly rust.

TestDrive automatically scrapes input/output data from BOJ(Baekjoon Online Judge) and runs tests for your executable binary file!

🚖 TestDrive What does it do? TestDrive automatically scrapes input/output data from BOJ(Baekjoon Online Judge) and runs tests for your executable bin

Owner
null
A fuzzer setup to fuzz libc functions.

libc-fuzzer This does what it sounds like! It attempts to, as automatically as possible, generate and run fuzzers for up to the entire set of libc (in

null 9 Nov 30, 2022
An unofficial client library for the fuzz-introspector API.

fuzz-introspector-client An unofficial client library for the fuzz-introspector API. Quickstart Add package as a dependency; cargo add fuzz-introspect

Nathaniel Brough 4 Nov 25, 2023
Easy-to-use grammar-based black-box fuzzer. Has found dozens of bugs in important targets like Clang, Deno, and rustc.

tree-crasher tree-crasher is an easy-to-use grammar-based black-box fuzzer. It parses a number of input files using tree-sitter grammars, and produces

Langston Barrett 5 Mar 28, 2023
a grammar based feedback fuzzer

Nautilus NOTE: THIS IS AN OUTDATE REPOSITORY, THE CURRENT RELEASE IS AVAILABLE HERE. THIS REPO ONLY SERVES AS A REFERENCE FOR THE PAPER Nautilus is a

Chair for Sys­tems Se­cu­ri­ty 157 Oct 26, 2022
Rnp - A simple cloud-friendly tool for testing network reachability.

Rnp - A simple cloud-friendly tool for testing network reachability. Release Status Crates.io Github release Nuget packages NOTE: This project is in e

Riff 50 Dec 13, 2022
A heckin small test generator

heckcheck A heckin small test generator API Docs | Releases | Contributing Installation $ cargo add heckcheck Safety This crate uses #![deny(unsafe_co

Yoshua Wuyts 18 Mar 20, 2022
A minimalist property-based testing library based on the arbitrary crate.

A minimalist property-based testing library based on the arbitrary crate.

Aleksey Kladov 61 Dec 21, 2022
Travis CI and AppVeyor template to test your Rust crate on 5 architectures and publish binary releases of it for Linux, macOS and Windows

trust Travis CI and AppVeyor template to test your Rust crate on 5 architectures and publish binary releases of it for Linux, macOS and Windows Featur

Jorge Aparicio 1.2k Dec 30, 2022
ArchTest is a rule based architecture testing tool for rust

ArchTest is a rule based architecture testing tool. It applies static analyses on the specified rust project to extract use relationships.

Tom Dymel 7 Sep 26, 2021
Automated property based testing for Rust (with shrinking).

quickcheck QuickCheck is a way to do property based testing using randomly generated input. This crate comes with the ability to randomly generate and

Andrew Gallant 2k Jan 2, 2023