Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,21 @@ cc = "1.0"
members = ["."]

[profile.release]
panic = "abort"
lto = true
codegen-units = 1
debug-assertions = true
overflow-checks = true

# When testing a large fuzz corpus, -O1 offers a nice speedup
[profile.dev]
panic = "abort"
opt-level = 1

[lib]
name = "lightning_fuzz"
path = "src/lib.rs"
crate-type = ["rlib", "dylib", "staticlib"]
crate-type = ["rlib", "staticlib"]

[lints.rust.unexpected_cfgs]
level = "forbid"
Expand Down
10 changes: 10 additions & 0 deletions fuzz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,16 @@ mv hfuzz_workspace/fuzz_target/SIGABRT.PC.7ffff7e21ce1.STACK.[…].fuzz ./test_c

This will reproduce the failing fuzz input and yield a usable stack trace.

Alternatively, you can use the `stdin_fuzz` feature to pipe the crash input directly without
creating test case files on disk:

```shell
echo -ne '\x2d\x31\x36\x38\x37\x34\x09\x01...' | RUSTFLAGS="--cfg=fuzzing --cfg=secp256k1_fuzz --cfg=hashes_fuzz" cargo run --features stdin_fuzz --bin full_stack_target
```

Panics will abort the process directly (the crate uses `panic = "abort"`), resulting in a
non-zero exit code. Piping via stdin is useful for reproducing crashes during `git bisect` or
when working with AI agents that can construct and pipe byte sequences directly.

## How do I add a new fuzz test?

Expand Down
11 changes: 6 additions & 5 deletions fuzz/src/bin/base32_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");

extern crate lightning_fuzz;
use lightning_fuzz::base32::*;
use lightning_fuzz::utils::test_logger;

#[cfg(feature = "afl")]
#[macro_use] extern crate afl;
#[cfg(feature = "afl")]
fn main() {
fuzz!(|data| {
base32_run(data.as_ptr(), data.len());
base32_test(&data, test_logger::DevNull {});
});
}

Expand All @@ -40,7 +41,7 @@ fn main() {
fn main() {
loop {
fuzz!(|data| {
base32_run(data.as_ptr(), data.len());
base32_test(&data, test_logger::DevNull {});
});
}
}
Expand All @@ -49,7 +50,7 @@ fn main() {
#[macro_use] extern crate libfuzzer_sys;
#[cfg(feature = "libfuzzer_fuzz")]
fuzz_target!(|data: &[u8]| {
base32_run(data.as_ptr(), data.len());
base32_test(data, test_logger::DevNull {});
});

#[cfg(feature = "stdin_fuzz")]
Expand All @@ -58,7 +59,7 @@ fn main() {

let mut data = Vec::with_capacity(8192);
std::io::stdin().read_to_end(&mut data).unwrap();
base32_run(data.as_ptr(), data.len());
base32_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
}

#[test]
Expand All @@ -70,7 +71,7 @@ fn run_test_cases() {
use std::sync::{atomic, Arc};
{
let data: Vec<u8> = vec![0];
base32_run(data.as_ptr(), data.len());
base32_test(&data, test_logger::DevNull {});
}
let mut threads = Vec::new();
let threads_running = Arc::new(atomic::AtomicUsize::new(0));
Expand Down
11 changes: 6 additions & 5 deletions fuzz/src/bin/bech32_parse_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");

extern crate lightning_fuzz;
use lightning_fuzz::bech32_parse::*;
use lightning_fuzz::utils::test_logger;

#[cfg(feature = "afl")]
#[macro_use] extern crate afl;
#[cfg(feature = "afl")]
fn main() {
fuzz!(|data| {
bech32_parse_run(data.as_ptr(), data.len());
bech32_parse_test(&data, test_logger::DevNull {});
});
}

Expand All @@ -40,7 +41,7 @@ fn main() {
fn main() {
loop {
fuzz!(|data| {
bech32_parse_run(data.as_ptr(), data.len());
bech32_parse_test(&data, test_logger::DevNull {});
});
}
}
Expand All @@ -49,7 +50,7 @@ fn main() {
#[macro_use] extern crate libfuzzer_sys;
#[cfg(feature = "libfuzzer_fuzz")]
fuzz_target!(|data: &[u8]| {
bech32_parse_run(data.as_ptr(), data.len());
bech32_parse_test(data, test_logger::DevNull {});
});

#[cfg(feature = "stdin_fuzz")]
Expand All @@ -58,7 +59,7 @@ fn main() {

let mut data = Vec::with_capacity(8192);
std::io::stdin().read_to_end(&mut data).unwrap();
bech32_parse_run(data.as_ptr(), data.len());
bech32_parse_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
}

#[test]
Expand All @@ -70,7 +71,7 @@ fn run_test_cases() {
use std::sync::{atomic, Arc};
{
let data: Vec<u8> = vec![0];
bech32_parse_run(data.as_ptr(), data.len());
bech32_parse_test(&data, test_logger::DevNull {});
}
let mut threads = Vec::new();
let threads_running = Arc::new(atomic::AtomicUsize::new(0));
Expand Down
11 changes: 6 additions & 5 deletions fuzz/src/bin/bolt11_deser_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");

extern crate lightning_fuzz;
use lightning_fuzz::bolt11_deser::*;
use lightning_fuzz::utils::test_logger;

#[cfg(feature = "afl")]
#[macro_use] extern crate afl;
#[cfg(feature = "afl")]
fn main() {
fuzz!(|data| {
bolt11_deser_run(data.as_ptr(), data.len());
bolt11_deser_test(&data, test_logger::DevNull {});
});
}

Expand All @@ -40,7 +41,7 @@ fn main() {
fn main() {
loop {
fuzz!(|data| {
bolt11_deser_run(data.as_ptr(), data.len());
bolt11_deser_test(&data, test_logger::DevNull {});
});
}
}
Expand All @@ -49,7 +50,7 @@ fn main() {
#[macro_use] extern crate libfuzzer_sys;
#[cfg(feature = "libfuzzer_fuzz")]
fuzz_target!(|data: &[u8]| {
bolt11_deser_run(data.as_ptr(), data.len());
bolt11_deser_test(data, test_logger::DevNull {});
});

#[cfg(feature = "stdin_fuzz")]
Expand All @@ -58,7 +59,7 @@ fn main() {

let mut data = Vec::with_capacity(8192);
std::io::stdin().read_to_end(&mut data).unwrap();
bolt11_deser_run(data.as_ptr(), data.len());
bolt11_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
}

#[test]
Expand All @@ -70,7 +71,7 @@ fn run_test_cases() {
use std::sync::{atomic, Arc};
{
let data: Vec<u8> = vec![0];
bolt11_deser_run(data.as_ptr(), data.len());
bolt11_deser_test(&data, test_logger::DevNull {});
}
let mut threads = Vec::new();
let threads_running = Arc::new(atomic::AtomicUsize::new(0));
Expand Down
11 changes: 6 additions & 5 deletions fuzz/src/bin/chanmon_consistency_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");

extern crate lightning_fuzz;
use lightning_fuzz::chanmon_consistency::*;
use lightning_fuzz::utils::test_logger;

#[cfg(feature = "afl")]
#[macro_use] extern crate afl;
#[cfg(feature = "afl")]
fn main() {
fuzz!(|data| {
chanmon_consistency_run(data.as_ptr(), data.len());
chanmon_consistency_test(&data, test_logger::DevNull {});
});
}

Expand All @@ -40,7 +41,7 @@ fn main() {
fn main() {
loop {
fuzz!(|data| {
chanmon_consistency_run(data.as_ptr(), data.len());
chanmon_consistency_test(&data, test_logger::DevNull {});
});
}
}
Expand All @@ -49,7 +50,7 @@ fn main() {
#[macro_use] extern crate libfuzzer_sys;
#[cfg(feature = "libfuzzer_fuzz")]
fuzz_target!(|data: &[u8]| {
chanmon_consistency_run(data.as_ptr(), data.len());
chanmon_consistency_test(data, test_logger::DevNull {});
});

#[cfg(feature = "stdin_fuzz")]
Expand All @@ -58,7 +59,7 @@ fn main() {

let mut data = Vec::with_capacity(8192);
std::io::stdin().read_to_end(&mut data).unwrap();
chanmon_consistency_run(data.as_ptr(), data.len());
chanmon_consistency_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
}

#[test]
Expand All @@ -70,7 +71,7 @@ fn run_test_cases() {
use std::sync::{atomic, Arc};
{
let data: Vec<u8> = vec![0];
chanmon_consistency_run(data.as_ptr(), data.len());
chanmon_consistency_test(&data, test_logger::DevNull {});
}
let mut threads = Vec::new();
let threads_running = Arc::new(atomic::AtomicUsize::new(0));
Expand Down
11 changes: 6 additions & 5 deletions fuzz/src/bin/chanmon_deser_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");

extern crate lightning_fuzz;
use lightning_fuzz::chanmon_deser::*;
use lightning_fuzz::utils::test_logger;

#[cfg(feature = "afl")]
#[macro_use] extern crate afl;
#[cfg(feature = "afl")]
fn main() {
fuzz!(|data| {
chanmon_deser_run(data.as_ptr(), data.len());
chanmon_deser_test(&data, test_logger::DevNull {});
});
}

Expand All @@ -40,7 +41,7 @@ fn main() {
fn main() {
loop {
fuzz!(|data| {
chanmon_deser_run(data.as_ptr(), data.len());
chanmon_deser_test(&data, test_logger::DevNull {});
});
}
}
Expand All @@ -49,7 +50,7 @@ fn main() {
#[macro_use] extern crate libfuzzer_sys;
#[cfg(feature = "libfuzzer_fuzz")]
fuzz_target!(|data: &[u8]| {
chanmon_deser_run(data.as_ptr(), data.len());
chanmon_deser_test(data, test_logger::DevNull {});
});

#[cfg(feature = "stdin_fuzz")]
Expand All @@ -58,7 +59,7 @@ fn main() {

let mut data = Vec::with_capacity(8192);
std::io::stdin().read_to_end(&mut data).unwrap();
chanmon_deser_run(data.as_ptr(), data.len());
chanmon_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
}

#[test]
Expand All @@ -70,7 +71,7 @@ fn run_test_cases() {
use std::sync::{atomic, Arc};
{
let data: Vec<u8> = vec![0];
chanmon_deser_run(data.as_ptr(), data.len());
chanmon_deser_test(&data, test_logger::DevNull {});
}
let mut threads = Vec::new();
let threads_running = Arc::new(atomic::AtomicUsize::new(0));
Expand Down
11 changes: 6 additions & 5 deletions fuzz/src/bin/feature_flags_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");

extern crate lightning_fuzz;
use lightning_fuzz::feature_flags::*;
use lightning_fuzz::utils::test_logger;

#[cfg(feature = "afl")]
#[macro_use] extern crate afl;
#[cfg(feature = "afl")]
fn main() {
fuzz!(|data| {
feature_flags_run(data.as_ptr(), data.len());
feature_flags_test(&data, test_logger::DevNull {});
});
}

Expand All @@ -40,7 +41,7 @@ fn main() {
fn main() {
loop {
fuzz!(|data| {
feature_flags_run(data.as_ptr(), data.len());
feature_flags_test(&data, test_logger::DevNull {});
});
}
}
Expand All @@ -49,7 +50,7 @@ fn main() {
#[macro_use] extern crate libfuzzer_sys;
#[cfg(feature = "libfuzzer_fuzz")]
fuzz_target!(|data: &[u8]| {
feature_flags_run(data.as_ptr(), data.len());
feature_flags_test(data, test_logger::DevNull {});
});

#[cfg(feature = "stdin_fuzz")]
Expand All @@ -58,7 +59,7 @@ fn main() {

let mut data = Vec::with_capacity(8192);
std::io::stdin().read_to_end(&mut data).unwrap();
feature_flags_run(data.as_ptr(), data.len());
feature_flags_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
}

#[test]
Expand All @@ -70,7 +71,7 @@ fn run_test_cases() {
use std::sync::{atomic, Arc};
{
let data: Vec<u8> = vec![0];
feature_flags_run(data.as_ptr(), data.len());
feature_flags_test(&data, test_logger::DevNull {});
}
let mut threads = Vec::new();
let threads_running = Arc::new(atomic::AtomicUsize::new(0));
Expand Down
Loading
Loading