Skip to content

Commit

Permalink
Sender id fix (#610)
Browse files Browse the repository at this point in the history
* Starting to fix id issues

* add crashing testcase

* remove debug flags
  • Loading branch information
domenukk authored Apr 15, 2022
1 parent a99d0b2 commit 1690dbb
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 17 deletions.
2 changes: 2 additions & 0 deletions fuzzers/libfuzzer_libpng/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ edition = "2021"
[features]
default = ["std"]
std = []
# Forces a crash
crash = []

[profile.release]
lto = true
Expand Down
61 changes: 61 additions & 0 deletions fuzzers/libfuzzer_libpng/Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,24 @@ windows_alias = "unsupported"
command = "cargo"
args = ["build" , "--release"]

[tasks.crash_cxx]
linux_alias = "crash_cxx_unix"
mac_alias = "crash_cxx_unix"
windows_alias = "unsupported"

[tasks.crash_cxx_unix]
command = "cargo"
args = ["build" , "--release", "--features=crash"]

[tasks.crash_cc]
linux_alias = "crash_cc_unix"
mac_alias = "crash_cc_unix"
windows_alias = "unsupported"

[tasks.crash_cc_unix]
command = "cargo"
args = ["build" , "--release", "--features=crash"]

# Library
[tasks.lib]
linux_alias = "lib_unix"
Expand All @@ -60,6 +78,20 @@ make -C libpng-1.6.37 CC="${PROJECT_DIR}/target/release/libafl_cc" CXX="${PROJEC
'''
dependencies = [ "libpng", "cxx", "cc" ]

# Library
[tasks.crash_lib]
linux_alias = "crash_lib_unix"
mac_alias = "crash_lib_unix"
windows_alias = "unsupported"

[tasks.crash_lib_unix]
script_runner="@shell"
script='''
cd libpng-1.6.37 && ./configure --enable-shared=no --with-pic=yes --enable-hardware-optimizations=yes
cd "${PROJECT_DIR}"
make -C libpng-1.6.37 CC="${PROJECT_DIR}/target/release/libafl_cc" CXX="${PROJECT_DIR}/target/release/libafl_cxx"
'''
dependencies = [ "libpng", "crash_cxx", "crash_cc" ]

# Harness
[tasks.fuzzer]
Expand All @@ -72,6 +104,17 @@ command = "target/release/libafl_cxx"
args = ["${PROJECT_DIR}/harness.cc", "${PROJECT_DIR}/libpng-1.6.37/.libs/libpng16.a", "-I", "${PROJECT_DIR}/libpng-1.6.37/", "-o", "${FUZZER_NAME}", "-lm", "-lz"]
dependencies = [ "lib", "cxx", "cc" ]

# Crashing Harness
[tasks.fuzzer_crash]
linux_alias = "fuzzer_crash_unix"
mac_alias = "fuzzer_crash_unix"
windows_alias = "unsupported"

[tasks.fuzzer_crash_unix]
command = "target/release/libafl_cxx"
args = ["${PROJECT_DIR}/harness.cc", "${PROJECT_DIR}/libpng-1.6.37/.libs/libpng16.a", "-I", "${PROJECT_DIR}/libpng-1.6.37/", "-o", "${FUZZER_NAME}_crash", "-lm", "-lz"]
dependencies = [ "crash_lib", "crash_cxx", "crash_cc" ]

# Run the fuzzer
[tasks.run]
linux_alias = "run_unix"
Expand All @@ -87,6 +130,24 @@ sleep 0.2
'''
dependencies = [ "fuzzer" ]


# Run the fuzzer with a crash
[tasks.crash]
linux_alias = "crash_unix"
mac_alias = "crash_unix"
windows_alias = "unsupported"

[tasks.crash_unix]
script_runner = "@shell"
script='''
./${FUZZER_NAME}_crash &
sleep 0.2
./${FUZZER_NAME}_crash 2>/dev/null
'''
dependencies = [ "fuzzer_crash" ]



# Test
[tasks.test]
linux_alias = "test_unix"
Expand Down
10 changes: 10 additions & 0 deletions fuzzers/libfuzzer_libpng/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use mimalloc::MiMalloc;
static GLOBAL: MiMalloc = MiMalloc;

use core::time::Duration;
#[cfg(feature = "crash")]
use std::ptr;
use std::{env, path::PathBuf};

use libafl::{
Expand Down Expand Up @@ -145,6 +147,14 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
#[cfg(feature = "crash")]
if buf.len() > 4 && buf[4] == 0 {
unsafe {
eprintln!("Crashing (for testing purposes)");
let addr = ptr::null_mut();
*addr = 1;
}
}
libfuzzer_test_one_input(buf);
ExitKind::Ok
};
Expand Down
36 changes: 22 additions & 14 deletions libafl/src/bolts/llmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ fn next_shmem_size(max_alloc: usize) -> usize {

/// Initialize a new `llmp_page`. The size should be relative to
/// `llmp_page->messages`
unsafe fn _llmp_page_init<SHM: ShMem>(shmem: &mut SHM, sender: u32, allow_reinit: bool) {
unsafe fn _llmp_page_init<SHM: ShMem>(shmem: &mut SHM, sender_id: ClientId, allow_reinit: bool) {
#[cfg(all(feature = "llmp_debug", feature = "std"))]
println!("_llmp_page_init: shmem {:?}", &shmem);
let map_size = shmem.len();
Expand All @@ -469,7 +469,7 @@ unsafe fn _llmp_page_init<SHM: ShMem>(shmem: &mut SHM, sender: u32, allow_reinit
}

(*page).magic = PAGE_INITIALIZED_MAGIC;
(*page).sender = sender;
(*page).sender_id = sender_id;
(*page).current_msg_id.store(0, Ordering::Relaxed);
(*page).max_alloc_size = 0;
// Don't forget to subtract our own header size
Expand Down Expand Up @@ -707,7 +707,7 @@ pub struct LlmpPage {
/// to check if this page got initialized properly
pub magic: u64,
/// The id of the sender
pub sender: u32,
pub sender_id: ClientId,
/// Set to != 1 by the receiver, once it got mapped.
/// It's not safe for the sender to unmap this page before
/// (The os may have tidied up the memory when the receiver starts to map)
Expand Down Expand Up @@ -750,7 +750,7 @@ where
SP: ShMemProvider,
{
/// ID of this sender.
pub id: u32,
pub id: ClientId,
/// Ref to the last message this sender sent on the last page.
/// If null, a new page (just) started.
pub last_msg_sent: *const LlmpMsg,
Expand All @@ -775,12 +775,16 @@ where
/// Create a new [`LlmpSender`] using a given [`ShMemProvider`], and `id`.
/// If `keep_pages_forever` is `true`, `ShMem` will never be freed.
/// If it is `false`, the pages will be unmapped once they are full, and have been mapped by at least one `LlmpReceiver`.
pub fn new(mut shmem_provider: SP, id: u32, keep_pages_forever: bool) -> Result<Self, Error> {
pub fn new(
mut shmem_provider: SP,
id: ClientId,
keep_pages_forever: bool,
) -> Result<Self, Error> {
Ok(Self {
id,
last_msg_sent: ptr::null_mut(),
out_shmems: vec![LlmpSharedMap::new(
0,
id,
shmem_provider.new_shmem(LLMP_CFG_INITIAL_MAP_SIZE)?,
)],
// drop pages to the broker if it already read them
Expand All @@ -795,6 +799,7 @@ where
/// This is only useful if all connected llmp parties start over, for example after a crash.
/// # Safety
/// Only safe if you really really restart the page on everything connected
/// No receiver should read from this page at a different location.
pub unsafe fn reset(&mut self) {
_llmp_page_init(
&mut self.out_shmems.last_mut().unwrap().shmem,
Expand Down Expand Up @@ -903,7 +908,7 @@ where
};

Ok(Self {
id: 0,
id: unsafe { (*out_shmem.page()).sender_id },
last_msg_sent,
out_shmems: vec![out_shmem],
// drop pages to the broker if it already read them
Expand Down Expand Up @@ -1117,7 +1122,7 @@ where

// Create a new shard page.
let mut new_map_shmem = LlmpSharedMap::new(
(*old_map).sender,
(*old_map).sender_id,
self.shmem_provider
.new_shmem(next_shmem_size((*old_map).max_alloc_size))?,
);
Expand All @@ -1135,7 +1140,6 @@ where
println!("Setting max alloc size: {:?}", (*old_map).max_alloc_size);

(*new_map).max_alloc_size = (*old_map).max_alloc_size;
(*new_map).sender = self.id;

/* On the old map, place a last message linking to the new map for the clients
* to consume */
Expand Down Expand Up @@ -2536,12 +2540,13 @@ where
pub fn new(
mut shmem_provider: SP,
initial_broker_shmem: LlmpSharedMap<SP::ShMem>,
sender_id: ClientId,
) -> Result<Self, Error> {
Ok(Self {
sender: LlmpSender {
id: 0,
id: sender_id,
last_msg_sent: ptr::null_mut(),
out_shmems: vec![LlmpSharedMap::new(0, {
out_shmems: vec![LlmpSharedMap::new(sender_id, {
shmem_provider.new_shmem(LLMP_CFG_INITIAL_MAP_SIZE)?
})],
// drop pages to the broker if it already read them
Expand Down Expand Up @@ -2647,7 +2652,8 @@ where
/// Creates a new [`LlmpClient`], reading the map id and len from env
pub fn create_using_env(mut shmem_provider: SP, env_var: &str) -> Result<Self, Error> {
let map = LlmpSharedMap::existing(shmem_provider.existing_from_env(env_var)?);
Self::new(shmem_provider, map)
let client_id = unsafe { (*map.page()).sender_id };
Self::new(shmem_provider, map, client_id)
}

#[cfg(feature = "std")]
Expand Down Expand Up @@ -2689,7 +2695,9 @@ where
let map = LlmpSharedMap::existing(
shmem_provider.shmem_from_description(broker_shmem_description)?,
);
let mut ret = Self::new(shmem_provider, map)?;

// We'll set `sender_id` later
let mut ret = Self::new(shmem_provider, map, 0)?;

let client_hello_req = TcpRequest::LocalClientHello {
shmem_description: ret.sender.out_shmems.first().unwrap().shmem.description(),
Expand All @@ -2712,7 +2720,7 @@ where
ret.sender.id = client_id;
// Also set the sender on our initial llmp map correctly.
unsafe {
(*ret.sender.out_shmems.first_mut().unwrap().page_mut()).sender = client_id;
(*ret.sender.out_shmems.first_mut().unwrap().page_mut()).sender_id = client_id;
}

Ok(ret)
Expand Down
3 changes: 2 additions & 1 deletion libafl/src/events/llmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ where
let mut ctr: u64 = 0;
// Client->parent loop
loop {
dbg!("Spawning next client (id {})", ctr);
println!("Spawning next client (id {})", ctr);

// On Unix, we fork
#[cfg(all(unix, feature = "fork"))]
Expand Down Expand Up @@ -975,6 +975,7 @@ mod tests {
let mut llmp_client = LlmpClient::new(
shmem_provider.clone(),
LlmpSharedMap::new(0, shmem_provider.new_shmem(1024).unwrap()),
0,
)
.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion libafl/src/events/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ where
let mut ctr: u64 = 0;
// Client->parent loop
loop {
dbg!("Spawning next client (id {})", ctr);
println!("Spawning next client (id {})", ctr);

// On Unix, we fork
#[cfg(all(unix, feature = "fork"))]
Expand Down
1 change: 0 additions & 1 deletion libafl/src/monitors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,6 @@ pub mod pybind {
self.get_mut_monitor().display(event_msg, sender_id);
}
}

/// Register the classes to the python module
pub fn register(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<PythonSimpleMonitor>()?;
Expand Down

0 comments on commit 1690dbb

Please sign in to comment.