mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
fuzz: Add honggfuzz (#206)
* fuzz: Add honggfuzz - Added honggfuzz in fuzz2/ (alongside libfuzzer in fuzz/) - Created convenience script for fuzzing binary decoder - Created a script to convert inputs that cause crashes into arrays so that they can be used in unit tests * Create honggfuzz as subdirectory of fuzz/ - Reorg so that honggfuzz is under fuzz/ instead of in a separate sibling-level directory fuzz2 - Update fuzz/README.md to make it explicit that it covers libfuzzer Note: `cargo fuzz`/libfuzzer seems to insist that its folder exists at `$REPO/fuzz/` so that's the reason for this particular folder structure. --------- Co-authored-by: y <y>
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
# DarkFi Fuzzing
|
||||
|
||||
This directory contains our fuzz tests. It is a WIP and likley to be
|
||||
re-organized as we expand the complexity of the tests
|
||||
This directory contains our fuzz tests. It is a WIP and likely to be
|
||||
re-organized as we expand the complexity of the tests.
|
||||
|
||||
This document covers the usage of `libfuzzer`. An alternative fuzzing
|
||||
tool `honggfuzz` and its related files are located in `fuzz/honggfuzz`.
|
||||
|
||||
## Building the corpora
|
||||
|
||||
@@ -73,4 +76,4 @@ This might introduce subtle issues in the fuzzing process especially since
|
||||
errors found during fuzzing are likely to be precisely the edge-cases that
|
||||
trigger incompatibilites between build architectures.
|
||||
|
||||
Further research is needed here to find a reliable solution.
|
||||
Further research is needed here to find a reliable solution.
|
||||
|
||||
4
fuzz/honggfuzz/.gitignore
vendored
Normal file
4
fuzz/honggfuzz/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
Cargo.lock
|
||||
target/
|
||||
hfuzz_target/
|
||||
hfuzz_workspace/*/input/*
|
||||
41
fuzz/honggfuzz/Cargo.toml
Normal file
41
fuzz/honggfuzz/Cargo.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
[package]
|
||||
name = "darkfi-fuzz2"
|
||||
version = "0.0.0"
|
||||
publish = false
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata]
|
||||
cargo-fuzz = true
|
||||
|
||||
[dependencies]
|
||||
honggfuzz = "0.5"
|
||||
|
||||
[dependencies.darkfi]
|
||||
path = "../.."
|
||||
features = ["zkas"]
|
||||
|
||||
[dependencies.darkfi-serial]
|
||||
path = "../../src/serial"
|
||||
features = ["derive", "semver", "collections", "crypto", "hash"]
|
||||
|
||||
[patch.crates-io]
|
||||
blake2b_simd = {git="https://github.com/parazyd/blake2_simd", branch="impl-common"}
|
||||
|
||||
# Prevent this from interfering with workspaces
|
||||
[workspace]
|
||||
members = ["."]
|
||||
|
||||
[profile.release]
|
||||
debug = 1
|
||||
|
||||
[[bin]]
|
||||
name = "zkbinary-decode"
|
||||
path = "src/zkbinary_decode.rs"
|
||||
test = false
|
||||
doc = false
|
||||
|
||||
[[bin]]
|
||||
name = "serial-decode-string"
|
||||
path = "src/serial_decode_string.rs"
|
||||
test = false
|
||||
doc = false
|
||||
28
fuzz/honggfuzz/README.md
Normal file
28
fuzz/honggfuzz/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Fuzz2 - honggfuzz
|
||||
|
||||
This directory contains files pertaining to fuzz testing with the [`honggfuzz` fuzzer](https://docs.rs/honggfuzz/latest/honggfuzz/).
|
||||
|
||||
We're trying this tool out alongside libfuzzer (covered in `darkfi/fuzz/`).
|
||||
|
||||
## Comparison to libfuzzer
|
||||
|
||||
- Does not halt execution on crashes (can discover multiple crashes in one fuzzing session)
|
||||
- Fewer memory issues (tool less likely to crash, easier to configure)
|
||||
- Better UI
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
cargo install honggfuzz
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
# Build targets from Cargo.toml [[bin]] section
|
||||
cargo hfuzz build
|
||||
# Run
|
||||
cargo hfuzz run zkbinary-decode
|
||||
```
|
||||
|
||||
Further info: https://docs.rs/honggfuzz/latest/honggfuzz/#how-to-use-this-crate
|
||||
@@ -0,0 +1,48 @@
|
||||
=====================================================================
|
||||
TIME: 2023-08-30.15:26:53
|
||||
=====================================================================
|
||||
FUZZER ARGS:
|
||||
mutationsPerRun : 5
|
||||
externalCmd : NULL
|
||||
fuzzStdin : FALSE
|
||||
timeout : 5 (sec)
|
||||
ignoreAddr : (nil)
|
||||
ASLimit : 0 (MiB)
|
||||
RSSLimit : 0 (MiB)
|
||||
DATALimit : 0 (MiB)
|
||||
wordlistFile : NULL
|
||||
dynFileMethod :
|
||||
fuzzTarget : hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string
|
||||
CRASH:
|
||||
DESCRIPTION:
|
||||
ORIG_FNAME: 63ade6888888884b45c5555555557de6.00000010.honggfuzz.cov
|
||||
FUZZ_FNAME: hfuzz_workspace/serial-decode-string/SIGABRT.PC.7ffff7c8e83c.STACK.c8ecc5e84.CODE.-6.ADDR.0.INSTR.mov____%eax,%ebx.fuzz
|
||||
PID: 237583
|
||||
SIGNAL: SIGABRT (6)
|
||||
PC: 0x7ffff7c8e83c
|
||||
FAULT ADDRESS: 0x0
|
||||
INSTRUCTION: mov____%eax,%ebx
|
||||
STACK HASH: 0000000c8ecc5e84
|
||||
STACK:
|
||||
<0x00007ffff7c3e668> [func:UNKNOWN file: line:0 module:/usr/lib/libc.so.6]
|
||||
<0x00007ffff7c264b8> [func:UNKNOWN file: line:0 module:/usr/lib/libc.so.6]
|
||||
<0x000055555558ec77> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555555d197> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x0000555555560f77> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555558cf50> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555558cc91> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555558b586> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555558ca22> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555555e393> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555555fa3a> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555556074b> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x0000555555560a9d> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x00005555555608d5> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x000055555556089a> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x0000555555560828> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x00005555555867fb> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x00005555555607fc> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
<0x00007ffff7c27cd0> [func:UNKNOWN file: line:0 module:/usr/lib/libc.so.6]
|
||||
<0x00007ffff7c27d8a> [func:UNKNOWN file: line:0 module:/usr/lib/libc.so.6]
|
||||
<0x000055555555ecd5> [func:UNKNOWN file: line:0 module:/home/psychopomp/coding/darkfi/main/fuzz2/hfuzz_target/x86_64-unknown-linux-gnu/release/serial-decode-string]
|
||||
=====================================================================
|
||||
Binary file not shown.
33
fuzz/honggfuzz/script/binary-to-bytearray.py
Executable file
33
fuzz/honggfuzz/script/binary-to-bytearray.py
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Take a binary file as input and prints its bytes as ordinals, formatted as an
|
||||
array. The goal is to take a file that has caused a crash during binary fuzzing
|
||||
and convert it into a unit test that can detect panic regressioins.
|
||||
See darkfi/src/zkas/decoder.rs for example unit tests.
|
||||
|
||||
input:
|
||||
- binary.bin
|
||||
|
||||
output
|
||||
- [1, 2, 3, 5, 8, 11]
|
||||
|
||||
Now the output can be easily pasted into a unit test.
|
||||
"""
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print(f"Usage: {__file__} <binary_file>")
|
||||
exit(1)
|
||||
|
||||
if not os.path.isfile(sys.argv[1]):
|
||||
print("Argument is not a file")
|
||||
exit(2)
|
||||
|
||||
bytes = []
|
||||
with open(sys.argv[1], "rb") as f:
|
||||
while (byte := f.read(1)):
|
||||
bytes.append(str(ord(byte)))
|
||||
|
||||
print(f"[{', '.join(bytes)}]")
|
||||
15
fuzz/honggfuzz/script/generate-binary-corpus.sh
Executable file
15
fuzz/honggfuzz/script/generate-binary-corpus.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#/usr/bin/env bash
|
||||
: '
|
||||
Copies all ZK binary files (.zk.bin) from the main repository into a destination folder
|
||||
in the fuzzing directory. This allows the compiled example binaries to be used as
|
||||
test inputs for the fuzzer. This should in turn allow for more efficient fuzzing.
|
||||
'
|
||||
set -e
|
||||
|
||||
# Run from inside fuzz2 directory
|
||||
CWD=$(pwd)
|
||||
DST=$CWD/hfuzz_workspace/zkbinary-decode/input/
|
||||
cd ..
|
||||
mkdir -p $DST
|
||||
find -name "*.zk.bin" -exec cp {} $CWD/hfuzz_workspace/zkbinary-decode/input/ \;
|
||||
cd $CWD
|
||||
34
fuzz/honggfuzz/src/serial_decode_string.rs
Normal file
34
fuzz/honggfuzz/src/serial_decode_string.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
/* This file is part of DarkFi (https://dark.fi)
|
||||
*
|
||||
* Copyright (C) 2020-2023 Dyne.org foundation
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern crate darkfi_serial;
|
||||
|
||||
use honggfuzz::fuzz;
|
||||
use darkfi_serial::deserialize;
|
||||
|
||||
fn main() {
|
||||
loop {
|
||||
fuzz!(|data: &[u8]| {
|
||||
// Deserialize arbitrary data as a String
|
||||
let _res: String = match deserialize::<String>(&data) {
|
||||
Ok(..) => "".to_string(),
|
||||
Err(..) => "".to_string(),
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
30
fuzz/honggfuzz/src/zkbinary_decode.rs
Normal file
30
fuzz/honggfuzz/src/zkbinary_decode.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
/* This file is part of DarkFi (https://dark.fi)
|
||||
*
|
||||
* Copyright (C) 2020-2023 Dyne.org foundation
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
extern crate darkfi_serial;
|
||||
|
||||
use honggfuzz::fuzz;
|
||||
use darkfi::zkas::ZkBinary;
|
||||
|
||||
fn main() {
|
||||
loop {
|
||||
fuzz!(|data: &[u8]| {
|
||||
let _dec = ZkBinary::decode(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user