debugging llmp

This commit is contained in:
Dominik Maier 2021-03-14 19:58:04 +01:00
parent 73ceb928ae
commit b33cb5d721
4 changed files with 60 additions and 30 deletions

View File

@ -35,6 +35,7 @@ std = [] # print, sharedmap, ... support
runtime = [] # a runtime for clang inmem-executor runtime = [] # a runtime for clang inmem-executor
anymapdbg = ["serde_json"] # uses serde_json to Debug the anymap trait. Disable for smaller footprint. anymapdbg = ["serde_json"] # uses serde_json to Debug the anymap trait. Disable for smaller footprint.
derive = ["libafl_derive"] # provide derive(SerdeAny) macro. derive = ["libafl_derive"] # provide derive(SerdeAny) macro.
llmp_small_maps = [] # reduces initial map size for llmp
[[example]] [[example]]
name = "llmp_test" name = "llmp_test"

View File

@ -8,14 +8,16 @@ use core::{convert::TryInto, time::Duration};
#[cfg(all(unix, feature = "std"))] #[cfg(all(unix, feature = "std"))]
use std::{thread, time}; use std::{thread, time};
use libafl::bolts::llmp::Tag;
#[cfg(all(unix, feature = "std"))] #[cfg(all(unix, feature = "std"))]
use libafl::{ use libafl::{
bolts::{llmp, shmem::UnixShMem}, bolts::{llmp, shmem::UnixShMem},
Error, Error,
}; };
const _TAG_SIMPLE_U32_V1: u32 = 0x51300321; const _TAG_SIMPLE_U32_V1: Tag = 0x51300321;
const _TAG_MATH_RESULT_V1: u32 = 0x77474331; const _TAG_MATH_RESULT_V1: Tag = 0x77474331;
const _TAG_1MEG_V1: Tag = 0xB1111161;
#[cfg(all(unix, feature = "std"))] #[cfg(all(unix, feature = "std"))]
fn adder_loop(port: u16) -> ! { fn adder_loop(port: u16) -> ! {
@ -35,7 +37,11 @@ fn adder_loop(port: u16) -> ! {
current_result = current_result =
current_result.wrapping_add(u32::from_le_bytes(buf.try_into().unwrap())); current_result.wrapping_add(u32::from_le_bytes(buf.try_into().unwrap()));
} }
_ => println!("Adder Client ignored unknown message {}", tag), _ => println!(
"Adder Client ignored unknown message {} with {} bytes",
tag,
buf.len()
),
}; };
} }
@ -55,6 +61,19 @@ fn adder_loop(port: u16) -> ! {
} }
} }
#[cfg(all(unix, feature = "std"))]
fn large_msg_loop(port: u16) -> ! {
let mut client = llmp::LlmpClient::<UnixShMem>::create_attach_to_tcp(port).unwrap();
let meg_buf = [1u8; 1 << 20];
loop {
client.send_buf(_TAG_1MEG_V1, &meg_buf).unwrap();
println!("Sending the next megabyte");
thread::sleep(time::Duration::from_millis(100))
}
}
#[cfg(all(unix, feature = "std"))] #[cfg(all(unix, feature = "std"))]
fn broker_message_hook( fn broker_message_hook(
client_id: u32, client_id: u32,
@ -95,7 +114,7 @@ fn main() {
let mode = std::env::args() let mode = std::env::args()
.nth(1) .nth(1)
.expect("no mode specified, chose 'broker', 'ctr', or 'adder'"); .expect("no mode specified, chose 'broker', 'ctr', 'adder', or 'large'");
let port: u16 = std::env::args() let port: u16 = std::env::args()
.nth(2) .nth(2)
.unwrap_or("1337".into()) .unwrap_or("1337".into())
@ -128,6 +147,9 @@ fn main() {
"adder" => { "adder" => {
adder_loop(port); adder_loop(port);
} }
"large" => {
large_msg_loop(port);
}
_ => { _ => {
println!("No valid mode supplied"); println!("No valid mode supplied");
} }

View File

@ -102,10 +102,14 @@ use crate::{
use super::shmem::HasFd; use super::shmem::HasFd;
/// We'll start off with 256 megabyte maps per fuzzer client /// We'll start off with 256 megabyte maps per fuzzer client
const LLMP_PREF_INITIAL_MAP_SIZE: usize = 1 << 28; #[cfg(not(feature = "llmp_small_maps"))]
const LLMP_CFG_INITIAL_MAP_SIZE: usize = 1 << 28;
/// If llmp_small_maps is set, we start off with 1 meg.
#[cfg(feature = "llmp_small_maps")]
const LLMP_CFG_INITIAL_MAP_SIZE: usize = 1 << 20;
/// What byte count to align messages to /// What byte count to align messages to
/// LlmpMsg sizes (including header) will always be rounded up to be a multiple of this value /// LlmpMsg sizes (including header) will always be rounded up to be a multiple of this value
const LLMP_PREF_ALIGNNMENT: usize = 64; const LLMP_CFG_ALIGNNMENT: usize = 64;
/// A msg fresh from the press: No tag got sent by the user yet /// A msg fresh from the press: No tag got sent by the user yet
const LLMP_TAG_UNSET: Tag = 0xDEADAF; const LLMP_TAG_UNSET: Tag = 0xDEADAF;
@ -199,19 +203,19 @@ unsafe fn llmp_msg_in_page(page: *const LlmpPage, msg: *const LlmpMsg) -> bool {
&& (page as *const u8).add((*page).size_total) > msg as *const u8 && (page as *const u8).add((*page).size_total) > msg as *const u8
} }
/// allign to LLMP_PREF_ALIGNNMENT=64 bytes /// allign to LLMP_CFG_ALIGNNMENT=64 bytes
#[inline] #[inline]
const fn llmp_align(to_align: usize) -> usize { const fn llmp_align(to_align: usize) -> usize {
// check if we need to align first // check if we need to align first
if LLMP_PREF_ALIGNNMENT == 0 { if LLMP_CFG_ALIGNNMENT == 0 {
return to_align; return to_align;
} }
// Then do the alignment // Then do the alignment
let modulo = to_align % LLMP_PREF_ALIGNNMENT; let modulo = to_align % LLMP_CFG_ALIGNNMENT;
if modulo == 0 { if modulo == 0 {
to_align to_align
} else { } else {
to_align + LLMP_PREF_ALIGNNMENT - modulo to_align + LLMP_CFG_ALIGNNMENT - modulo
} }
} }
@ -235,7 +239,7 @@ fn msg_offset_from_env(env_name: &str) -> Result<Option<u64>, Error> {
fn new_map_size(max_alloc: usize) -> usize { fn new_map_size(max_alloc: usize) -> usize {
max( max(
max_alloc * 2 + EOP_MSG_SIZE + LLMP_PAGE_HEADER_LEN, max_alloc * 2 + EOP_MSG_SIZE + LLMP_PAGE_HEADER_LEN,
LLMP_PREF_INITIAL_MAP_SIZE, LLMP_CFG_INITIAL_MAP_SIZE,
) )
.next_power_of_two() .next_power_of_two()
} }
@ -543,7 +547,7 @@ where
last_msg_sent: ptr::null_mut(), last_msg_sent: ptr::null_mut(),
out_maps: vec![LlmpSharedMap::new( out_maps: vec![LlmpSharedMap::new(
0, 0,
SH::new_map(new_map_size(LLMP_PREF_INITIAL_MAP_SIZE))?, SH::new_map(new_map_size(LLMP_CFG_INITIAL_MAP_SIZE))?,
)], )],
// drop pages to the broker if it already read them // drop pages to the broker if it already read them
keep_pages_forever, keep_pages_forever,
@ -573,7 +577,7 @@ where
pub fn to_env(&self, env_name: &str) -> Result<(), Error> { pub fn to_env(&self, env_name: &str) -> Result<(), Error> {
let current_out_map = self.out_maps.last().unwrap(); let current_out_map = self.out_maps.last().unwrap();
current_out_map.shmem.write_to_env(env_name)?; current_out_map.shmem.write_to_env(env_name)?;
current_out_map.msg_to_env(self.last_msg_sent, env_name) unsafe { current_out_map.msg_to_env(self.last_msg_sent, env_name) }
} }
/// Waits for this sender to be save to unmap. /// Waits for this sender to be save to unmap.
@ -930,7 +934,7 @@ where
pub fn to_env(&self, env_name: &str) -> Result<(), Error> { pub fn to_env(&self, env_name: &str) -> Result<(), Error> {
let current_out_map = &self.current_recv_map; let current_out_map = &self.current_recv_map;
current_out_map.shmem.write_to_env(env_name)?; current_out_map.shmem.write_to_env(env_name)?;
current_out_map.msg_to_env(self.last_msg_recvd, env_name) unsafe { current_out_map.msg_to_env(self.last_msg_recvd, env_name) }
} }
/// Create a Receiver, reattaching to an existing sender map. /// Create a Receiver, reattaching to an existing sender map.
@ -1203,14 +1207,16 @@ where
/// Store this msg offset to env_name + _OFFSET env variable. /// Store this msg offset to env_name + _OFFSET env variable.
/// It can be restored using msg_from_env with the same env_name later. /// It can be restored using msg_from_env with the same env_name later.
/// # Safety
/// This function will dereference the msg ptr, make sure it's valid.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn msg_to_env(&self, msg: *const LlmpMsg, map_env_name: &str) -> Result<(), Error> { pub unsafe fn msg_to_env(&self, msg: *const LlmpMsg, map_env_name: &str) -> Result<(), Error> {
if msg.is_null() { if msg.is_null() {
env::set_var(&format!("{}_OFFSET", map_env_name), _NULL_ENV_STR) env::set_var(&format!("{}_OFFSET", map_env_name), _NULL_ENV_STR)
} else { } else {
env::set_var( env::set_var(
&format!("{}_OFFSET", map_env_name), &format!("{}_OFFSET", map_env_name),
format!("{}", unsafe { self.msg_to_offset(msg) }?), format!("{}", self.msg_to_offset(msg)?),
) )
}; };
Ok(()) Ok(())
@ -1327,9 +1333,8 @@ where
msg.copy_to_nonoverlapping(out, size_of::<LlmpMsg>() + (*msg).buf_len_padded as usize); msg.copy_to_nonoverlapping(out, size_of::<LlmpMsg>() + (*msg).buf_len_padded as usize);
(*out).buf_len_padded = actual_size; (*out).buf_len_padded = actual_size;
/* We need to replace the message ID with our own */ /* We need to replace the message ID with our own */
match self.llmp_out.send(out) { if let Err(e) = self.llmp_out.send(out) {
Err(e) => panic!("Error sending msg: {:?}", e), panic!("Error sending msg: {:?}", e)
_ => (),
}; };
self.llmp_out.last_msg_sent = out; self.llmp_out.last_msg_sent = out;
Ok(()) Ok(())
@ -1433,7 +1438,7 @@ where
// Tcp out map sends messages from background thread tcp server to foreground client // Tcp out map sends messages from background thread tcp server to foreground client
let tcp_out_map = LlmpSharedMap::new( let tcp_out_map = LlmpSharedMap::new(
llmp_tcp_id, llmp_tcp_id,
SH::new_map(new_map_size(LLMP_PREF_INITIAL_MAP_SIZE))?, SH::new_map(new_map_size(LLMP_CFG_INITIAL_MAP_SIZE))?,
); );
let tcp_out_map_str = tcp_out_map.shmem.shm_str(); let tcp_out_map_str = tcp_out_map.shmem.shm_str();
let tcp_out_map_size = tcp_out_map.shmem.map().len(); let tcp_out_map_size = tcp_out_map.shmem.map().len();
@ -1476,7 +1481,7 @@ where
(*msg).tag = LLMP_TAG_NEW_SHM_CLIENT; (*msg).tag = LLMP_TAG_NEW_SHM_CLIENT;
let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo; let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
(*pageinfo).shm_str = new_client_map_str; (*pageinfo).shm_str = new_client_map_str;
(*pageinfo).map_size = LLMP_PREF_INITIAL_MAP_SIZE; (*pageinfo).map_size = LLMP_CFG_INITIAL_MAP_SIZE;
match new_client_sender.send(msg) { match new_client_sender.send(msg) {
Ok(()) => (), Ok(()) => (),
Err(e) => println!("Error forwarding client on map: {:?}", e), Err(e) => println!("Error forwarding client on map: {:?}", e),
@ -1492,10 +1497,12 @@ where
.to_string_lossy() .to_string_lossy()
.into_owned() .into_owned()
.parse() .parse()
.expect(&format!( .unwrap_or_else(|_| {
"ShmId is not a valid int file descriptor: {:?}", panic!(
broadcast_str_initial "ShmId is not a valid int file descriptor: {:?}",
)); broadcast_str_initial
)
});
match sendmsg( match sendmsg(
stream.as_raw_fd(), stream.as_raw_fd(),
@ -1539,7 +1546,7 @@ where
let pageinfo = let pageinfo =
(*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo; (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
(*pageinfo).shm_str = fdstr; (*pageinfo).shm_str = fdstr;
(*pageinfo).map_size = LLMP_PREF_INITIAL_MAP_SIZE; (*pageinfo).map_size = LLMP_CFG_INITIAL_MAP_SIZE;
match new_client_sender.send(msg) { match new_client_sender.send(msg) {
Ok(()) => (), Ok(()) => (),
Err(e) => { Err(e) => {
@ -1750,7 +1757,7 @@ where
last_msg_sent: ptr::null_mut(), last_msg_sent: ptr::null_mut(),
out_maps: vec![LlmpSharedMap::new( out_maps: vec![LlmpSharedMap::new(
0, 0,
SH::new_map(new_map_size(LLMP_PREF_INITIAL_MAP_SIZE))?, SH::new_map(new_map_size(LLMP_CFG_INITIAL_MAP_SIZE))?,
)], )],
// drop pages to the broker if it already read them // drop pages to the broker if it already read them
keep_pages_forever: false, keep_pages_forever: false,
@ -1851,7 +1858,7 @@ where
let ret = Self::new(LlmpSharedMap::existing(SH::existing_from_shm_slice( let ret = Self::new(LlmpSharedMap::existing(SH::existing_from_shm_slice(
&new_broker_map_str, &new_broker_map_str,
LLMP_PREF_INITIAL_MAP_SIZE, LLMP_CFG_INITIAL_MAP_SIZE,
)?))?; )?))?;
stream.write_all(ret.sender.out_maps.first().unwrap().shmem.shm_slice())?; stream.write_all(ret.sender.out_maps.first().unwrap().shmem.shm_slice())?;
@ -1895,7 +1902,7 @@ where
let ret = Self::new(LlmpSharedMap::existing(SH::existing_from_shm_slice( let ret = Self::new(LlmpSharedMap::existing(SH::existing_from_shm_slice(
&fdstr, &fdstr,
LLMP_PREF_INITIAL_MAP_SIZE, LLMP_CFG_INITIAL_MAP_SIZE,
)?))?; )?))?;
match sendmsg( match sendmsg(

View File

@ -22,7 +22,7 @@ use crate::Error;
pub use libc::{c_void, siginfo_t}; pub use libc::{c_void, siginfo_t};
#[derive(IntoPrimitive, TryFromPrimitive, Hash, Clone, Copy)] #[derive(IntoPrimitive, TryFromPrimitive, Clone, Copy)]
#[repr(i32)] #[repr(i32)]
pub enum Signal { pub enum Signal {
SigAbort = SIGABRT, SigAbort = SIGABRT,