diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 00000000..572e03bd --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,4 @@ + +target +corpus +artifacts diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 00000000..4a9439ff --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,22 @@ + +[package] +name = "bitcoin-fuzz" +version = "0.0.1" +authors = ["Automatically generated"] +publish = false + +[package.metadata] +cargo-fuzz = true + +[dependencies.bitcoin] +path = ".." +[dependencies.libfuzzer-sys] +git = "https://github.com/rust-fuzz/libfuzzer-sys.git" + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "fuzzer_script_1" +path = "fuzzers/fuzzer_script_1.rs" diff --git a/fuzz/fuzzers/fuzzer_script_1.rs b/fuzz/fuzzers/fuzzer_script_1.rs new file mode 100644 index 00000000..d99c60cb --- /dev/null +++ b/fuzz/fuzzers/fuzzer_script_1.rs @@ -0,0 +1,13 @@ +#![no_main] +#[macro_use] extern crate libfuzzer_sys; +extern crate bitcoin; + +type BResult = Result; +//type BResult = Result; +//type BResult = Result; +//type BResult = Result; +//type BResult = Result; + +fuzz_target!(|data: &[u8]| { + let _: BResult = bitcoin::network::serialize::deserialize(data); +}); diff --git a/src/network/encodable.rs b/src/network/encodable.rs index 8f1c4df4..689a09d2 100644 --- a/src/network/encodable.rs +++ b/src/network/encodable.rs @@ -188,7 +188,9 @@ impl> ConsensusDecodable for Vec Result, D::Error> { let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); - let byte_size = len as usize * mem::size_of::(); + let byte_size = try!((len as usize) + .checked_mul(mem::size_of::()) + .ok_or(d.error("Invalid length".to_owned()))); if byte_size > MAX_VEC_SIZE { return Err(d.error(format!("tried to allocate vec of size {} (max {})", byte_size, MAX_VEC_SIZE))); } @@ -208,6 +210,9 @@ impl> ConsensusDecodable for Box<[ fn consensus_decode(d: &mut D) -> Result, D::Error> { let VarInt(len): VarInt = try!(ConsensusDecodable::consensus_decode(d)); let len = len as usize; + if len > MAX_VEC_SIZE { + return Err(d.error(format!("tried to allocate vec of size {} (max {})", len, MAX_VEC_SIZE))); + } let mut ret = Vec::with_capacity(len); for _ in 0..len { ret.push(try!(ConsensusDecodable::consensus_decode(d))); } Ok(ret.into_boxed_slice())