diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 025d260783..01a27f6519 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -118,7 +118,7 @@ jobs: toolchain: nightly - uses: Swatinem/rust-cache@v1 - name: Add nightly rustfmt and clippy - run: rustup toolchain install nightly && rustup target add --toolchain nightly aarch64-unknown-none && rustup component add --toolchain nightly rust-src + run: rustup toolchain install nightly && rustup target add --toolchain nightly aarch64-unknown-none && rustup component add --toolchain nightly rust-src && rustup target add thumbv6m-none-eabi - uses: actions/checkout@v2 - name: Build aarch64-unknown-none run: cd ./fuzzers/baby_no_std && cargo +nightly build -Zbuild-std=core,alloc --target aarch64-unknown-none -v --release && cd ../.. @@ -126,6 +126,8 @@ jobs: run: cd ./fuzzers/baby_no_std && cargo +nightly run || test $? -ne 0 || exit 1 - name: no_std tests run: cd ./libafl && cargo test --no-default-features + - name: armv6m-none-eabi (32 bit no_std) clippy + run: cd ./libafl && cargo clippy --target thumbv6m-none-eabi --no-default-features build-docker: runs-on: ubuntu-latest steps: diff --git a/Cargo.toml b/Cargo.toml index 8d4f8b181e..aeb96ea7b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ members = [ "libafl_concolic/test/runtime_test", "utils/deexit", "utils/gramatron/construct_automata", + "utils/libafl_benches", ] default-members = [ "libafl", diff --git a/Dockerfile b/Dockerfile index a753b547ce..812ea76c19 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,6 @@ COPY libafl_derive/Cargo.toml libafl_derive/Cargo.toml COPY scripts/dummy.rs libafl_derive/src/lib.rs COPY libafl/Cargo.toml libafl/build.rs libafl/ -COPY libafl/benches libafl/benches COPY libafl/examples libafl/examples COPY scripts/dummy.rs libafl/src/lib.rs diff --git a/libafl/Cargo.toml b/libafl/Cargo.toml index 3a526389be..bc97002274 100644 --- a/libafl/Cargo.toml +++ b/libafl/Cargo.toml @@ -38,11 +38,7 @@ llmp_small_maps = [] # reduces initial map size for llmp rustversion = "1.0" [dev-dependencies] -criterion = "0.3" # Benchmarking -ahash = "0.7" # another hash -fxhash = "0.2.1" # yet another hash -xxhash-rust = { version = "0.8.2", features = ["xxh3"] } # xxh3 hashing for rust -serde_json = "1.0" +serde_json = { version = "1.0", default-features = false, features = ["alloc"] } num_cpus = "1.0" # cpu count, for llmp example serial_test = "0.5" @@ -100,14 +96,6 @@ windows = { version = "0.29.0", features = ["std", "Win32_Foundation", "Win32_Sy [target.'cfg(windows)'.build-dependencies] windows = "0.29.0" -[[bench]] -name = "rand_speeds" -harness = false - -[[bench]] -name = "hash_speeds" -harness = false - #[profile.release] #lto = true #opt-level = 3 diff --git a/libafl/src/bolts/cpu.rs b/libafl/src/bolts/cpu.rs index c1a0f93689..f0cefffa61 100644 --- a/libafl/src/bolts/cpu.rs +++ b/libafl/src/bolts/cpu.rs @@ -33,6 +33,7 @@ pub fn read_time_counter() -> u64 { /// change this implementation rather than every instead of [`read_time_counter`] /// On unsupported architectures, it's falling back to normal system time, in millis. #[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] +#[must_use] pub fn read_time_counter() -> u64 { current_nanos() } diff --git a/libafl/src/bolts/llmp.rs b/libafl/src/bolts/llmp.rs index ec7607a933..9b7c6df306 100644 --- a/libafl/src/bolts/llmp.rs +++ b/libafl/src/bolts/llmp.rs @@ -60,13 +60,17 @@ For broker2broker communication, all messages are forwarded via network sockets. */ use alloc::{string::String, vec::Vec}; +#[cfg(not(target_pointer_width = "64"))] +use core::sync::atomic::AtomicU32; +#[cfg(target_pointer_width = "64")] +use core::sync::atomic::AtomicU64; use core::{ cmp::max, fmt::Debug, hint, mem::size_of, ptr, slice, - sync::atomic::{fence, AtomicU16, AtomicU64, Ordering}, + sync::atomic::{fence, AtomicU16, Ordering}, time::Duration, }; use serde::{Deserialize, Serialize}; @@ -173,7 +177,11 @@ pub type BrokerId = u32; /// The flags, indicating, for example, enabled compression. pub type Flags = u32; /// The message ID, an ever-increasing number, unique only to a sharedmap/page. +#[cfg(target_pointer_width = "64")] pub type MessageId = u64; +/// The message ID, an ever-increasing number, unique only to a sharedmap/page. +#[cfg(not(target_pointer_width = "64"))] +pub type MessageId = u32; /// This is for the server the broker will spawn. /// If an llmp connection is local - use sharedmaps @@ -519,7 +527,7 @@ pub struct LlmpMsg { /// flags, currently only used for indicating compression pub flags: Flags, //u32 /// The message ID, unique per page - pub message_id: MessageId, //u64 + pub message_id: MessageId, //u64 on 64 bit, else u32 /// Buffer length as specified by the user pub buf_len: u64, /// (Actual) buffer length after padding @@ -684,8 +692,12 @@ pub struct LlmpPage { pub safe_to_unmap: AtomicU16, /// Not used at the moment (would indicate that the sender is no longer there) pub sender_dead: AtomicU16, + #[cfg(target_pointer_width = "64")] /// The current message ID pub current_msg_id: AtomicU64, + #[cfg(not(target_pointer_width = "64"))] + /// The current message ID + pub current_msg_id: AtomicU32, /// How much space is available on this page in bytes pub size_total: usize, /// How much space is used on this page in bytes @@ -1300,7 +1312,7 @@ where /// current page. After EOP, this gets replaced with the new one pub current_recv_shmem: LlmpSharedMap, /// Caches the highest msg id we've seen so far - highest_msg_id: u64, + highest_msg_id: MessageId, } /// Receiving end of an llmp channel @@ -2325,37 +2337,36 @@ where msg_buf_len_padded, size_of::() ))); - } else { - let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo; - - match self.shmem_provider.shmem_from_id_and_size( - ShMemId::from_array(&(*pageinfo).shm_str), - (*pageinfo).map_size, - ) { - Ok(new_shmem) => { - let mut new_page = LlmpSharedMap::existing(new_shmem); - let id = next_id; - next_id += 1; - new_page.mark_safe_to_unmap(); - self.llmp_clients.push(LlmpReceiver { - id, - current_recv_shmem: new_page, - last_msg_recvd: ptr::null_mut(), - shmem_provider: self.shmem_provider.clone(), - highest_msg_id: 0, - }); - } - Err(e) => { - #[cfg(feature = "std")] - println!("Error adding client! Ignoring: {:?}", e); - #[cfg(not(feature = "std"))] - return Err(Error::Unknown(format!( - "Error adding client! PANIC! {:?}", - e - ))); - } - }; } + let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo; + + match self.shmem_provider.shmem_from_id_and_size( + ShMemId::from_array(&(*pageinfo).shm_str), + (*pageinfo).map_size, + ) { + Ok(new_shmem) => { + let mut new_page = LlmpSharedMap::existing(new_shmem); + let id = next_id; + next_id += 1; + new_page.mark_safe_to_unmap(); + self.llmp_clients.push(LlmpReceiver { + id, + current_recv_shmem: new_page, + last_msg_recvd: ptr::null_mut(), + shmem_provider: self.shmem_provider.clone(), + highest_msg_id: 0, + }); + } + Err(e) => { + #[cfg(feature = "std")] + println!("Error adding client! Ignoring: {:?}", e); + #[cfg(not(feature = "std"))] + return Err(Error::Unknown(format!( + "Error adding client! PANIC! {:?}", + e + ))); + } + }; } // handle all other messages _ => { diff --git a/libafl/src/bolts/mod.rs b/libafl/src/bolts/mod.rs index 6e5a8afc19..5570c0a7f9 100644 --- a/libafl/src/bolts/mod.rs +++ b/libafl/src/bolts/mod.rs @@ -69,7 +69,7 @@ pub fn current_time() -> time::Duration { SystemTime::now().duration_since(UNIX_EPOCH).unwrap() } -/// external defined function in case of no_std +/// external defined function in case of `no_std` /// /// Define your own `external_current_millis()` function via `extern "C"` /// which is linked into the binary and called from here. @@ -79,9 +79,10 @@ extern "C" { fn external_current_millis() -> u64; } -/// Current time (fixed fallback for no_std) +/// Current time (fixed fallback for `no_std`) #[cfg(not(feature = "std"))] #[inline] +#[must_use] pub fn current_time() -> time::Duration { let millis = unsafe { external_current_millis() }; time::Duration::from_millis(millis) diff --git a/libafl/src/executors/inprocess.rs b/libafl/src/executors/inprocess.rs index a209eed373..0d69a090c4 100644 --- a/libafl/src/executors/inprocess.rs +++ b/libafl/src/executors/inprocess.rs @@ -235,6 +235,7 @@ pub struct InProcessHandlers { impl InProcessHandlers { /// Call before running a target. + #[allow(clippy::unused_self)] pub fn pre_run_target( &self, _executor: &E, diff --git a/libafl/src/mutators/mopt_mutator.rs b/libafl/src/mutators/mopt_mutator.rs index 4f99d0a3b5..93275d6db7 100644 --- a/libafl/src/mutators/mopt_mutator.rs +++ b/libafl/src/mutators/mopt_mutator.rs @@ -459,6 +459,7 @@ where } } + #[allow(clippy::cast_lossless)] if mopt.pilot_time > mopt.period_pilot { let new_finds = mopt.total_finds - mopt.finds_until_last_swarm; let f = (new_finds as f64) / ((mopt.pilot_time as f64) / (PERIOD_PILOT_COEF)); diff --git a/utils/README.md b/utils/README.md index d3231fd3c7..c79d7a570f 100644 --- a/utils/README.md +++ b/utils/README.md @@ -12,3 +12,8 @@ Abort, on the other hand, raises an error LibAFL's inprocess executor will be ab ## Gramatron: gramatron grammars and preprocessing utils See https://github.com/HexHive/Gramatron + +## libafl_benches + +This folder contains benchmarks for various things in LibAFL, like hash speeds and RNGs. +Run with `cargo bench` \ No newline at end of file diff --git a/utils/deexit/Cargo.toml b/utils/deexit/Cargo.toml index b6211d965e..29b8ee335b 100644 --- a/utils/deexit/Cargo.toml +++ b/utils/deexit/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "deexit" version = "0.1.0" -edition = "2018" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/utils/libafl_benches/Cargo.toml b/utils/libafl_benches/Cargo.toml new file mode 100644 index 0000000000..a7c317c21a --- /dev/null +++ b/utils/libafl_benches/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "libafl_benches" +version = "0.7.1" +edition = "2021" + +[dev-dependencies] +criterion = "0.3" # Benchmarking +ahash = { version = "0.7", default-features=false, features=["compile-time-rng"] } # The hash function already used in hashbrown +rustc-hash = { version = "1.0", default-features=false } # yet another hash +xxhash-rust = { version = "0.8.2", features = ["xxh3"] } # xxh3 hashing for rust +libafl = { path = "../../libafl", default-features=false } # libafl + +[[bench]] +name = "rand_speeds" +harness = false + +[[bench]] +name = "hash_speeds" +harness = false + diff --git a/libafl/benches/hash_speeds.rs b/utils/libafl_benches/benches/hash_speeds.rs similarity index 85% rename from libafl/benches/hash_speeds.rs rename to utils/libafl_benches/benches/hash_speeds.rs index 7d6a9df3ef..6c10255162 100644 --- a/libafl/benches/hash_speeds.rs +++ b/utils/libafl_benches/benches/hash_speeds.rs @@ -28,7 +28,11 @@ fn criterion_benchmark(c: &mut Criterion) { }) }); c.bench_function("fxhash", |b| { - b.iter(|| fxhash::hash64(black_box(&bench_vec))) + b.iter(|| { + let mut hasher = rustc_hash::FxHasher::default(); + hasher.write(black_box(&bench_vec)); + hasher.finish() + }) }); } diff --git a/libafl/benches/rand_speeds.rs b/utils/libafl_benches/benches/rand_speeds.rs similarity index 100% rename from libafl/benches/rand_speeds.rs rename to utils/libafl_benches/benches/rand_speeds.rs