Fixed Forkserver shmem input length, made it configurable (#1342)
* Fixed Forkserver shmem input length, made it configurable * fix redqueen clippy * Clippy * Clippy * WHY ARE THERE TWO TIMES THE SAME FN * More clippy
This commit is contained in:
parent
829b5049e6
commit
e5b3e5a677
@ -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'
|
||||
@ -35,8 +35,9 @@ 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"
|
||||
@ -44,8 +45,9 @@ 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]
|
||||
@ -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
|
||||
@ -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
|
||||
|
@ -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};
|
||||
@ -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
|
||||
};
|
||||
|
||||
|
@ -1443,7 +1443,7 @@ 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()
|
||||
@ -1451,7 +1451,7 @@ impl<T: ShMem> std::io::Seek for ShMemCursor<T> {
|
||||
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()
|
||||
|
@ -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,
|
||||
);
|
||||
@ -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;
|
||||
|
@ -499,7 +499,6 @@ where
|
||||
|
||||
Ok(cur)
|
||||
} else {
|
||||
if cur.as_millis() % 1000 == 0 {}
|
||||
Ok(last_report_time)
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -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()
|
||||
@ -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,
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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())?;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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(),
|
||||
)),
|
||||
@ -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 =
|
||||
@ -1448,7 +1448,7 @@ 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();
|
||||
@ -1456,7 +1456,7 @@ where
|
||||
}
|
||||
|
||||
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();
|
||||
@ -1541,7 +1541,7 @@ 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();
|
||||
@ -1549,7 +1549,7 @@ where
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -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;
|
||||
}
|
||||
@ -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(())
|
||||
@ -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;
|
||||
}
|
||||
@ -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(())
|
||||
@ -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;
|
||||
}
|
||||
@ -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(())
|
||||
@ -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;
|
||||
}
|
||||
@ -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(())
|
||||
|
@ -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",
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user