forked from nervosnetwork/ckb
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request nervosnetwork#4468 from joii2020/dev-fuzz-network
Add fuzz on network
- Loading branch information
Showing
10 changed files
with
443 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
target | ||
corpus | ||
artifacts | ||
coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
[package] | ||
name = "ckb-network-fuzz" | ||
version = "0.117.0-pre" | ||
publish = false | ||
edition = "2021" | ||
license = "MIT" | ||
description = "ckb network fuzz testing" | ||
homepage = "https://github.com/nervosnetwork/ckb" | ||
repository = "https://github.com/nervosnetwork/ckb" | ||
|
||
[package.metadata] | ||
cargo-fuzz = true | ||
|
||
[dependencies] | ||
libfuzzer-sys = "0.4" | ||
ipnetwork = "0.18" | ||
|
||
[dependencies.ckb-network] | ||
path = ".." | ||
features = ["fuzz"] | ||
|
||
# Prevent this from interfering with workspaces | ||
[workspace] | ||
members = ["."] | ||
|
||
[profile.release] | ||
debug = 1 | ||
|
||
[[bin]] | ||
name = "fuzz_compress" | ||
path = "fuzz_targets/fuzz_compress.rs" | ||
test = false | ||
doc = false | ||
|
||
[[bin]] | ||
name = "fuzz_decompress" | ||
path = "fuzz_targets/fuzz_decompress.rs" | ||
test = false | ||
doc = false | ||
|
||
[[bin]] | ||
name = "fuzz_addr_manager" | ||
path = "fuzz_targets/fuzz_addr_manager.rs" | ||
test = false | ||
doc = false | ||
|
||
[[bin]] | ||
name = "fuzz_peer_store" | ||
path = "fuzz_targets/fuzz_peer_store.rs" | ||
test = false | ||
doc = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#![no_main] | ||
|
||
use libfuzzer_sys::fuzz_target; | ||
|
||
use ckb_network::{ | ||
peer_store::{addr_manager::AddrManager, types::AddrInfo}, | ||
PeerId, | ||
}; | ||
|
||
use std::collections::HashSet; | ||
use std::net::Ipv4Addr; | ||
|
||
const ADDR_SIZE: usize = 4 + 32; // IPv4+Port+SHA256 | ||
|
||
fn new_addr(data: &[u8], index: usize) -> AddrInfo { | ||
let pos = 8 + index * ADDR_SIZE; | ||
let data = data[pos..pos + ADDR_SIZE].to_vec(); | ||
|
||
let ip = Ipv4Addr::from(u32::from_le_bytes(data[0..4].try_into().unwrap())); | ||
// let ip = Ipv4Addr::from(((225 << 24) + index) as u32); | ||
// let port = u16::from_le_bytes(data[4..6].try_into().unwrap()); | ||
let peer_id = | ||
PeerId::from_bytes(vec![vec![0x12], vec![0x20], data[4..].to_vec()].concat()).unwrap(); | ||
|
||
AddrInfo::new( | ||
format!("/ip4/{}/tcp/43/p2p/{}", ip, peer_id.to_base58()) | ||
.parse() | ||
.unwrap(), | ||
0, | ||
0, | ||
0, | ||
) | ||
} | ||
|
||
fn test_remove( | ||
mut addr_manager: AddrManager, | ||
basic: &HashSet<AddrInfo>, | ||
rm_num: usize, | ||
) -> AddrManager { | ||
let removed = addr_manager.fetch_random(rm_num, |_| true); | ||
// assert_eq!(removed.len(), rm_num.min(basic.len())); | ||
assert!(removed.len() <= rm_num.min(basic.len())); | ||
|
||
for addr in &removed { | ||
addr_manager.remove(&addr.addr); | ||
} | ||
assert!(addr_manager.count() <= (basic.len() - removed.len())); | ||
for addr in removed { | ||
addr_manager.add(addr); | ||
} | ||
assert!(addr_manager.count() <= basic.len()); | ||
|
||
addr_manager | ||
} | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
if data.len() < 8 + ADDR_SIZE { | ||
return; | ||
} | ||
if (data.len() - 8) % ADDR_SIZE != 0 { | ||
return; | ||
} | ||
let scale: u16 = u16::from_le_bytes(data[0..2].try_into().unwrap()) % 100; | ||
let (basic_len, added_len) = { | ||
let t = (data.len() - 8) / ADDR_SIZE; | ||
|
||
let b = (t as f32 / 100.0 * scale as f32) as usize; | ||
(b, t - b) | ||
}; | ||
let mut addr_manager = AddrManager::default(); | ||
|
||
let mut basic = HashSet::new(); | ||
for i in 0..basic_len { | ||
let addr = new_addr(data, i); | ||
basic.insert(addr.clone()); | ||
addr_manager.add(addr); | ||
} | ||
assert!(basic.len() >= addr_manager.count()); | ||
|
||
let removed_num1 = | ||
u16::from_le_bytes(data[2..4].try_into().unwrap()) as usize % (basic.len() + 8); | ||
let mut addr_manager = test_remove(addr_manager, &basic, removed_num1); | ||
|
||
let mut added = Vec::new(); | ||
for i in 0..added_len { | ||
let addr = new_addr(data, i + basic_len); | ||
added.push(addr.clone()); | ||
|
||
addr_manager.add(addr.clone()); | ||
basic.insert(addr); | ||
} | ||
assert!(basic.len() >= addr_manager.count()); | ||
|
||
let removed_num2 = | ||
u16::from_le_bytes(data[4..6].try_into().unwrap()) as usize % (basic.len() + 4); | ||
|
||
let mut _addr_manager = test_remove(addr_manager, &basic, removed_num2); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#![no_main] | ||
|
||
use libfuzzer_sys::fuzz_target; | ||
|
||
use ckb_network::bytes::{Bytes, BytesMut}; | ||
use ckb_network::compress::{compress, decompress}; | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
let raw_data = Bytes::from(data.to_vec()); | ||
|
||
let cmp_data = compress(raw_data.clone()); | ||
let demsg = decompress(BytesMut::from(cmp_data.as_ref())).unwrap(); | ||
assert_eq!(raw_data, demsg); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#![no_main] | ||
|
||
use libfuzzer_sys::fuzz_target; | ||
|
||
use ckb_network::bytes::{Bytes, BytesMut}; | ||
use ckb_network::compress::decompress; | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
let raw_data = Bytes::from(data.to_vec()); | ||
let _demsg = decompress(BytesMut::from(raw_data.as_ref())); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#![no_main] | ||
|
||
use libfuzzer_sys::fuzz_target; | ||
|
||
use ckb_network::{ | ||
multiaddr::MultiAddr, peer_store::types::BannedAddr, peer_store::PeerStore, Flags, PeerId, | ||
}; | ||
use ckb_network_fuzz::BufManager; | ||
|
||
fn new_multi_addr(data: &mut BufManager) -> (MultiAddr, Flags) { | ||
let flags = data.get(); | ||
let addr_flag = data.get::<u8>(); | ||
|
||
let mut addr_str = if addr_flag & 0b1 != 1 { | ||
let buf = data.get_buf(16); | ||
format!( | ||
"/ip6/{}", | ||
std::net::Ipv6Addr::from(u128::from_le_bytes(buf.try_into().unwrap())).to_string() | ||
) | ||
} else { | ||
format!("/ip4/{}", data.get::<std::net::Ipv4Addr>().to_string()) | ||
}; | ||
|
||
addr_str += &format!("/tcp/{}", data.get::<u16>()); | ||
|
||
addr_str += &format!("/p2p/{}", data.get::<ckb_network::PeerId>().to_base58()); | ||
|
||
(addr_str.parse().unwrap(), flags) | ||
} | ||
|
||
fn add_ban_addr(data: &mut BufManager, peer_store: &mut PeerStore) { | ||
let num = data.get::<u8>() as usize; | ||
for _ in 0..num { | ||
let flags = data.get::<u8>(); | ||
|
||
let network = if flags & 0b1 == 1 { | ||
data.get::<ipnetwork::Ipv4Network>().into() | ||
} else { | ||
data.get::<ipnetwork::Ipv6Network>().into() | ||
}; | ||
|
||
let ban_addr = BannedAddr { | ||
address: network, | ||
ban_until: data.get(), | ||
created_at: data.get(), | ||
ban_reason: String::new(), | ||
}; | ||
peer_store.mut_ban_list().ban(ban_addr); | ||
} | ||
} | ||
|
||
fn add_basic_addr(data: &mut BufManager, peer_store: &mut PeerStore) { | ||
let flags = data.get::<u32>(); | ||
if flags & 0b1 == 0 { | ||
return; | ||
} | ||
|
||
if (flags >> 1) & 0b1 == 1 { | ||
add_ban_addr(data, peer_store); | ||
} | ||
|
||
let basic_num = data.get::<u32>(); | ||
|
||
let num = basic_num % 16 + (16384) - 8; // ±8 | ||
|
||
for i in 0..num { | ||
let addr = format!( | ||
"/ip4/{}/tcp/43/p2p/{}", | ||
std::net::Ipv4Addr::from(i as u32).to_string(), | ||
PeerId::random().to_base58() | ||
) | ||
.parse() | ||
.unwrap(); | ||
let _ = peer_store.add_addr_fuzz(addr, Flags::all(), data.get(), data.get()); | ||
} | ||
} | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
let mut data = BufManager::new(data); | ||
|
||
let mut peer_store: PeerStore = Default::default(); | ||
|
||
// basic addr: | ||
add_basic_addr(&mut data, &mut peer_store); | ||
|
||
let fetch_count = data.get::<u16>() as usize; | ||
let fetch_flag = data.get(); | ||
|
||
while !data.is_end() { | ||
let (addr, flag) = new_multi_addr(&mut data); | ||
let last_connected_time = data.get(); | ||
let attempts_count = data.get::<u32>(); | ||
let _res = peer_store.add_addr_fuzz(addr, flag, last_connected_time, attempts_count); | ||
// _res.expect("msg"); | ||
} | ||
|
||
let ret = peer_store.fetch_random_addrs(fetch_count, fetch_flag); | ||
assert!(ret.len() <= fetch_count); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
nightly |
Oops, something went wrong.