Tutorial

For this tutorial, we are going to fuzz the URL parser rust-url.

Clone

Clone the repository and navigate inside:

git clone https://github.com/servo/rust-url
cd rust-url

Dependencies

Modify Cargo.toml and add the following lines to the [dependencies] section:

afl = "0.1"
afl-plugin = "0.1"

The afl-plugin crate includes a compiler plugin that will be used to instrument the rust-url crate. The afl crate will be used to setup the necessary runtime afl expects during afl-fuzz. Also, it has a few other utilities.

Instrumentation

Open up src/lib.rs and add these two lines before all other non-documentation/non-comment lines:

#![feature(plugin)]
#![plugin(afl_plugin)]

The first line indicates to the compiler that we are opting-in to an unstable Rust feature: compiler plugins. The second line specifies which compiler plugin we want to use. This particular compiler plugin will add the AFL instrumentation to the rust-url crate.

Driver

AFL requires an executable that will read from stdin. Create a new file src/main.rs and add the following contents:

#![feature(plugin)]
#![plugin(afl_plugin)]

extern crate afl;
extern crate url;

fn main() {
    afl::handle_string(|s| {
        let _ = url::Url::parse(&s);
    })
}

Input

AFL needs an input directory with test cases.

Make a new directory in and add a test:

mkdir in
echo "https://rust-lang.org" > in/basic

Build

You'll need to enter the Docker environment to get the binary to compile correctly:

docker run -v $(pwd):/source -it corey/afl.rs sh

Run cargo build to compile it. It will create an executable at target/debug/url.

Fuzz

afl-fuzz -i in -o out target/debug/url

Exiting

You can exit afl-fuzz by pressing ctrl-c and you can exit the Docker environment by running the exit command.