Skip to content

Commit

Permalink
Merge branch 'main' into multi-stream
Browse files Browse the repository at this point in the history
  • Loading branch information
andreafioraldi authored Oct 11, 2023
2 parents cf90042 + 4c17da0 commit 29c2c84
Show file tree
Hide file tree
Showing 21 changed files with 337 additions and 130 deletions.
6 changes: 0 additions & 6 deletions fuzzers/fuzzbench_forkserver_cmplog/test/test-cmplog.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,16 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t i) {
if (*icmp != 0x69694141) return 0;
if (memcmp(buf + 8, "1234EF", 6) == 0) abort();
return 0;

}

int main(int argc, char *argv[]) {

unsigned char buf[1024];
ssize_t i;
while (__AFL_LOOP(1000)) {

i = read(0, (char *)buf, sizeof(buf) - 1);
if (i > 0) buf[i] = 0;
LLVMFuzzerTestOneInput(buf, i);

}

return 0;

}

1 change: 1 addition & 0 deletions fuzzers/qemu_systemmode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ codegen-units = 1
libafl = { path = "../../libafl/" }
libafl_bolts = { path = "../../libafl_bolts/" }
libafl_qemu = { path = "../../libafl_qemu/", features = ["arm", "systemmode"] }
env_logger = "*"
6 changes: 4 additions & 2 deletions fuzzers/qemu_systemmode/example/main.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
int BREAKPOINT() {
int __attribute__((noinline)) BREAKPOINT() {
for (;;) {}
}

int LLVMFuzzerTestOneInput(unsigned int *Data, unsigned int Size) {
// if (Data[3] == 0) {while(1){}} // cause a timeout
if (Data[3] == 0) {
while (1) {}
} // cause a timeout
for (int i = 0; i < Size; i++) {
// if (Data[i] > 0xFFd0 && Data[i] < 0xFFFF) {return 1;} // cause qemu to
// crash
Expand Down
7 changes: 6 additions & 1 deletion fuzzers/qemu_systemmode/src/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ use libafl_qemu::{
pub static mut MAX_INPUT_SIZE: usize = 50;

pub fn fuzz() {
env_logger::init();

if let Ok(s) = env::var("FUZZ_SIZE") {
str::parse::<usize>(&s).expect("FUZZ_SIZE was not a number");
};
Expand Down Expand Up @@ -193,7 +195,7 @@ pub fn fuzz() {
let mut hooks = QemuHooks::new(&emu, tuple_list!(QemuEdgeCoverageHelper::default()));

// Create a QEMU in-process executor
let executor = QemuExecutor::new(
let mut executor = QemuExecutor::new(
&mut hooks,
&mut harness,
tuple_list!(edges_observer, time_observer),
Expand All @@ -203,6 +205,9 @@ pub fn fuzz() {
)
.expect("Failed to create QemuExecutor");

// Instead of calling the timeout handler and restart the process, trigger a breakpoint ASAP
executor.break_on_timeout();

// Wrap the executor to keep track of the timeout
let mut executor = TimeoutExecutor::new(executor, timeout);

Expand Down
1 change: 1 addition & 0 deletions libafl/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pub type ShutdownFuncPtr =
///
/// This will acceess `data` and write to the global `data.staterestorer_ptr` if it's not null.
#[cfg(all(unix, feature = "std"))]
#[allow(clippy::needless_pass_by_value)]
pub unsafe fn shutdown_handler<SP>(
signal: Signal,
_info: &mut siginfo_t,
Expand Down
1 change: 1 addition & 0 deletions libafl/src/executors/inprocess.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! It should usually be paired with extra error-handling, such as a restarting event manager, to be effective.
//!
//! Needs the `fork` feature flag.
#![allow(clippy::needless_pass_by_value)]

use alloc::boxed::Box;
#[cfg(all(unix, feature = "std"))]
Expand Down
5 changes: 5 additions & 0 deletions libafl/src/mutators/token_mutations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ impl Tokens {
pub fn tokens(&self) -> &[Vec<u8>] {
&self.tokens_vec
}

/// Returns an iterator over the tokens.
pub fn iter(&self) -> Iter<'_, Vec<u8>> {
<&Self as IntoIterator>::into_iter(self)
}
}

impl AddAssign for Tokens {
Expand Down
120 changes: 60 additions & 60 deletions libafl/src/observers/concolic/serialization_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,66 +381,6 @@ impl<W: Write + Seek> MessageFileWriter<W> {
}
}

#[cfg(test)]
mod serialization_tests {
use alloc::vec::Vec;
use std::io::Cursor;

use super::{MessageFileReader, MessageFileWriter, SymExpr};

/// This test intends to ensure that the serialization format can efficiently encode the required information.
/// This is mainly useful to fail if any changes should be made in the future that (inadvertently) reduce
/// serialization efficiency.
#[test]
fn efficient_serialization() {
let mut buf = Vec::new();
{
let mut cursor = Cursor::new(&mut buf);
let mut writer = MessageFileWriter::from_writer(&mut cursor).unwrap();
let a = writer.write_message(SymExpr::True).unwrap();
let b = writer.write_message(SymExpr::True).unwrap();
writer.write_message(SymExpr::And { a, b }).unwrap();
writer.update_trace_header().unwrap();
}
let expected_size = 8 + // the header takes 8 bytes to encode the length of the trace
1 + // tag to create SymExpr::True (a)
1 + // tag to create SymExpr::True (b)
1 + // tag to create SymExpr::And
1 + // reference to a
1; // reference to b
assert_eq!(buf.len(), expected_size);
}

/// This test intends to verify that a trace written by [`MessageFileWriter`] can indeed be read back by
/// [`MessageFileReader`].
#[test]
fn serialization_roundtrip() {
let mut buf = Vec::new();
{
let mut cursor = Cursor::new(&mut buf);
let mut writer = MessageFileWriter::from_writer(&mut cursor).unwrap();
let a = writer.write_message(SymExpr::True).unwrap();
let b = writer.write_message(SymExpr::True).unwrap();
writer.write_message(SymExpr::And { a, b }).unwrap();
writer.update_trace_header().unwrap();
}
let mut reader = MessageFileReader::from_length_prefixed_buffer(&buf).unwrap();
let (first_bool_id, first_bool) = reader.next_message().unwrap().unwrap();
assert_eq!(first_bool, SymExpr::True);
let (second_bool_id, second_bool) = reader.next_message().unwrap().unwrap();
assert_eq!(second_bool, SymExpr::True);
let (_, and) = reader.next_message().unwrap().unwrap();
assert_eq!(
and,
SymExpr::And {
a: first_bool_id,
b: second_bool_id
}
);
assert!(reader.next_message().is_none());
}
}

use libafl_bolts::shmem::{ShMem, ShMemCursor, ShMemProvider, StdShMemProvider};

/// The default environment variable name to use for the shared memory used by the concolic tracing
Expand Down Expand Up @@ -511,3 +451,63 @@ impl MessageFileWriter<ShMemCursor<<StdShMemProvider as ShMemProvider>::ShMem>>
/// A writer that will write messages to a shared memory buffer.
pub type StdShMemMessageFileWriter =
MessageFileWriter<ShMemCursor<<StdShMemProvider as ShMemProvider>::ShMem>>;

#[cfg(test)]
mod serialization_tests {
use alloc::vec::Vec;
use std::io::Cursor;

use super::{MessageFileReader, MessageFileWriter, SymExpr};

/// This test intends to ensure that the serialization format can efficiently encode the required information.
/// This is mainly useful to fail if any changes should be made in the future that (inadvertently) reduce
/// serialization efficiency.
#[test]
fn efficient_serialization() {
let mut buf = Vec::new();
{
let mut cursor = Cursor::new(&mut buf);
let mut writer = MessageFileWriter::from_writer(&mut cursor).unwrap();
let a = writer.write_message(SymExpr::True).unwrap();
let b = writer.write_message(SymExpr::True).unwrap();
writer.write_message(SymExpr::And { a, b }).unwrap();
writer.update_trace_header().unwrap();
}
let expected_size = 8 + // the header takes 8 bytes to encode the length of the trace
1 + // tag to create SymExpr::True (a)
1 + // tag to create SymExpr::True (b)
1 + // tag to create SymExpr::And
1 + // reference to a
1; // reference to b
assert_eq!(buf.len(), expected_size);
}

/// This test intends to verify that a trace written by [`MessageFileWriter`] can indeed be read back by
/// [`MessageFileReader`].
#[test]
fn serialization_roundtrip() {
let mut buf = Vec::new();
{
let mut cursor = Cursor::new(&mut buf);
let mut writer = MessageFileWriter::from_writer(&mut cursor).unwrap();
let a = writer.write_message(SymExpr::True).unwrap();
let b = writer.write_message(SymExpr::True).unwrap();
writer.write_message(SymExpr::And { a, b }).unwrap();
writer.update_trace_header().unwrap();
}
let mut reader = MessageFileReader::from_length_prefixed_buffer(&buf).unwrap();
let (first_bool_id, first_bool) = reader.next_message().unwrap().unwrap();
assert_eq!(first_bool, SymExpr::True);
let (second_bool_id, second_bool) = reader.next_message().unwrap().unwrap();
assert_eq!(second_bool, SymExpr::True);
let (_, and) = reader.next_message().unwrap().unwrap();
assert_eq!(
and,
SymExpr::And {
a: first_bool_id,
b: second_bool_id
}
);
assert!(reader.next_message().is_none());
}
}
Loading

0 comments on commit 29c2c84

Please sign in to comment.