diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index c4ed4c703..dbdb69d2e 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -13,6 +13,7 @@ cargo-fuzz = true [features] afl_fuzz = ["afl"] honggfuzz_fuzz = ["honggfuzz"] +libfuzzer_fuzz = ["libfuzzer-sys"] [dependencies] afl = { version = "0.4", optional = true } @@ -22,6 +23,7 @@ bitcoin_hashes = { git = "https://github.com/TheBlueMatt/bitcoin_hashes", branch hex = "0.3" honggfuzz = { version = "0.5", optional = true } secp256k1 = { version = "0.11", features=["fuzztarget"] } +libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git", optional = true } [build-dependencies] cc = "1.0" diff --git a/fuzz/fuzz_targets/full_stack_target.rs b/fuzz/fuzz_targets/full_stack_target.rs index 21acf2777..67146634e 100644 --- a/fuzz/fuzz_targets/full_stack_target.rs +++ b/fuzz/fuzz_targets/full_stack_target.rs @@ -1,3 +1,12 @@ +//! Test that no series of bytes received over the wire/connections created/payments sent can +//! result in a crash. We do this by standing up a node and then reading bytes from input to denote +//! actions such as creating new inbound/outbound connections, bytes to be read from a connection, +//! or payments to send/ways to handle events generated. +//! This test has been very useful, though due to its complexity good starting inputs are critical. + +//Uncomment this for libfuzzer builds: +//#![no_main] + extern crate bitcoin; extern crate bitcoin_hashes; extern crate lightning; @@ -9,11 +18,12 @@ use bitcoin::blockdata::script::{Builder, Script}; use bitcoin::blockdata::opcodes; use bitcoin::consensus::encode::deserialize; use bitcoin::network::constants::Network; -use bitcoin::util::hash::{BitcoinHash, Sha256dHash, Hash160}; +use bitcoin::util::hash::{BitcoinHash, Sha256dHash}; use bitcoin_hashes::Hash as TraitImport; use bitcoin_hashes::HashEngine as TraitImportEngine; use bitcoin_hashes::sha256::Hash as Sha256; +use bitcoin_hashes::hash160::Hash as Hash160; use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,ChainListener,FeeEstimator,ChainWatchInterfaceUtil}; use lightning::chain::transaction::OutPoint; @@ -235,7 +245,7 @@ impl KeysInterface for KeyProvider { fn get_destination_script(&self) -> Script { let secp_ctx = Secp256k1::signing_only(); let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &hex::decode("0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap()[..]).unwrap(); - let our_channel_monitor_claim_key_hash = Hash160::from_data(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); + let our_channel_monitor_claim_key_hash = Hash160::hash(&PublicKey::from_secret_key(&secp_ctx, &channel_monitor_claim_key).serialize()); Builder::new().push_opcode(opcodes::All::OP_PUSHBYTES_0).push_slice(&our_channel_monitor_claim_key_hash[..]).into_script() } @@ -540,6 +550,14 @@ fn main() { } } +#[cfg(feature = "libfuzzer_fuzz")] +#[macro_use] extern crate libfuzzer_sys; +#[cfg(feature = "libfuzzer_fuzz")] +fuzz_target!(|data: &[u8]| { + let logger: Arc = Arc::new(test_logger::TestLogger{}); + do_test(data, &logger); +}); + extern crate hex; #[cfg(test)] mod tests { diff --git a/src/util/byte_utils.rs b/src/util/byte_utils.rs index 7230a4e1c..44445666f 100644 --- a/src/util/byte_utils.rs +++ b/src/util/byte_utils.rs @@ -10,6 +10,7 @@ pub fn slice_to_be32(v: &[u8]) -> u32 { ((v[2] as u32) << 8*1) | ((v[3] as u32) << 8*0) } +#[cfg(not(feature = "fuzztarget"))] // Used only by poly1305 #[inline] pub fn slice_to_le32(v: &[u8]) -> u32 { ((v[0] as u32) << 8*0) | @@ -54,6 +55,7 @@ pub fn be32_to_array(u: u32) -> [u8; 4] { v[3] = ((u >> 8*0) & 0xff) as u8; v } +#[cfg(not(feature = "fuzztarget"))] // Used only by poly1305 #[inline] pub fn le32_to_array(u: u32) -> [u8; 4] { let mut v = [0; 4]; diff --git a/src/util/mod.rs b/src/util/mod.rs index 1a6eb8049..c1b6c2300 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -6,6 +6,7 @@ pub mod ser; pub(crate) mod byte_utils; pub(crate) mod chacha20; +#[cfg(not(feature = "fuzztarget"))] pub(crate) mod poly1305; pub(crate) mod chacha20poly1305rfc; pub(crate) mod internal_traits;