Skip to content

Commit ba99ab9

Browse files
joostjagerclaude
andcommitted
Use panic=abort for fuzz crate and remove extern "C" FFI wrappers
Remove crate-type = ["rlib", "dylib", "staticlib"] from the fuzz library, keeping only the default rlib. The dylib and staticlib types were added in e28fd78 (2019) for a planned C-callable harness that was never implemented. Nothing consumes the generated targets.h header or links against the shared/static library. Removing dylib is what enables panic=abort: Rust forces panic=unwind on dylib crates for ABI compatibility, which prevented setting panic=abort regardless of profile settings. With only rlib remaining, panic=abort now works and is set on both dev and release profiles. This eliminates unwind table generation and landing pad overhead, producing smaller and faster fuzz binaries. The stdin_fuzz targets no longer need catch_unwind + process::exit(1) since panics now abort the process directly (exit code 134/SIGABRT). cargo test continues to work because the test harness automatically overrides panic=abort back to panic=unwind. Also remove all #[no_mangle] pub extern "C" fn ..._run() wrappers from every fuzz module. These existed to expose each target through the C ABI via the now-removed staticlib/dylib, but all fuzzer frontends (AFL, honggfuzz, libfuzzer, stdin_fuzz) are Rust binaries that can call the _test() functions directly. The generated target binaries are updated accordingly. Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent ccbc566 commit ba99ab9

File tree

149 files changed

+439
-1230
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+439
-1230
lines changed

fuzz/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,20 @@ cc = "1.0"
3939
members = ["."]
4040

4141
[profile.release]
42+
panic = "abort"
4243
lto = true
4344
codegen-units = 1
4445
debug-assertions = true
4546
overflow-checks = true
4647

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

5153
[lib]
5254
name = "lightning_fuzz"
5355
path = "src/lib.rs"
54-
crate-type = ["rlib", "dylib", "staticlib"]
5556

5657
[lints.rust.unexpected_cfgs]
5758
level = "forbid"

fuzz/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,9 @@ creating test case files on disk:
155155
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
156156
```
157157

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

161162
## How do I add a new fuzz test?
162163

@@ -166,8 +167,8 @@ suitable. For the sake of example, let's call the new fuzz target we're creating
166167
`my_fuzzy_experiment`.
167168

168169
2. In the newly created file `fuzz/src/my_fuzzy_experiment.rs`, run a string substitution
169-
of `process_network_graph` to `my_fuzzy_experiment`, such that the three methods in the
170-
file are `do_test`, `my_fuzzy_experiment_test`, and `my_fuzzy_experiment_run`.
170+
of `process_network_graph` to `my_fuzzy_experiment`, such that the two methods in the
171+
file are `do_test` and `my_fuzzy_experiment_test`.
171172

172173
3. Adjust the body (not the signature!) of `do_test` as necessary for the new fuzz test.
173174

fuzz/src/base32.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,3 @@ pub fn do_test(data: &[u8]) {
5151
pub fn base32_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
5252
do_test(data);
5353
}
54-
55-
#[no_mangle]
56-
pub extern "C" fn base32_run(data: *const u8, datalen: usize) {
57-
do_test(unsafe { std::slice::from_raw_parts(data, datalen) });
58-
}

fuzz/src/bech32_parse.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,3 @@ impl core::fmt::Display for Bytes {
5050
pub fn bech32_parse_test<Out: test_logger::Output>(data: &[u8], out: Out) {
5151
do_test(data, out);
5252
}
53-
54-
#[no_mangle]
55-
pub extern "C" fn bech32_parse_run(data: *const u8, datalen: usize) {
56-
do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, test_logger::DevNull {});
57-
}

fuzz/src/bin/base32_target.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");
2424

2525
extern crate lightning_fuzz;
2626
use lightning_fuzz::base32::*;
27+
use lightning_fuzz::utils::test_logger;
2728

2829
#[cfg(feature = "afl")]
2930
#[macro_use] extern crate afl;
3031
#[cfg(feature = "afl")]
3132
fn main() {
3233
fuzz!(|data| {
33-
base32_run(data.as_ptr(), data.len());
34+
base32_test(&data, test_logger::DevNull {});
3435
});
3536
}
3637

@@ -40,7 +41,7 @@ fn main() {
4041
fn main() {
4142
loop {
4243
fuzz!(|data| {
43-
base32_run(data.as_ptr(), data.len());
44+
base32_test(&data, test_logger::DevNull {});
4445
});
4546
}
4647
}
@@ -49,7 +50,7 @@ fn main() {
4950
#[macro_use] extern crate libfuzzer_sys;
5051
#[cfg(feature = "libfuzzer_fuzz")]
5152
fuzz_target!(|data: &[u8]| {
52-
base32_run(data.as_ptr(), data.len());
53+
base32_test(data, test_logger::DevNull {});
5354
});
5455

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

5960
let mut data = Vec::with_capacity(8192);
6061
std::io::stdin().read_to_end(&mut data).unwrap();
61-
let res = std::panic::catch_unwind(|| {
62-
base32_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
63-
});
64-
if res.is_err() {
65-
std::process::exit(1);
66-
}
62+
base32_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
6763
}
6864

6965
#[test]
@@ -75,7 +71,7 @@ fn run_test_cases() {
7571
use std::sync::{atomic, Arc};
7672
{
7773
let data: Vec<u8> = vec![0];
78-
base32_run(data.as_ptr(), data.len());
74+
base32_test(&data, test_logger::DevNull {});
7975
}
8076
let mut threads = Vec::new();
8177
let threads_running = Arc::new(atomic::AtomicUsize::new(0));

fuzz/src/bin/bech32_parse_target.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");
2424

2525
extern crate lightning_fuzz;
2626
use lightning_fuzz::bech32_parse::*;
27+
use lightning_fuzz::utils::test_logger;
2728

2829
#[cfg(feature = "afl")]
2930
#[macro_use] extern crate afl;
3031
#[cfg(feature = "afl")]
3132
fn main() {
3233
fuzz!(|data| {
33-
bech32_parse_run(data.as_ptr(), data.len());
34+
bech32_parse_test(&data, test_logger::DevNull {});
3435
});
3536
}
3637

@@ -40,7 +41,7 @@ fn main() {
4041
fn main() {
4142
loop {
4243
fuzz!(|data| {
43-
bech32_parse_run(data.as_ptr(), data.len());
44+
bech32_parse_test(&data, test_logger::DevNull {});
4445
});
4546
}
4647
}
@@ -49,7 +50,7 @@ fn main() {
4950
#[macro_use] extern crate libfuzzer_sys;
5051
#[cfg(feature = "libfuzzer_fuzz")]
5152
fuzz_target!(|data: &[u8]| {
52-
bech32_parse_run(data.as_ptr(), data.len());
53+
bech32_parse_test(data, test_logger::DevNull {});
5354
});
5455

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

5960
let mut data = Vec::with_capacity(8192);
6061
std::io::stdin().read_to_end(&mut data).unwrap();
61-
let res = std::panic::catch_unwind(|| {
62-
bech32_parse_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
63-
});
64-
if res.is_err() {
65-
std::process::exit(1);
66-
}
62+
bech32_parse_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
6763
}
6864

6965
#[test]
@@ -75,7 +71,7 @@ fn run_test_cases() {
7571
use std::sync::{atomic, Arc};
7672
{
7773
let data: Vec<u8> = vec![0];
78-
bech32_parse_run(data.as_ptr(), data.len());
74+
bech32_parse_test(&data, test_logger::DevNull {});
7975
}
8076
let mut threads = Vec::new();
8177
let threads_running = Arc::new(atomic::AtomicUsize::new(0));

fuzz/src/bin/bolt11_deser_target.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");
2424

2525
extern crate lightning_fuzz;
2626
use lightning_fuzz::bolt11_deser::*;
27+
use lightning_fuzz::utils::test_logger;
2728

2829
#[cfg(feature = "afl")]
2930
#[macro_use] extern crate afl;
3031
#[cfg(feature = "afl")]
3132
fn main() {
3233
fuzz!(|data| {
33-
bolt11_deser_run(data.as_ptr(), data.len());
34+
bolt11_deser_test(&data, test_logger::DevNull {});
3435
});
3536
}
3637

@@ -40,7 +41,7 @@ fn main() {
4041
fn main() {
4142
loop {
4243
fuzz!(|data| {
43-
bolt11_deser_run(data.as_ptr(), data.len());
44+
bolt11_deser_test(&data, test_logger::DevNull {});
4445
});
4546
}
4647
}
@@ -49,7 +50,7 @@ fn main() {
4950
#[macro_use] extern crate libfuzzer_sys;
5051
#[cfg(feature = "libfuzzer_fuzz")]
5152
fuzz_target!(|data: &[u8]| {
52-
bolt11_deser_run(data.as_ptr(), data.len());
53+
bolt11_deser_test(data, test_logger::DevNull {});
5354
});
5455

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

5960
let mut data = Vec::with_capacity(8192);
6061
std::io::stdin().read_to_end(&mut data).unwrap();
61-
let res = std::panic::catch_unwind(|| {
62-
bolt11_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
63-
});
64-
if res.is_err() {
65-
std::process::exit(1);
66-
}
62+
bolt11_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
6763
}
6864

6965
#[test]
@@ -75,7 +71,7 @@ fn run_test_cases() {
7571
use std::sync::{atomic, Arc};
7672
{
7773
let data: Vec<u8> = vec![0];
78-
bolt11_deser_run(data.as_ptr(), data.len());
74+
bolt11_deser_test(&data, test_logger::DevNull {});
7975
}
8076
let mut threads = Vec::new();
8177
let threads_running = Arc::new(atomic::AtomicUsize::new(0));

fuzz/src/bin/chanmon_consistency_target.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");
2424

2525
extern crate lightning_fuzz;
2626
use lightning_fuzz::chanmon_consistency::*;
27+
use lightning_fuzz::utils::test_logger;
2728

2829
#[cfg(feature = "afl")]
2930
#[macro_use] extern crate afl;
3031
#[cfg(feature = "afl")]
3132
fn main() {
3233
fuzz!(|data| {
33-
chanmon_consistency_run(data.as_ptr(), data.len());
34+
chanmon_consistency_test(&data, test_logger::DevNull {});
3435
});
3536
}
3637

@@ -40,7 +41,7 @@ fn main() {
4041
fn main() {
4142
loop {
4243
fuzz!(|data| {
43-
chanmon_consistency_run(data.as_ptr(), data.len());
44+
chanmon_consistency_test(&data, test_logger::DevNull {});
4445
});
4546
}
4647
}
@@ -49,7 +50,7 @@ fn main() {
4950
#[macro_use] extern crate libfuzzer_sys;
5051
#[cfg(feature = "libfuzzer_fuzz")]
5152
fuzz_target!(|data: &[u8]| {
52-
chanmon_consistency_run(data.as_ptr(), data.len());
53+
chanmon_consistency_test(data, test_logger::DevNull {});
5354
});
5455

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

5960
let mut data = Vec::with_capacity(8192);
6061
std::io::stdin().read_to_end(&mut data).unwrap();
61-
let res = std::panic::catch_unwind(|| {
62-
chanmon_consistency_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
63-
});
64-
if res.is_err() {
65-
std::process::exit(1);
66-
}
62+
chanmon_consistency_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
6763
}
6864

6965
#[test]
@@ -75,7 +71,7 @@ fn run_test_cases() {
7571
use std::sync::{atomic, Arc};
7672
{
7773
let data: Vec<u8> = vec![0];
78-
chanmon_consistency_run(data.as_ptr(), data.len());
74+
chanmon_consistency_test(&data, test_logger::DevNull {});
7975
}
8076
let mut threads = Vec::new();
8177
let threads_running = Arc::new(atomic::AtomicUsize::new(0));

fuzz/src/bin/chanmon_deser_target.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ compile_error!("Fuzz targets need cfg=secp256k1_fuzz");
2424

2525
extern crate lightning_fuzz;
2626
use lightning_fuzz::chanmon_deser::*;
27+
use lightning_fuzz::utils::test_logger;
2728

2829
#[cfg(feature = "afl")]
2930
#[macro_use] extern crate afl;
3031
#[cfg(feature = "afl")]
3132
fn main() {
3233
fuzz!(|data| {
33-
chanmon_deser_run(data.as_ptr(), data.len());
34+
chanmon_deser_test(&data, test_logger::DevNull {});
3435
});
3536
}
3637

@@ -40,7 +41,7 @@ fn main() {
4041
fn main() {
4142
loop {
4243
fuzz!(|data| {
43-
chanmon_deser_run(data.as_ptr(), data.len());
44+
chanmon_deser_test(&data, test_logger::DevNull {});
4445
});
4546
}
4647
}
@@ -49,7 +50,7 @@ fn main() {
4950
#[macro_use] extern crate libfuzzer_sys;
5051
#[cfg(feature = "libfuzzer_fuzz")]
5152
fuzz_target!(|data: &[u8]| {
52-
chanmon_deser_run(data.as_ptr(), data.len());
53+
chanmon_deser_test(data, test_logger::DevNull {});
5354
});
5455

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

5960
let mut data = Vec::with_capacity(8192);
6061
std::io::stdin().read_to_end(&mut data).unwrap();
61-
let res = std::panic::catch_unwind(|| {
62-
chanmon_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
63-
});
64-
if res.is_err() {
65-
std::process::exit(1);
66-
}
62+
chanmon_deser_test(&data, lightning_fuzz::utils::test_logger::Stdout {});
6763
}
6864

6965
#[test]
@@ -75,7 +71,7 @@ fn run_test_cases() {
7571
use std::sync::{atomic, Arc};
7672
{
7773
let data: Vec<u8> = vec![0];
78-
chanmon_deser_run(data.as_ptr(), data.len());
74+
chanmon_deser_test(&data, test_logger::DevNull {});
7975
}
8076
let mut threads = Vec::new();
8177
let threads_running = Arc::new(atomic::AtomicUsize::new(0));

0 commit comments

Comments
 (0)