Skip to content

Commit

Permalink
Document features (#1453)
Browse files Browse the repository at this point in the history
* Document features

* Fix doctest

* remove link

* <<<<head

* Fix doc links
  • Loading branch information
domenukk committed Aug 24, 2023
1 parent e89e8db commit f68fe95
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_and_test.yml
Expand Up @@ -91,7 +91,7 @@ jobs:

# ---- doc check ----
- name: Build Docs
run: cargo doc
run: cargo +nightly doc --all-features
- name: Test Docs
run: cargo +nightly test --doc --all-features

Expand Down
14 changes: 8 additions & 6 deletions README.md
Expand Up @@ -50,41 +50,43 @@ The LLVM tools (including clang, clang++) are needed (newer than LLVM 11.0.0 but
- Cargo-make
We use cargo-make to build the fuzzers in `fuzzers/` directory. You can install it with

```
```sh
cargo install cargo-make
```

2. Clone the LibAFL repository with

```
```sh
git clone https://github.com/AFLplusplus/LibAFL
```

3. Build the library using

```
```sh
cargo build --release
```

4. Build the API documentation with

```
```sh
cargo doc
```

5. Browse the LibAFL book (WIP!) with (requires [mdbook](https://rust-lang.github.io/mdBook/index.html))

```
```sh
cd docs && mdbook serve
```

We collect all example fuzzers in [`./fuzzers`](./fuzzers/).
Be sure to read their documentation (and source), this is *the natural way to get started!*

You can run each example fuzzer with
```

```sh
cargo make run
```

as long as the fuzzer directory has `Makefile.toml` file.

The best-tested fuzzer is [`./fuzzers/libfuzzer_libpng`](./fuzzers/libfuzzer_libpng), a multicore libfuzzer-like fuzzer using LibAFL for a libpng harness.
Expand Down
133 changes: 102 additions & 31 deletions libafl/Cargo.toml
Expand Up @@ -12,48 +12,116 @@ edition = "2021"
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]

[package.metadata.docs.rs]
features = ["document-features"]
all-features = true

[features]
default = ["std", "derive", "llmp_compression", "llmp_small_maps", "llmp_broker_timeouts", "rand_trait", "fork", "prelude", "gzip", "regex", "serdeany_autoreg", "tui_monitor"]
std = ["serde_json", "serde_json/std", "nix", "serde/std", "bincode", "wait-timeout", "uuid", "backtrace", "serial_test", "libafl_bolts/std", "typed-builder"] # print, env, launcher ... support
derive = ["libafl_derive", "libafl_bolts/derive"] # provide derive(SerdeAny) macro.
fork = ["libafl_bolts/derive"] # uses the fork() syscall to spawn children, instead of launching a new command, if supported by the OS (has no effect on Windows, no_std).
rand_trait = ["libafl_bolts/rand_trait"] # If set, libafl's rand implementations will implement `rand::Rng`
introspection = [] # Include performance statistics of the fuzzing pipeline
concolic_mutation = ["z3"] # include a simple concolic mutator based on z3

#! # Feature Flags
#! ### General Features

## Enables features that need rust's `std` lib to work, like print, env, ... support
std = ["serde_json", "serde_json/std", "nix", "serde/std", "bincode", "wait-timeout", "uuid", "backtrace", "serial_test", "libafl_bolts/std", "typed-builder"]

## Collects performance statistics of the fuzzing pipeline and displays it on `Monitor` components
introspection = []

## Will build the `pyo3` bindings
python = ["pyo3", "concat-idents", "libafl_bolts/python"]
prelude = ["libafl_bolts/prelude"] # Expose libafl::prelude for access without additional using directives
tui_monitor = ["tui", "crossterm"] # enable TuiMonitor with crossterm
prometheus_monitor = ["std", "async-std", "prometheus-client", "tide", "futures"]
cli = ["libafl_bolts/cli"] # expose libafl_bolts::cli for easy commandline parsing
qemu_cli = ["cli", "libafl_bolts/qemu_cli"] # Commandline flags for qemu-based fuzzers
frida_cli = ["cli", "libafl_bolts/frida_cli"] # Commandline flags for frida-based fuzzers
afl_exec_sec = [] # calculate exec/sec like AFL

## Expose `libafl::prelude` for access without additional using directives
prelude = ["libafl_bolts/prelude"]

## Calculate exec/sec like AFL, using 5 second time windows
afl_exec_sec = []

## Stores the backtraces of all generated `Error`s. Good for debugging, but may come with a slight performance hit.
errors_backtrace = ["libafl_bolts/errors_backtrace"]
cmin = ["z3"] # corpus minimisation
corpus_btreemap = [] # Switches from HashMap to BTreeMap for CorpusId
gzip = ["libafl_bolts/gzip"] # Enables gzip compression in certain parts of the lib
regex = ["std", "dep:regex"] # enables the NaiveTokenizer and StacktraceObserver
casr = ["libcasr", "std", "regex"] # enables deduplication based on libcasr for StacktraceObserver
tcp_manager = ["tokio", "std"] # A simple EventManager proxying everything via TCP

## Switches from `HashMap` to `BTreeMap` for `CorpusId`
corpus_btreemap = []

## Enables gzip compression in certain parts of the lib
gzip = ["libafl_bolts/gzip"]

## If set, will use the `fork()` syscall to spawn children, instead of launching a new command, if supported by the OS (has no effect on `Windows`).
fork = ["libafl_bolts/derive"]

## Collected stats to decide if observers must be serialized or not (which should reduce mem use and increase speed)
adaptive_serialization = []

# features hiding dependencies licensed under GPL
gpl = []
# features hiding dependencies licensed under AGPL
agpl = ["gpl", "nautilus"]
nautilus = ["grammartec", "std", "serde_json/std"]

# SerdeAny features
serdeany_autoreg = ["libafl_bolts/serdeany_autoreg"] # Automatically register all `#[derive(SerdeAny)]` types at startup.
#! ## Additional Components

## Enables `TcpEventManager`, a simple EventManager proxying everything via TCP. This uses `tokio`.
tcp_manager = ["tokio", "std"]

## Enables the `NaiveTokenizer` and `StacktraceObserver`
regex = ["std", "dep:regex"]

## Enables deduplication based on `libcasr` for `StacktraceObserver`
casr = ["libcasr", "std", "regex"]

## Enables features for corpus minimization
cmin = ["z3"]

## Enables the `PrometheusMonitor` which will monitor stats via UDP, for `Grafana` and others.
prometheus_monitor = ["std", "async-std", "prometheus-client", "tide", "futures"]

## Include a simple concolic mutator based on z3
concolic_mutation = ["z3"]

# LLMP features
llmp_bind_public = ["libafl_bolts/llmp_bind_public"] # If set, llmp will bind to 0.0.0.0, allowing cross-device communication. Binds to localhost by default.
llmp_compression = ["libafl_bolts/llmp_compression"] # llmp compression using GZip
llmp_debug = ["libafl_bolts/llmp_debug"] # Enables debug output for LLMP
## Enable the fancy TuiMonitor for a termanal UI using crossterm
tui_monitor = ["tui", "crossterm"]


#! ## LibAFL-Bolts Features

## Provide the `#[derive(SerdeAny)]` macro.
derive = ["libafl_derive", "libafl_bolts/derive"] # provide `derive(SerdeAny) macro.

## Expose `libafl_bolts::cli` for easy commandline parsing of common fuzzer settings
cli = ["libafl_bolts/cli"]

## Enables extra commandline flags for qemu-based fuzzers in `cli`
qemu_cli = ["cli", "libafl_bolts/qemu_cli"]

## Enables extra commandline flags for frida-based fuzzers in `cli`
frida_cli = ["cli", "libafl_bolts/frida_cli"]

## If set, libafl_bolt's `rand` implementations will implement `rand::Rng`
rand_trait = ["libafl_bolts/rand_trait"]

#! ### SerdeAny features

## Automatically register all `#[derive(SerdeAny)]` types at startup.
serdeany_autoreg = ["libafl_bolts/serdeany_autoreg"]

#! ### LLMP features

## The broker loop will yield occasionally, even without status messages from client nodes
llmp_broker_timeouts = ["std"]

## If set, llmp will bind to 0.0.0.0, allowing cross-device communication. Binds to localhost by default.
llmp_bind_public = ["libafl_bolts/llmp_bind_public"]

## Enables llmp compression using GZip
llmp_compression = ["libafl_bolts/llmp_compression"]

## Enables debug output for LLMP (also needs a `logger` installed)
llmp_debug = ["libafl_bolts/llmp_debug"]

## Reduces the initial map size for llmp
llmp_small_maps = ["libafl_bolts/llmp_small_maps"] # reduces initial map size for llmp
llmp_broker_timeouts = ["std"] # The broker loop will yield occasionally, even without status messages from client nodes

#! ## License-Changing Dependencies(!)

## Enables features hiding dependencies licensed under `AGPL`
agpl = ["nautilus"]

## Enables the [`Nautilus`](https://wcventure.github.io/FuzzingPaper/Paper/NDSS19_Nautilus.pdf) Grammar Mutator (AGPL-licensed)
nautilus = ["grammartec", "std", "serde_json/std"]

[build-dependencies]
rustversion = "1.0"
Expand Down Expand Up @@ -107,6 +175,9 @@ libcasr = { version = "2.7", optional = true}
# optional-dev deps (change when target.'cfg(accessible(::std))'.test-dependencies will be stable)
serial_test = { version = "2", optional = true, default-features = false, features = ["logging"] }

# Document all features of this crate (for `cargo doc`)
document-features = { version = "0.2" }

# AGPL
# !!! this create requires nightly
grammartec = { version = "0.3", optional = true }
Expand Down
5 changes: 2 additions & 3 deletions libafl/src/events/tcp.rs
Expand Up @@ -335,8 +335,7 @@ where
}
}

/// An [`EventManager`] that forwards all events to other attached fuzzers on shared maps or via tcp,
/// using low-level message passing, [`libafl_bolts::tcp`].
/// An [`EventManager`] that forwards all events to other attached via tcp.
pub struct TcpEventManager<S>
where
S: UsesInput,
Expand Down Expand Up @@ -844,7 +843,7 @@ pub enum ManagerKind {
/// The CPU core ID of this client
cpu_core: Option<CoreId>,
},
/// A [`tcp::TcpBroker`], forwarding the packets of local clients.
/// A broker, forwarding all packets of local clients via TCP.
Broker,
}

Expand Down
4 changes: 3 additions & 1 deletion libafl/src/lib.rs
@@ -1,7 +1,9 @@
/*!
Welcome to `LibAFL`
*/

#![doc = include_str!("../../README.md")]
/*! */
#![doc = document_features::document_features!()]
#![allow(incomplete_features)]
#![no_std]
// For `type_eq`
Expand Down
72 changes: 56 additions & 16 deletions libafl_bolts/Cargo.toml
Expand Up @@ -12,30 +12,67 @@ edition = "2021"
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]

[package.metadata.docs.rs]
features = ["document-features"]
all-features = true

[features]
default = ["std", "derive", "llmp_compression", "llmp_small_maps", "rand_trait", "prelude", "gzip", "serdeany_autoreg", "alloc"]
std = ["serde_json", "serde_json/std", "hostname", "nix", "serde/std", "uuid", "backtrace", "uds", "serial_test", "alloc"] # print, env, ... support
alloc = ["serde/alloc", "hashbrown", "postcard", "erased-serde/alloc", "ahash"] # Enables all features that allocate in no_std
derive = ["libafl_derive"] # provide derive(SerdeAny) macro.
rand_trait = ["rand_core"] # If set, libafl's rand implementations will implement `rand::Rng`

#! # Feature Flags
#! ### General Features

## Enables features that need rust's `std` lib to work, like print, env, ... support
std = ["serde_json", "serde_json/std", "hostname", "nix", "serde/std", "uuid", "backtrace", "uds", "serial_test", "alloc"]

## Enables all features that allocate in `no_std`
alloc = ["serde/alloc", "hashbrown", "postcard", "erased-serde/alloc", "ahash"]

## Provide the `#[derive(SerdeAny)]` macro.
derive = ["libafl_derive"]

## If set, libafl_bolt's `rand` implementations will implement `rand::Rng`
rand_trait = ["rand_core"]

## Will build the `pyo3` bindings
python = ["pyo3", "std"]
prelude = [] # Expose libafl::prelude for access without additional using directives
cli = ["clap"] # expose libafl_bolts::cli for easy commandline parsing
qemu_cli = ["cli"] # Commandline flagr for qemu-based fuzzers
frida_cli = ["cli"] # Commandline flags for frida-based fuzzers

## Expose `libafl::prelude` for direct access to all types without additional `use` directives
prelude = []

## Expose `libafl_bolts::cli` for easy commandline parsing of common fuzzer settings
cli = ["clap"]

## Enables extra commandline flags for qemu-based fuzzers in `cli`
qemu_cli = ["cli"]

## Enables extra commandline flags for frida-based fuzzers in `cli`
frida_cli = ["cli"]

## Stores the backtraces of all generated `Error`s. Good for debugging, but may come with a slight performance hit.
errors_backtrace = ["backtrace"]
gzip = ["miniz_oxide", "alloc"] # Enables gzip compression in certain parts of the lib

# SerdeAny features
serdeany_autoreg = ["ctor"] # Automatically register all `#[derive(SerdeAny)]` types at startup.
## Enables gzip compression in certain parts of the lib
gzip = ["miniz_oxide", "alloc"]

#! ### SerdeAny features

## Automatically register all `#[derive(SerdeAny)]` types at startup.
serdeany_autoreg = ["ctor"]


#! ### LLMP features

# LLMP features
llmp_bind_public = ["alloc"] # If set, llmp will bind to 0.0.0.0, allowing cross-device communication. Binds to localhost by default.
llmp_compression = ["alloc", "gzip"] # llmp compression using GZip
llmp_debug = ["alloc"] # Enables debug output for LLMP
llmp_small_maps = ["alloc"] # reduces initial map size for llmp
## If set, llmp will bind to 0.0.0.0, allowing cross-device communication. Binds to localhost by default.
llmp_bind_public = ["alloc"]

## Enables llmp compression using GZip
llmp_compression = ["alloc", "gzip"]

## Enables debug output for LLMP (also needs a `logger` installed)
llmp_debug = ["alloc"]

## Reduces the initial map size for llmp
llmp_small_maps = ["alloc"]

[build-dependencies]
rustversion = "1.0"
Expand Down Expand Up @@ -73,6 +110,9 @@ pyo3 = { version = "0.18.3", optional = true, features = ["serde", "macros"] }
# optional-dev deps (change when target.'cfg(accessible(::std))'.test-dependencies will be stable)
serial_test = { version = "2", optional = true, default-features = false, features = ["logging"] }

# Document all features of this crate (for `cargo doc`)
document-features = { version = "0.2" }

[target.'cfg(unix)'.dependencies]
libc = "0.2" # For (*nix) libc
uds = { version = "0.4", optional = true, default-features = false }
Expand Down
8 changes: 4 additions & 4 deletions libafl_bolts/src/lib.rs
@@ -1,9 +1,9 @@
#![doc = include_str!("../README.md")]

/*!
Welcome to `LibAFL`
* Welcome to `LibAFL_bolts`
*/

#![doc = include_str!("../README.md")]
/*! */
#![doc = document_features::document_features!()]
#![allow(incomplete_features)]
#![no_std]
// For `type_eq`
Expand Down
6 changes: 3 additions & 3 deletions libafl_targets/src/sancov_8bit.rs
Expand Up @@ -52,11 +52,11 @@ mod observers {

#[must_use]
#[export_name = "counters_maps_observer"]
/// Create a new [`CountersMultiMapObserver`] of the [`COUNTERS_MAP`].
/// Create a new [`CountersMultiMapObserver`] of the [`COUNTERS_MAPS`].
///
/// This is a special [`MultiMapObserver`] for the [`COUNTERS_MAP`] and may be used when
/// This is a special [`libafl::observers::MultiMapObserver`] for the [`COUNTERS_MAPS`] and may be used when
/// 8-bit counters are used for `SanitizerCoverage`. You can utilize this observer in a
/// [`HitcountsIterableMapObserver`] like so:
/// [`libafl::observers::HitcountsIterableMapObserver`] like so:
///
/// ```rust,ignore
/// use libafl::{
Expand Down

0 comments on commit f68fe95

Please sign in to comment.