Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed Forkserver shmem input length, made it configurable #1342

Merged
merged 6 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions fuzzers/libfuzzer_libpng_launcher/Makefile.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Variables
[env]
FUZZER_NAME='fuzzer_libpng_launcher'
CARGO_TARGET_DIR = { value = "${PROJECT_DIR}/target", condition = { env_not_set = ["CARGO_TARGET_DIR"] } }
CARGO_TARGET_DIR = { value = "${PROJECT_DIR}/target/x86_64-unknown-linux-gnu", condition = { env_not_set = ["CARGO_TARGET_DIR"] } }
LIBAFL_CC = '${CARGO_TARGET_DIR}/release/libafl_cc'
LIBAFL_CXX = '${CARGO_TARGET_DIR}/release/libafl_cxx'
LIBAFL_LIBTOOL = '${CARGO_TARGET_DIR}/release/libafl_libtool'
Expand Down Expand Up @@ -35,17 +35,19 @@ mac_alias = "cxx_unix"
windows_alias = "unsupported"

[tasks.cxx_unix]
command = "cargo"
args = ["build" , "--release"]
script="RUSTFLAGS=-Zsanitizer=address cargo +nightly build -Zbuild-std --target x86_64-unknown-linux-gnu --release"
#command = "cargo"
#args = ["build" , "--release"]

[tasks.cc]
linux_alias = "cc_unix"
mac_alias = "cc_unix"
windows_alias = "unsupported"

[tasks.cc_unix]
command = "cargo"
args = ["build" , "--release"]
script="RUSTFLAGS=-Zsanitizer=address cargo +nightly build -Zbuild-std --target x86_64-unknown-linux-gnu --release"
#command = "cargo"
#args = ["build" , "--release"]

# Library
[tasks.lib]
Expand All @@ -55,7 +57,7 @@ windows_alias = "unsupported"

[tasks.lib_unix]
script_runner="@shell"
script='''
cript='''
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="${CARGO_TARGET_DIR}/release/libafl_cc" CXX="${CARGO_TARGET_DIR}/release/libafl_cxx" LIBTOOL=${CARGO_TARGET_DIR}/release/libafl_libtool
Expand All @@ -71,7 +73,7 @@ windows_alias = "unsupported"

[tasks.fuzzer_unix]
command = "${CARGO_TARGET_DIR}/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"]
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", "-fsanitize=address"]
dependencies = [ "lib", "cxx", "cc" ]

# Run the fuzzer
Expand Down
14 changes: 11 additions & 3 deletions fuzzers/libfuzzer_libpng_launcher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
//! The example harness is built for libpng.
//! In this example, you will see the use of the `launcher` feature.
//! The `launcher` will spawn new processes for each cpu core.
use mimalloc::MiMalloc;
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;
//use mimalloc::MiMalloc;
//#[global_allocator]
//static GLOBAL: MiMalloc = MiMalloc;

use core::time::Duration;
use std::{env, net::SocketAddr, path::PathBuf};
Expand Down Expand Up @@ -197,7 +197,15 @@ pub fn libafl_main() {
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();

// Artificial timeout to check timeout
libfuzzer_test_one_input(buf);

// We're timeouting
if buf.len() == 42 {
println!("TIMEOUT :)");
std::thread::sleep(Duration::from_millis(1_000_000));
}
ExitKind::Ok
};

Expand Down
4 changes: 2 additions & 2 deletions libafl/src/bolts/shmem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1443,15 +1443,15 @@ impl<T: ShMem> std::io::Seek for ShMemCursor<T> {
std::io::SeekFrom::End(offset) => {
let map_len = self.inner.as_slice().len();
i64::try_from(map_len).unwrap();
let signed_pos = map_len as i64;
let signed_pos = i64::try_from(map_len).unwrap();
let effective = signed_pos.checked_add(offset).unwrap();
assert!(effective >= 0);
effective.try_into().unwrap()
}
std::io::SeekFrom::Current(offset) => {
let current_pos = self.pos;
i64::try_from(current_pos).unwrap();
let signed_pos = current_pos as i64;
let signed_pos = i64::try_from(current_pos).unwrap();
let effective = signed_pos.checked_add(offset).unwrap();
assert!(effective >= 0);
effective.try_into().unwrap()
Expand Down
8 changes: 2 additions & 6 deletions libafl/src/bolts/staterestore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ where
let shmem_content = self.content_mut();
unsafe {
ptr::copy_nonoverlapping(
filename_buf.as_ptr() as *const u8,
filename_buf.as_ptr(),
shmem_content.buf.as_mut_ptr(),
len,
);
Expand All @@ -166,11 +166,7 @@ where
let len = serialized.len();
let shmem_content = self.content_mut();
unsafe {
ptr::copy_nonoverlapping(
serialized.as_ptr() as *const u8,
shmem_content.buf.as_mut_ptr(),
len,
);
ptr::copy_nonoverlapping(serialized.as_ptr(), shmem_content.buf.as_mut_ptr(), len);
}
shmem_content.buf_len = len;
shmem_content.is_disk = false;
Expand Down
1 change: 0 additions & 1 deletion libafl/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,6 @@ where

Ok(cur)
} else {
if cur.as_millis() % 1000 == 0 {}
Ok(last_report_time)
}
}
Expand Down
32 changes: 21 additions & 11 deletions libafl/src/executors/forkserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const fn fs_opt_get_mapsize(x: i32) -> i32 {

/// The length of header bytes which tells shmem size
const SHMEM_FUZZ_HDR_SIZE: usize = 4;
const MAX_FILE: usize = 1024 * 1024;
const MAX_INPUT_SIZE_DEFAULT: usize = 1024 * 1024;

/// Configure the target, `limit`, `setsid`, `pipe_stdin`, the code was borrowed from the [`Angora`](https://github.com/AngoraFuzzer/Angora) fuzzer
pub trait ConfigTarget {
Expand Down Expand Up @@ -436,14 +436,20 @@ where
let last_run_timed_out = self.executor.forkserver().last_run_timed_out();

if self.executor.uses_shmem_testcase() {
let shmem = unsafe { self.executor.shmem_mut().as_mut().unwrap_unchecked() };
let map = unsafe { self.executor.shmem_mut().as_mut().unwrap_unchecked() };
let target_bytes = input.target_bytes();
let size = target_bytes.as_slice().len();
let mut size = target_bytes.as_slice().len();
let max_size = map.len() - SHMEM_FUZZ_HDR_SIZE;
if size > max_size {
// Truncate like AFL++ does
size = max_size;
}
let size_in_bytes = size.to_ne_bytes();
// The first four bytes tells the size of the shmem.
shmem.as_mut_slice()[..4].copy_from_slice(&size_in_bytes[..4]);
shmem.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)]
.copy_from_slice(target_bytes.as_slice());
map.as_mut_slice()[..SHMEM_FUZZ_HDR_SIZE]
.copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]);
map.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)]
.copy_from_slice(&target_bytes.as_slice()[..size]);
} else {
self.executor
.input_file_mut()
Expand Down Expand Up @@ -610,6 +616,7 @@ pub struct ForkserverExecutorBuilder<'a, SP> {
autotokens: Option<&'a mut Tokens>,
input_filename: Option<OsString>,
shmem_provider: Option<&'a mut SP>,
max_input_size: usize,
map_size: Option<usize>,
real_map_size: i32,
}
Expand Down Expand Up @@ -716,10 +723,10 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> {
None => None,
Some(provider) => {
// setup shared memory
let mut shmem = provider.new_shmem(MAX_FILE + SHMEM_FUZZ_HDR_SIZE)?;
let mut shmem = provider.new_shmem(self.max_input_size + SHMEM_FUZZ_HDR_SIZE)?;
shmem.write_to_env("__AFL_SHM_FUZZ_ID")?;

let size_in_bytes = (MAX_FILE + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes();
let size_in_bytes = (self.max_input_size + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes();
shmem.as_mut_slice()[..4].clone_from_slice(&size_in_bytes[..4]);
Some(shmem)
}
Expand Down Expand Up @@ -1035,6 +1042,7 @@ impl<'a> ForkserverExecutorBuilder<'a, UnixShMemProvider> {
shmem_provider: None,
map_size: None,
real_map_size: 0,
max_input_size: MAX_INPUT_SIZE_DEFAULT,
}
}

Expand All @@ -1057,6 +1065,7 @@ impl<'a> ForkserverExecutorBuilder<'a, UnixShMemProvider> {
shmem_provider: Some(shmem_provider),
map_size: self.map_size,
real_map_size: self.real_map_size,
max_input_size: MAX_INPUT_SIZE_DEFAULT,
}
}
}
Expand Down Expand Up @@ -1091,16 +1100,17 @@ where
let map = unsafe { self.map.as_mut().unwrap_unchecked() };
let target_bytes = input.target_bytes();
let mut size = target_bytes.as_slice().len();
if size > MAX_FILE {
let max_size = map.len() - SHMEM_FUZZ_HDR_SIZE;
if size > max_size {
// Truncate like AFL++ does
size = MAX_FILE;
size = max_size;
}
let size_in_bytes = size.to_ne_bytes();
// The first four bytes tells the size of the shmem.
map.as_mut_slice()[..SHMEM_FUZZ_HDR_SIZE]
.copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]);
map.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)]
.copy_from_slice(target_bytes.as_slice());
.copy_from_slice(&target_bytes.as_slice()[..size]);
} else {
self.input_file.write_buf(input.target_bytes().as_slice())?;
}
Expand Down
1 change: 1 addition & 0 deletions libafl/src/mutators/mutations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,7 @@ fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) {
let mut first_diff: i64 = -1;
let mut last_diff: i64 = -1;
for (i, (this_el, other_el)) in this.iter().zip(other.iter()).enumerate() {
#[allow(clippy::cast_possible_wrap)]
if this_el != other_el {
if first_diff < 0 {
first_diff = i as i64;
Expand Down
12 changes: 6 additions & 6 deletions libafl/src/mutators/token_mutations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ impl AFLppRedQueen {
)),
0xffff,
),
4 | 5 | 6 | 7 => (
4..=7 => (
u64::from(u32::from_be_bytes(
buf[buf_idx..buf_idx + 4].try_into().unwrap(),
)),
Expand Down Expand Up @@ -852,7 +852,7 @@ impl AFLppRedQueen {
}
}
}
4 | 5 | 6 | 7 => {
4..=7 => {
if its_len >= 4 {
let buf_32 = u32::from_be_bytes(buf[buf_idx..buf_idx + 4].try_into().unwrap());
let another_buf_32 =
Expand Down Expand Up @@ -1448,15 +1448,15 @@ where

if !cmp_found {
if orig_v0 == new_v0
&& check_if_text(&orig_v0.to_ne_bytes().to_vec(), hshape).size()
&& check_if_text(orig_v0.to_ne_bytes().as_ref(), hshape).size()
== hshape
{
let v = orig_v0.to_ne_bytes().to_vec();
Self::try_add_autotokens(&mut gathered_tokens, &v, hshape);
}

if orig_v1 == new_v1
&& check_if_text(&orig_v1.to_ne_bytes().to_vec(), hshape).size()
&& check_if_text(orig_v1.to_ne_bytes().as_ref(), hshape).size()
== hshape
{
let v = orig_v1.to_ne_bytes().to_vec();
Expand Down Expand Up @@ -1541,15 +1541,15 @@ where

if !cmp_found {
if orig_v0 == new_v0
&& check_if_text(&orig_v0.to_ne_bytes().to_vec(), hshape).size()
&& check_if_text(orig_v0.to_ne_bytes().as_ref(), hshape).size()
== hshape
{
let v = orig_v0.to_ne_bytes().to_vec();
Self::try_add_autotokens(&mut gathered_tokens, &v, hshape);
}

if orig_v1 == new_v1
&& check_if_text(&orig_v1.to_ne_bytes().to_vec(), hshape).size()
&& check_if_text(orig_v1.to_ne_bytes().as_ref(), hshape).size()
== hshape
{
let v = orig_v1.to_ne_bytes().to_vec();
Expand Down
16 changes: 8 additions & 8 deletions libafl/src/observers/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ where
let cnt = self.usable_count();
let map = self.as_slice();
let mut res = 0;
for x in map[0..cnt].iter() {
for x in &map[0..cnt] {
if *x != initial {
res += 1;
}
Expand Down Expand Up @@ -386,7 +386,7 @@ where
let initial = self.initial();
let cnt = self.usable_count();
let map = self.as_mut_slice();
for x in map[0..cnt].iter_mut() {
for x in &mut map[0..cnt] {
*x = initial;
}
Ok(())
Expand Down Expand Up @@ -815,7 +815,7 @@ where
let cnt = self.usable_count();
let map = self.as_slice();
let mut res = 0;
for x in map[0..cnt].iter() {
for x in &map[0..cnt] {
if *x != initial {
res += 1;
}
Expand All @@ -838,7 +838,7 @@ where
let initial = self.initial();
let cnt = self.usable_count();
let map = self.as_mut_slice();
for x in map[0..cnt].iter_mut() {
for x in &mut map[0..cnt] {
*x = initial;
}
Ok(())
Expand Down Expand Up @@ -1091,7 +1091,7 @@ where
let cnt = self.usable_count();
let map = self.as_slice();
let mut res = 0;
for x in map[0..cnt].iter() {
for x in &map[0..cnt] {
if *x != initial {
res += 1;
}
Expand All @@ -1109,7 +1109,7 @@ where
let initial = self.initial();
let cnt = self.usable_count();
let map = self.as_mut_slice();
for x in map[0..cnt].iter_mut() {
for x in &mut map[0..cnt] {
*x = initial;
}
Ok(())
Expand Down Expand Up @@ -2082,7 +2082,7 @@ where
let cnt = self.usable_count();
let map = self.as_slice();
let mut res = 0;
for x in map[0..cnt].iter() {
for x in &map[0..cnt] {
if *x != initial {
res += 1;
}
Expand Down Expand Up @@ -2111,7 +2111,7 @@ where
let initial = self.initial();
let cnt = self.usable_count();
let map = self.as_mut_slice();
for x in map[0..cnt].iter_mut() {
for x in &mut map[0..cnt] {
*x = initial;
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion libafl/src/observers/stacktrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ pub fn get_asan_runtime_flags_with_log_path() -> String {
/// returns the recommended ASAN runtime flags to capture the backtrace correctly
#[must_use]
pub fn get_asan_runtime_flags() -> String {
let flags = vec![
let flags = [
"exitcode=0",
"abort_on_error=1",
"handle_abort=1",
Expand Down
1 change: 1 addition & 0 deletions libafl/src/schedulers/ecofuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ where
if !was_fuzzed {
let selection = Some(id);
state.metadata_mut::<EcoMetadata>()?.state = EcoState::Exploration;
#[allow(clippy::unnecessary_literal_unwrap)] // false positive
return Ok(selection.expect("Error in the algorithm, this cannot be None"));
}
}
Expand Down
2 changes: 1 addition & 1 deletion libafl/src/schedulers/probabilistic_sampling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ where
let threshold = meta.total_probability * rand_prob;
let mut k: f64 = 0.0;
let mut ret = *meta.map.keys().last().unwrap();
for (idx, prob) in meta.map.iter() {
for (idx, prob) in &meta.map {
k += prob;
if k >= threshold {
ret = *idx;
Expand Down
2 changes: 1 addition & 1 deletion libafl/src/schedulers/weighted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ where
sum += weight;
}

for (i, w) in weights.iter() {
for (i, w) in &weights {
p_arr.insert(*i, w * (n as f64) / sum);
}

Expand Down