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
anymapdbg = ["serde_json"] # uses serde_json to Debug the anymap trait. Disable for smaller footprint.
derive = ["libafl_derive"] # provide derive(SerdeAny) macro.
llmp_small_maps = [] # reduces initial map size for llmp
[[example]]
name = "llmp_test"

View File

@ -8,14 +8,16 @@ use core::{convert::TryInto, time::Duration};
#[cfg(all(unix, feature = "std"))]
use std::{thread, time};
use libafl::bolts::llmp::Tag;
#[cfg(all(unix, feature = "std"))]
use libafl::{
bolts::{llmp, shmem::UnixShMem},
Error,
};
const _TAG_SIMPLE_U32_V1: u32 = 0x51300321;
const _TAG_MATH_RESULT_V1: u32 = 0x77474331;
const _TAG_SIMPLE_U32_V1: Tag = 0x51300321;
const _TAG_MATH_RESULT_V1: Tag = 0x77474331;
const _TAG_1MEG_V1: Tag = 0xB1111161;
#[cfg(all(unix, feature = "std"))]
fn adder_loop(port: u16) -> ! {
@ -35,7 +37,11 @@ fn adder_loop(port: u16) -> ! {
current_result =
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"))]
fn broker_message_hook(
client_id: u32,
@ -95,7 +114,7 @@ fn main() {
let mode = std::env::args()
.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()
.nth(2)
.unwrap_or("1337".into())
@ -128,6 +147,9 @@ fn main() {
"adder" => {
adder_loop(port);
}
"large" => {
large_msg_loop(port);
}
_ => {
println!("No valid mode supplied");
}

View File

@ -102,10 +102,14 @@ use crate::{
use super::shmem::HasFd;
/// 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
/// 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
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
}
/// allign to LLMP_PREF_ALIGNNMENT=64 bytes
/// allign to LLMP_CFG_ALIGNNMENT=64 bytes
#[inline]
const fn llmp_align(to_align: usize) -> usize {
// check if we need to align first
if LLMP_PREF_ALIGNNMENT == 0 {
if LLMP_CFG_ALIGNNMENT == 0 {
return to_align;
}
// Then do the alignment
let modulo = to_align % LLMP_PREF_ALIGNNMENT;
let modulo = to_align % LLMP_CFG_ALIGNNMENT;
if modulo == 0 {
to_align
} 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 {
max(
max_alloc * 2 + EOP_MSG_SIZE + LLMP_PAGE_HEADER_LEN,
LLMP_PREF_INITIAL_MAP_SIZE,
LLMP_CFG_INITIAL_MAP_SIZE,
)
.next_power_of_two()
}
@ -543,7 +547,7 @@ where
last_msg_sent: ptr::null_mut(),
out_maps: vec![LlmpSharedMap::new(
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
keep_pages_forever,
@ -573,7 +577,7 @@ where
pub fn to_env(&self, env_name: &str) -> Result<(), Error> {
let current_out_map = self.out_maps.last().unwrap();
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.
@ -930,7 +934,7 @@ where
pub fn to_env(&self, env_name: &str) -> Result<(), Error> {
let current_out_map = &self.current_recv_map;
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.
@ -1203,14 +1207,16 @@ where
/// Store this msg offset to env_name + _OFFSET env variable.
/// 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")]
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() {
env::set_var(&format!("{}_OFFSET", map_env_name), _NULL_ENV_STR)
} else {
env::set_var(
&format!("{}_OFFSET", map_env_name),
format!("{}", unsafe { self.msg_to_offset(msg) }?),
format!("{}", self.msg_to_offset(msg)?),
)
};
Ok(())
@ -1327,9 +1333,8 @@ where
msg.copy_to_nonoverlapping(out, size_of::<LlmpMsg>() + (*msg).buf_len_padded as usize);
(*out).buf_len_padded = actual_size;
/* We need to replace the message ID with our own */
match self.llmp_out.send(out) {
Err(e) => panic!("Error sending msg: {:?}", e),
_ => (),
if let Err(e) = self.llmp_out.send(out) {
panic!("Error sending msg: {:?}", e)
};
self.llmp_out.last_msg_sent = out;
Ok(())
@ -1433,7 +1438,7 @@ where
// Tcp out map sends messages from background thread tcp server to foreground client
let tcp_out_map = LlmpSharedMap::new(
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_size = tcp_out_map.shmem.map().len();
@ -1476,7 +1481,7 @@ where
(*msg).tag = LLMP_TAG_NEW_SHM_CLIENT;
let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
(*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) {
Ok(()) => (),
Err(e) => println!("Error forwarding client on map: {:?}", e),
@ -1492,10 +1497,12 @@ where
.to_string_lossy()
.into_owned()
.parse()
.expect(&format!(
"ShmId is not a valid int file descriptor: {:?}",
broadcast_str_initial
));
.unwrap_or_else(|_| {
panic!(
"ShmId is not a valid int file descriptor: {:?}",
broadcast_str_initial
)
});
match sendmsg(
stream.as_raw_fd(),
@ -1539,7 +1546,7 @@ where
let pageinfo =
(*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
(*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) {
Ok(()) => (),
Err(e) => {
@ -1750,7 +1757,7 @@ where
last_msg_sent: ptr::null_mut(),
out_maps: vec![LlmpSharedMap::new(
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
keep_pages_forever: false,
@ -1851,7 +1858,7 @@ where
let ret = Self::new(LlmpSharedMap::existing(SH::existing_from_shm_slice(
&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())?;
@ -1895,7 +1902,7 @@ where
let ret = Self::new(LlmpSharedMap::existing(SH::existing_from_shm_slice(
&fdstr,
LLMP_PREF_INITIAL_MAP_SIZE,
LLMP_CFG_INITIAL_MAP_SIZE,
)?))?;
match sendmsg(

View File

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