Centralize clippy lints in workspace (#2606)

* centralize clippy definition

* fmt

* add update bindings script

* add a checked and unchecked version of memory read to qemu stuff

also, a lot of clippy thing

* update binding position

* rm old script, new one is a bit better

* update doc

* macos clippy

* adapt fuzzers

* windows clippy

* fix fuzzer

* windows clippy

* remove old allowed clippy

* remove some allowed clippy

* use default features for serde_json in gramatron

* better error handler for failed rw to memory
This commit is contained in:
Romain Malmain 2024-10-15 13:31:01 +02:00 committed by GitHub
parent 453d733a35
commit d48a7d508d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
75 changed files with 7638 additions and 16446 deletions

View File

@ -55,6 +55,7 @@ backtrace = { version = "0.3.74", default-features = false } # Used to get the s
bindgen = "0.70.1" bindgen = "0.70.1"
clap = "4.5.18" clap = "4.5.18"
cc = "1.1.21" cc = "1.1.21"
cmake = "0.1.51"
document-features = "0.2.10" document-features = "0.2.10"
hashbrown = { version = "0.14.5", default-features = false } # A faster hashmap, nostd compatible hashbrown = { version = "0.14.5", default-features = false } # A faster hashmap, nostd compatible
libc = "0.2.159" # For (*nix) libc libc = "0.2.159" # For (*nix) libc
@ -87,6 +88,45 @@ which = "6.0.3"
windows = "0.58.0" windows = "0.58.0"
z3 = "0.12.1" z3 = "0.12.1"
[workspace.lints.rust]
# Forbid
unexpected_cfgs = "forbid"
# Allow
incomplete_features = "allow"
ambiguous_glob_reexports = "allow"
[workspace.lints.clippy]
# Deny
all = { level = "deny", priority = -1 }
pedantic = { level = "deny", priority = -1 }
cargo_common_metadata = "deny"
# Warn
cargo = { level = "warn", priority = -1 }
negative_feature_names = "warn"
# Allow
unreadable_literal = "allow"
type_repetition_in_bounds = "allow"
missing_errors_doc = "allow"
cast_possible_truncation = "allow"
used_underscore_binding = "allow"
ptr_as_ptr = "allow"
missing_panics_doc = "allow"
module_name_repetitions = "allow"
unsafe_derive_deserialize = "allow"
similar_names = "allow"
too_many_lines = "allow"
[workspace.lints.rustdoc]
# Deny
broken_intra_doc_links = "deny"
[profile.release] [profile.release]
lto = true lto = true
codegen-units = 1 codegen-units = 1

View File

@ -159,7 +159,7 @@ impl Client<'_> {
instance_builder.build().run( instance_builder.build().run(
tuple_list!( tuple_list!(
CmpLogModule::default(), CmpLogModule::default(),
AsanGuestModule::default(qemu, asan_lib.take().unwrap()), AsanGuestModule::default(qemu, &asan_lib.take().unwrap()),
injection_module injection_module
), ),
state, state,
@ -168,7 +168,7 @@ impl Client<'_> {
instance_builder.build().run( instance_builder.build().run(
tuple_list!( tuple_list!(
CmpLogModule::default(), CmpLogModule::default(),
AsanGuestModule::default(qemu, asan_lib.take().unwrap()), AsanGuestModule::default(qemu, &asan_lib.take().unwrap()),
), ),
state, state,
) )
@ -186,7 +186,7 @@ impl Client<'_> {
) )
} }
} else if is_asan_guest { } else if is_asan_guest {
let modules = tuple_list!(AsanGuestModule::default(qemu, asan_lib.take().unwrap())); let modules = tuple_list!(AsanGuestModule::default(qemu, &asan_lib.take().unwrap()));
instance_builder.build().run(modules, state) instance_builder.build().run(modules, state)
} else if is_cmplog { } else if is_cmplog {
if let Some(injection_module) = injection_module { if let Some(injection_module) = injection_module {

View File

@ -98,7 +98,12 @@ impl Harness {
} }
let len = len as GuestReg; let len = len as GuestReg;
unsafe { self.qemu.write_mem(self.input_addr, buf) }; self.qemu.write_mem(self.input_addr, buf).map_err(|e| {
Error::unknown(format!(
"Failed to write to memory@{:#x}: {e:?}",
self.input_addr
))
})?;
self.qemu self.qemu
.write_reg(Regs::Pc, self.pc) .write_reg(Regs::Pc, self.pc)

View File

@ -273,6 +273,9 @@ document-features = { workspace = true, optional = true }
# Optional # Optional
clap = { workspace = true, optional = true } clap = { workspace = true, optional = true }
[lints]
workspace = true
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
libc = { workspace = true } # For (*nix) libc libc = { workspace = true } # For (*nix) libc
z3 = { workspace = true, optional = true } # for concolic mutation z3 = { workspace = true, optional = true } # for concolic mutation

View File

@ -338,7 +338,7 @@ where
/// Launch the broker and the clients and fuzz /// Launch the broker and the clients and fuzz
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))] #[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
#[allow(unused_mut, clippy::match_wild_err_arm)] #[allow(unused_mut, clippy::match_wild_err_arm, clippy::too_many_lines)]
pub fn launch_with_hooks<EMH, S>(&mut self, hooks: EMH) -> Result<(), Error> pub fn launch_with_hooks<EMH, S>(&mut self, hooks: EMH) -> Result<(), Error>
where where
S: State + HasExecutions, S: State + HasExecutions,

View File

@ -212,8 +212,8 @@ where
impl<A, B, DOT> ProxyObserversTuple<A, B, DOT> { impl<A, B, DOT> ProxyObserversTuple<A, B, DOT> {
fn set(&mut self, primary: &A, secondary: &B) { fn set(&mut self, primary: &A, secondary: &B) {
self.primary = OwnedMutPtr::Ptr(ptr::from_ref(primary) as *mut A); self.primary = OwnedMutPtr::Ptr(ptr::from_ref(primary).cast_mut());
self.secondary = OwnedMutPtr::Ptr(ptr::from_ref(secondary) as *mut B); self.secondary = OwnedMutPtr::Ptr(ptr::from_ref(secondary).cast_mut());
} }
} }

View File

@ -4,35 +4,11 @@ Welcome to `LibAFL`
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
/*! */ /*! */
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] #![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
#![forbid(unexpected_cfgs)]
#![allow(incomplete_features)]
#![no_std] #![no_std]
// For `type_eq` // For `type_eq`
#![cfg_attr(nightly, feature(specialization))] #![cfg_attr(nightly, feature(specialization))]
// For `std::simd` // For `std::simd`
#![cfg_attr(nightly, feature(portable_simd))] #![cfg_attr(nightly, feature(portable_simd))]
#![warn(clippy::cargo)]
#![allow(ambiguous_glob_reexports)]
#![deny(clippy::cargo_common_metadata)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::ptr_cast_constness,
clippy::unsafe_derive_deserialize,
clippy::similar_names,
clippy::too_many_lines,
clippy::into_iter_without_iter, // broken
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,
@ -73,9 +49,6 @@ Welcome to `LibAFL`
while_true while_true
) )
)] )]
// Till they fix this buggy lint in clippy
#![allow(clippy::borrow_as_ptr)]
#![allow(clippy::borrow_deref_ref)]
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[macro_use] #[macro_use]

View File

@ -23,6 +23,7 @@ use crate::{
/// The intent is that the value is something with interior mutability which the target could write to even though this /// The intent is that the value is something with interior mutability which the target could write to even though this
/// observer has a reference to it. Use [`RefCellValueObserver`] if using a [`RefCell`] around the value. /// observer has a reference to it. Use [`RefCellValueObserver`] if using a [`RefCell`] around the value.
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
#[allow(clippy::unsafe_derive_deserialize)]
pub struct ValueObserver<'a, T> { pub struct ValueObserver<'a, T> {
/// The name of this observer. /// The name of this observer.
name: Cow<'static, str>, name: Cow<'static, str>,
@ -82,6 +83,7 @@ impl<T: Hash> ObserverWithHashField for ValueObserver<'_, T> {
/// A simple observer with a single [`RefCell`]'d value. /// A simple observer with a single [`RefCell`]'d value.
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
#[allow(clippy::unsafe_derive_deserialize)]
pub struct RefCellValueObserver<'a, T> { pub struct RefCellValueObserver<'a, T> {
/// The name of this observer. /// The name of this observer.
name: Cow<'static, str>, name: Cow<'static, str>,

View File

@ -170,6 +170,9 @@ serial_test = { workspace = true, optional = true, default-features = false, fea
# Document all features of this crate (for `cargo doc`) # Document all features of this crate (for `cargo doc`)
document-features = { workspace = true, optional = true } document-features = { workspace = true, optional = true }
[lints]
workspace = true
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
libc = { workspace = true } # For (*nix) libc libc = { workspace = true } # For (*nix) libc
uds = { version = "0.4.2", optional = true, default-features = false } uds = { version = "0.4.2", optional = true, default-features = false }

View File

@ -4,33 +4,11 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
/*! */ /*! */
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] #![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
#![forbid(unexpected_cfgs)]
#![allow(incomplete_features)]
#![no_std] #![no_std]
// For `type_eq` // For `type_eq`
#![cfg_attr(nightly, feature(specialization))] #![cfg_attr(nightly, feature(specialization))]
// For `std::simd` // For `std::simd`
#![cfg_attr(nightly, feature(portable_simd))] #![cfg_attr(nightly, feature(portable_simd))]
#![warn(clippy::cargo)]
#![allow(ambiguous_glob_reexports)]
#![deny(clippy::cargo_common_metadata)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::ptr_cast_constness,
clippy::negative_feature_names,
clippy::too_many_lines
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,
@ -71,9 +49,6 @@
while_true while_true
) )
)] )]
// Till they fix this buggy lint in clippy
#![allow(clippy::borrow_as_ptr)]
#![allow(clippy::borrow_deref_ref)]
/// We need some sort of "[`String`]" for errors in `no_alloc`... /// We need some sort of "[`String`]" for errors in `no_alloc`...
/// We can only support `'static` without allocator, so let's do that. /// We can only support `'static` without allocator, so let's do that.
@ -707,7 +682,7 @@ where
type SliceRef = &'a [T]; type SliceRef = &'a [T];
fn as_slice(&'a self) -> Self::SliceRef { fn as_slice(&'a self) -> Self::SliceRef {
&*self self
} }
} }

View File

@ -2654,6 +2654,7 @@ where
/// It is supposed that the message is never unmapped. /// It is supposed that the message is never unmapped.
#[inline] #[inline]
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
#[allow(clippy::too_many_lines)]
unsafe fn handle_new_msgs(&mut self, client_id: ClientId) -> Result<bool, Error> { unsafe fn handle_new_msgs(&mut self, client_id: ClientId) -> Result<bool, Error> {
let mut new_messages = false; let mut new_messages = false;

View File

@ -1212,7 +1212,7 @@ mod tests {
proc, proc,
cur, cur,
proc, proc,
&mut out as *mut _, std::ptr::addr_of_mut!(out),
0, 0,
true, true,
DUPLICATE_SAME_ACCESS, DUPLICATE_SAME_ACCESS,
@ -1237,7 +1237,7 @@ mod tests {
} else if cfg!(target_arch = "aarch64") { } else if cfg!(target_arch = "aarch64") {
c.ctx.ContextFlags = CONTEXT_FULL_ARM64; c.ctx.ContextFlags = CONTEXT_FULL_ARM64;
} }
unsafe { GetThreadContext(thread, &mut c.ctx as *mut _).unwrap() }; unsafe { GetThreadContext(thread, std::ptr::addr_of_mut!(c.ctx)).unwrap() };
let mut writer = BufWriter::new(stdout()); let mut writer = BufWriter::new(stdout());
dump_registers(&mut writer, &c.ctx).unwrap(); dump_registers(&mut writer, &c.ctx).unwrap();

View File

@ -513,7 +513,7 @@ impl<'a, T> From<OwnedMutSlice<'a, T>> for OwnedSlice<'a, T> {
Self { Self {
inner: match mut_slice.inner { inner: match mut_slice.inner {
OwnedMutSliceInner::RefRaw(ptr, len, unsafe_marker) => { OwnedMutSliceInner::RefRaw(ptr, len, unsafe_marker) => {
OwnedSliceInner::RefRaw(ptr as _, len, unsafe_marker) OwnedSliceInner::RefRaw(ptr.cast_const(), len, unsafe_marker)
} }
OwnedMutSliceInner::Ref(r) => OwnedSliceInner::Ref(r as _), OwnedMutSliceInner::Ref(r) => OwnedSliceInner::Ref(r as _),
OwnedMutSliceInner::Owned(v) => OwnedSliceInner::Owned(v), OwnedMutSliceInner::Owned(v) => OwnedSliceInner::Owned(v),

View File

@ -1421,7 +1421,7 @@ pub mod win32_shmem {
let handle = OpenFileMappingA( let handle = OpenFileMappingA(
FILE_MAP_ALL_ACCESS.0, FILE_MAP_ALL_ACCESS.0,
BOOL(0), BOOL(0),
PCSTR(map_str_bytes.as_ptr() as *mut _), PCSTR(map_str_bytes.as_ptr().cast_mut()),
)?; )?;
let map = let map =

View File

@ -349,7 +349,7 @@ mod tests {
let bytes_read = bytes_reader.next_sub_slice_truncated(8); let bytes_read = bytes_reader.next_sub_slice_truncated(8);
let bytes_read_ref: &[u8] = &[]; let bytes_read_ref: &[u8] = &[];
assert_eq!(&*bytes_read.as_slice(), bytes_read_ref); assert_eq!(bytes_read.as_slice(), bytes_read_ref);
} }
#[test] #[test]

View File

@ -55,3 +55,6 @@ serde = { workspace = true, default-features = false, features = [
"alloc", "alloc",
"derive", "derive",
] } # serialization lib ] } # serialization lib
[lints]
workspace = true

View File

@ -1,21 +1,5 @@
//! Compiler Wrapper from `LibAFL` //! Compiler Wrapper from `LibAFL`
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![forbid(unexpected_cfgs)]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::unreadable_literal
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,

View File

@ -34,6 +34,9 @@ build = ["which", "cmake"]
clone = ["which"] clone = ["which"]
[dependencies] [dependencies]
which = { version = "6.0.3", optional = true } which = { workspace = true, optional = true }
cmake = { version = "0.1.51", optional = true } cmake = { workspace = true, optional = true }
log = "0.4.22" log = { workspace = true }
[lints]
workspace = true

View File

@ -1,7 +1,5 @@
//! This is a 'meta-package' for libafl that exposes a consistent URL and commit hash for the //! This is a 'meta-package' for libafl that exposes a consistent URL and commit hash for the
//! [`SymCC` fork](https://github.com/AFLplusplus/symcc). //! [`SymCC` fork](https://github.com/AFLplusplus/symcc).
#![allow(clippy::module_name_repetitions)]
#![forbid(unexpected_cfgs)]
/// The URL of the `LibAFL` `SymCC` fork. /// The URL of the `LibAFL` `SymCC` fork.
pub const SYMCC_REPO_URL: &str = "https://github.com/AFLplusplus/symcc.git"; pub const SYMCC_REPO_URL: &str = "https://github.com/AFLplusplus/symcc.git";
@ -65,6 +63,8 @@ pub use clone::clone_symcc;
#[cfg(feature = "build")] #[cfg(feature = "build")]
mod build { mod build {
#![allow(clippy::module_name_repetitions)]
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
/// Builds `SymCC` at the given directory using [`cmake`](https://crates.io/crates/cmake). /// Builds `SymCC` at the given directory using [`cmake`](https://crates.io/crates/cmake).

View File

@ -32,9 +32,6 @@ all-features = true
no-cpp-runtime = [] no-cpp-runtime = []
[dependencies] [dependencies]
unchecked_unwrap = "4.0.0"
ctor = "0.2.8"
libc = "0.2.159"
libafl = { path = "../../libafl", version = "0.13.2", default-features = false, features = [ libafl = { path = "../../libafl", version = "0.13.2", default-features = false, features = [
"std", "std",
"serdeany_autoreg", "serdeany_autoreg",
@ -44,9 +41,16 @@ libafl_bolts = { path = "../../libafl_bolts", version = "0.13.2", default-featur
"serdeany_autoreg", "serdeany_autoreg",
] } ] }
unchecked_unwrap = "4.0.0"
ctor = "0.2.8"
libc = { workspace = true }
[build-dependencies] [build-dependencies]
cmake = "0.1.51" cmake = { workspace = true }
bindgen = "0.70.1" bindgen = { workspace = true }
regex = "1.10.6" regex = { workspace = true }
which = "6.0.3" which = { workspace = true }
symcc_libafl = { path = "../symcc_libafl", version = "0.13.2" } symcc_libafl = { path = "../symcc_libafl", version = "0.13.2" }
[lints]
workspace = true

View File

@ -27,12 +27,6 @@
//! # SymCC and SymQEMU expect to runtime file to be called `libSymRuntime.so`. Setting the name to `SymRuntime` achieves this. //! # SymCC and SymQEMU expect to runtime file to be called `libSymRuntime.so`. Setting the name to `SymRuntime` achieves this.
//! name = "SymRuntime" //! name = "SymRuntime"
//! ``` //! ```
#![allow(
clippy::module_name_repetitions,
clippy::missing_panics_doc,
clippy::pub_underscore_fields
)]
#![forbid(unexpected_cfgs)]
pub mod filter; pub mod filter;
pub mod tracing; pub mod tracing;
@ -40,8 +34,9 @@ pub mod tracing;
// The following exports are used by the `export_runtime` macro. They are therefore exported, but hidden from docs, as they are not supposed to be used directly by the user. // The following exports are used by the `export_runtime` macro. They are therefore exported, but hidden from docs, as they are not supposed to be used directly by the user.
#[doc(hidden)] #[doc(hidden)]
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[allow(clippy::mixed_attributes_style)]
pub mod cpp_runtime { pub mod cpp_runtime {
#![allow(clippy::mixed_attributes_style)]
#![allow(clippy::pub_underscore_fields)]
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(non_snake_case)] #![allow(non_snake_case)]

View File

@ -22,4 +22,7 @@ categories = [
[dependencies] [dependencies]
libafl = { path = "../../../libafl" } libafl = { path = "../../../libafl" }
libafl_bolts = { path = "../../../libafl_bolts" } libafl_bolts = { path = "../../../libafl_bolts" }
clap = { version = "4.5.18", features = ["derive"] } clap = { workspace = true, features = ["derive"] }
[lints]
workspace = true

View File

@ -1,7 +1,6 @@
//! This is a straight-forward command line utility that can dump constraints written by a tracing runtime. //! This is a straight-forward command line utility that can dump constraints written by a tracing runtime.
//! It achieves this by running an instrumented target program with the necessary environment variables set. //! It achieves this by running an instrumented target program with the necessary environment variables set.
//! When the program has finished executing, it dumps the traced constraints to a file. //! When the program has finished executing, it dumps the traced constraints to a file.
#![forbid(unexpected_cfgs)]
use std::{ use std::{
ffi::OsString, ffi::OsString,

View File

@ -8,7 +8,7 @@ documentation = "https://docs.rs/libafl"
repository = "https://github.com/AFLplusplus/LibAFL/" repository = "https://github.com/AFLplusplus/LibAFL/"
readme = "../README.md" readme = "../README.md"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
keywords = ["fuzzing", "libafl", "symbolic", "symcc", "symqemu", "fuzzer"] keywords = ["fuzzing", "libafl", "symbolic", "symcc", "symqemu"]
categories = [ categories = [
"development-tools::testing", "development-tools::testing",
"emulators", "emulators",
@ -25,3 +25,6 @@ name = "SymRuntime"
[dependencies] [dependencies]
symcc_runtime = { path = "../../symcc_runtime" } symcc_runtime = { path = "../../symcc_runtime" }
[lints]
workspace = true

View File

@ -24,3 +24,6 @@ proc-macro = true
syn = { version = "2.0.77", features = ["full", "extra-traits"] } syn = { version = "2.0.77", features = ["full", "extra-traits"] }
quote = "1.0.37" quote = "1.0.37"
proc-macro2 = "1.0.86" proc-macro2 = "1.0.86"
[lints]
workspace = true

View File

@ -1,22 +1,6 @@
//! Derives for `LibAFL` //! Derives for `LibAFL`
#![no_std] #![no_std]
#![forbid(unexpected_cfgs)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::unreadable_literal
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,

View File

@ -46,13 +46,6 @@ auto-download = ["frida-gum-sys/auto-download", "frida-gum/auto-download"]
[build-dependencies] [build-dependencies]
cc = { workspace = true, features = ["parallel"] } cc = { workspace = true, features = ["parallel"] }
[target.'cfg(target_arch = "aarch64")'.dependencies]
yaxpeax-arm = "0.3.0"
[target.'cfg(target_arch = "x86_64")'.dependencies]
yaxpeax-x86 = "2.0.0"
iced-x86 = { version = "1.21.0", features = ["code_asm"], optional = true }
[dependencies] [dependencies]
libafl = { path = "../libafl", default-features = false, version = "0.13.2", features = [ libafl = { path = "../libafl", default-features = false, version = "0.13.2", features = [
"std", "std",
@ -101,12 +94,6 @@ yaxpeax-arch = "0.3.2"
document-features = { workspace = true, optional = true } # Document all features of this crate (for `cargo doc`) document-features = { workspace = true, optional = true } # Document all features of this crate (for `cargo doc`)
[target.'cfg(windows)'.dependencies]
winsafe = { version = "0.0.22", features = ["kernel"] }
[target.'cfg(target_vendor="apple")'.dependencies]
mach-sys = { version = "0.5.4" }
[dev-dependencies] [dev-dependencies]
serial_test = { workspace = true, default-features = false, features = [ serial_test = { workspace = true, default-features = false, features = [
"logging", "logging",
@ -115,3 +102,19 @@ clap = { workspace = true, features = ["derive"] }
libloading = "0.8.5" libloading = "0.8.5"
mimalloc = { workspace = true, default-features = false } mimalloc = { workspace = true, default-features = false }
dlmalloc = { version = "0.2.6", features = ["global"] } dlmalloc = { version = "0.2.6", features = ["global"] }
[lints]
workspace = true
[target.'cfg(target_arch = "aarch64")'.dependencies]
yaxpeax-arm = "0.3.0"
[target.'cfg(target_arch = "x86_64")'.dependencies]
yaxpeax-x86 = "2.0.0"
iced-x86 = { version = "1.21.0", features = ["code_asm"], optional = true }
[target.'cfg(windows)'.dependencies]
winsafe = { version = "0.0.22", features = ["kernel"] }
[target.'cfg(target_vendor="apple")'.dependencies]
mach-sys = { version = "0.5.4" }

View File

@ -512,7 +512,7 @@ impl Allocator {
return true; return true;
} }
if !self.is_managed(address as *mut c_void) { if !self.is_managed(address.cast_mut()) {
return true; return true;
} }

View File

@ -605,6 +605,7 @@ impl AsanErrorsObserver {
/// ///
/// # Safety /// # Safety
/// The field should not be accessed multiple times at the same time (i.e., from different threads)! /// The field should not be accessed multiple times at the same time (i.e., from different threads)!
#[must_use]
pub fn from_static_asan_errors() -> Self { pub fn from_static_asan_errors() -> Self {
Self::Static Self::Static
} }

View File

@ -147,6 +147,7 @@ pub struct FridaInstrumentationHelperBuilder {
impl FridaInstrumentationHelperBuilder { impl FridaInstrumentationHelperBuilder {
/// Create a new [`FridaInstrumentationHelperBuilder`] /// Create a new [`FridaInstrumentationHelperBuilder`]
#[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
} }
@ -409,6 +410,7 @@ impl FridaInstrumentationHelper<'_, ()> {
/// ///
/// See the documentation of [`FridaInstrumentationHelperBuilder`] /// See the documentation of [`FridaInstrumentationHelperBuilder`]
/// for more details. /// for more details.
#[must_use]
pub fn builder() -> FridaInstrumentationHelperBuilder { pub fn builder() -> FridaInstrumentationHelperBuilder {
FridaInstrumentationHelperBuilder::default() FridaInstrumentationHelperBuilder::default()
} }
@ -644,6 +646,7 @@ where
} }
/// Returns ref to the Transformer /// Returns ref to the Transformer
#[must_use]
pub fn transformer(&self) -> &Transformer<'a> { pub fn transformer(&self) -> &Transformer<'a> {
&self.transformer &self.transformer
} }
@ -671,6 +674,7 @@ where
} }
/// If stalker is enabled /// If stalker is enabled
#[must_use]
pub fn stalker_enabled(&self) -> bool { pub fn stalker_enabled(&self) -> bool {
self.stalker_enabled self.stalker_enabled
} }
@ -684,6 +688,7 @@ where
} }
/// Ranges /// Ranges
#[must_use]
pub fn ranges(&self) -> Ref<RangeMap<usize, (u16, String)>> { pub fn ranges(&self) -> Ref<RangeMap<usize, (u16, String)>> {
self.ranges.borrow() self.ranges.borrow()
} }

View File

@ -7,25 +7,6 @@ Additional documentation is available in [the `LibAFL` book](https://aflplus.plu
*/ */
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] #![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
#![forbid(unexpected_cfgs)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::unreadable_literal,
clippy::ptr_cast_constness,
clippy::must_use_candidate,
clippy::too_many_arguments
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,

View File

@ -162,6 +162,7 @@ const X86_64_REGS: [(RegSpec, X86Register); 34] = [
/// Get the value of a register given a context /// Get the value of a register given a context
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[must_use]
pub fn get_register(context: &CpuContext, reg: X86Register) -> u64 { pub fn get_register(context: &CpuContext, reg: X86Register) -> u64 {
match reg { match reg {
X86Register::Rax => context.rax(), X86Register::Rax => context.rax(),
@ -224,8 +225,9 @@ pub(crate) fn frida_to_cs(
} }
} }
#[cfg(target_arch = "x86_64")]
/// Get the `base`, `idx`, `scale`, `disp` for each operand /// Get the `base`, `idx`, `scale`, `disp` for each operand
#[cfg(target_arch = "x86_64")]
#[must_use]
pub fn operand_details(operand: &Operand) -> Option<(X86Register, X86Register, u8, i32)> { pub fn operand_details(operand: &Operand) -> Option<(X86Register, X86Register, u8, i32)> {
match operand { match operand {
Operand::MemDeref { base } => { Operand::MemDeref { base } => {
@ -263,8 +265,9 @@ pub fn operand_details(operand: &Operand) -> Option<(X86Register, X86Register, u
} }
} }
#[cfg(target_arch = "x86_64")]
/// Get the immediate value of the operand /// Get the immediate value of the operand
#[cfg(target_arch = "x86_64")]
#[must_use]
pub fn immediate_value(operand: &Operand) -> Option<i64> { pub fn immediate_value(operand: &Operand) -> Option<i64> {
match operand { match operand {
Operand::ImmediateI8 { imm } => Some(i64::from(*imm)), Operand::ImmediateI8 { imm } => Some(i64::from(*imm)),
@ -290,8 +293,9 @@ pub enum AccessType {
Write, Write,
} }
#[cfg(target_arch = "x86_64")]
/// Disassemble "count" number of instructions /// Disassemble "count" number of instructions
#[cfg(target_arch = "x86_64")]
#[must_use]
pub fn disas_count(decoder: &InstDecoder, data: &[u8], count: usize) -> Vec<Instruction> { pub fn disas_count(decoder: &InstDecoder, data: &[u8], count: usize) -> Vec<Instruction> {
let mut counter = count; let mut counter = count;
let mut ret = vec![]; let mut ret = vec![];
@ -312,6 +316,7 @@ pub fn disas_count(decoder: &InstDecoder, data: &[u8], count: usize) -> Vec<Inst
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
/// Disassemble "count" number of instructions /// Disassemble "count" number of instructions
#[must_use]
pub fn disas_count(decoder: &InstDecoder, data: &[u8], _count: usize) -> Vec<Instruction> { pub fn disas_count(decoder: &InstDecoder, data: &[u8], _count: usize) -> Vec<Instruction> {
let mut ret = vec![]; let mut ret = vec![];

View File

@ -50,3 +50,6 @@ features = ["document-features"]
all-features = true all-features = true
rustdoc-args = ["--cfg", "docsrs"] rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true

View File

@ -75,28 +75,6 @@
//! to the runtime (e.g., to prevent coverage being collected on the runtime). //! to the runtime (e.g., to prevent coverage being collected on the runtime).
//! //!
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] #![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
#![forbid(unexpected_cfgs)]
#![warn(clippy::cargo)]
#![allow(ambiguous_glob_reexports)]
#![deny(clippy::cargo_common_metadata)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::ptr_cast_constness,
clippy::unsafe_derive_deserialize,
clippy::similar_names,
clippy::too_many_lines
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,
@ -137,9 +115,6 @@
while_true while_true
) )
)] )]
// Till they fix this buggy lint in clippy
#![allow(clippy::borrow_as_ptr)]
#![allow(clippy::borrow_deref_ref)]
use std::ffi::{c_char, c_int}; use std::ffi::{c_char, c_int};

View File

@ -38,3 +38,6 @@ libafl_targets = { path = "../libafl_targets", version = "0.13.2", features = [
nix = { workspace = true, default-features = true, features = ["fs"] } nix = { workspace = true, default-features = true, features = ["fs"] }
typed-builder = { workspace = true } typed-builder = { workspace = true }
[lints]
workspace = true

View File

@ -1,6 +1,3 @@
#![allow(clippy::module_name_repetitions, clippy::missing_panics_doc)]
#![forbid(unexpected_cfgs)]
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub mod executor; pub mod executor;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]

View File

@ -142,3 +142,6 @@ cc = { workspace = true }
[lib] [lib]
name = "libafl_qemu" name = "libafl_qemu"
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
[lints]
workspace = true

View File

@ -39,3 +39,6 @@ cc = { workspace = true }
regex = { workspace = true } regex = { workspace = true }
rustversion = { workspace = true } rustversion = { workspace = true }
rustc_version = "0.4.1" rustc_version = "0.4.1"
[lints]
workspace = true

View File

@ -1,6 +1,3 @@
#![forbid(unexpected_cfgs)]
#![allow(clippy::missing_panics_doc)]
// #[rustversion::nightly] // #[rustversion::nightly]
// use std::io::{BufRead, BufReader}; // use std::io::{BufRead, BufReader};
use std::{ use std::{

View File

@ -1,11 +0,0 @@
#![forbid(unexpected_cfgs)]
use std::path::PathBuf;
use libafl_qemu_build::build_with_bindings;
// RUST_BACKTRACE=1 OUT_DIR=/tmp/foo/a/b/c cargo run
fn main() {
let bfile = PathBuf::from("generated_qemu_bindings.rs");
build_with_bindings("arm", false, false, None, &bfile);
}

View File

@ -65,3 +65,6 @@ pyo3 = { workspace = true, optional = true }
libafl_qemu_build = { path = "../libafl_qemu_build", version = "0.13.2" } libafl_qemu_build = { path = "../libafl_qemu_build", version = "0.13.2" }
pyo3-build-config = { workspace = true, optional = true } pyo3-build-config = { workspace = true, optional = true }
rustversion = { workspace = true } rustversion = { workspace = true }
[lints]
workspace = true

View File

@ -65,6 +65,7 @@ pub fn build() {
}) })
}; };
println!("cargo:rerun-if-env-changed=CPU_TARGET"); println!("cargo:rerun-if-env-changed=CPU_TARGET");
println!("cargo:rerun-if-env-changed=LIBAFL_QEMU_GEN_STUBS");
println!("cargo:rustc-cfg=cpu_target=\"{cpu_target}\""); println!("cargo:rustc-cfg=cpu_target=\"{cpu_target}\"");
println!("cargo::rustc-check-cfg=cfg(cpu_target, values(\"x86_64\", \"arm\", \"aarch64\", \"i386\", \"mips\", \"ppc\", \"hexagon\"))"); println!("cargo::rustc-check-cfg=cfg(cpu_target, values(\"x86_64\", \"arm\", \"aarch64\", \"i386\", \"mips\", \"ppc\", \"hexagon\"))");
@ -78,7 +79,7 @@ pub fn build() {
let src_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let src_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let src_dir = PathBuf::from(src_dir); let src_dir = PathBuf::from(src_dir);
let stub_bindings_file = src_dir.join("src/x86_64_stub_bindings.rs"); let stub_bindings_file = src_dir.join("src/bindings/x86_64_stub_bindings.rs");
if env::var("DOCS_RS").is_ok() || cfg!(feature = "clippy") { if env::var("DOCS_RS").is_ok() || cfg!(feature = "clippy") {
// Only build when we're not generating docs and not in clippy // Only build when we're not generating docs and not in clippy

View File

@ -0,0 +1,18 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused_mut)]
#![allow(unused)]
#![allow(unused_variables)]
#![allow(clippy::all)]
#![allow(clippy::pedantic)]
#![allow(improper_ctypes)]
#[cfg(all(not(feature = "clippy"), target_os = "linux"))]
#[rustfmt::skip]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
#[cfg(any(feature = "clippy", not(target_os = "linux")))]
mod x86_64_stub_bindings;
#[cfg(any(feature = "clippy", not(target_os = "linux")))]
pub use x86_64_stub_bindings::*;

File diff suppressed because it is too large Load Diff

View File

@ -5,14 +5,6 @@ Have a look at `libafl_qemu` for higher-level abstractions.
__Warning__: The documentation is built by default for `x86_64` in `usermode`. To access the documentation of other architectures or systemmode, the documentation must be rebuilt with the right features. __Warning__: The documentation is built by default for `x86_64` in `usermode`. To access the documentation of other architectures or systemmode, the documentation must be rebuilt with the right features.
*/ */
#![forbid(unexpected_cfgs)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(improper_ctypes)]
#![allow(unused_mut)]
#![allow(clippy::all)]
#![allow(clippy::pedantic)]
#![cfg_attr(nightly, feature(used_with_arg))] #![cfg_attr(nightly, feature(used_with_arg))]
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
@ -22,30 +14,9 @@ use std::ffi::c_void;
use num_enum::{IntoPrimitive, TryFromPrimitive}; use num_enum::{IntoPrimitive, TryFromPrimitive};
use strum_macros::EnumIter; use strum_macros::EnumIter;
#[cfg(all(not(feature = "clippy"), target_os = "linux"))] mod bindings;
mod bindings {
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(improper_ctypes)]
#![allow(unused_mut)]
#![allow(unused)]
#![allow(unused_variables)]
#![allow(clippy::all)]
#![allow(clippy::pedantic)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
#[cfg(all(not(feature = "clippy"), target_os = "linux"))]
pub use bindings::*; pub use bindings::*;
#[cfg(any(feature = "clippy", not(target_os = "linux")))]
#[allow(dead_code)]
#[rustfmt::skip]
mod x86_64_stub_bindings;
#[cfg(any(feature = "clippy", not(target_os = "linux")))]
pub use x86_64_stub_bindings::*;
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
mod usermode; mod usermode;
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
@ -57,6 +28,7 @@ pub use usermode::*;
// pub use systemmode::*; // pub use systemmode::*;
/// Safe linking with of extern "C" functions. /// Safe linking with of extern "C" functions.
///
/// This macro makes sure the declared symbol is defined *at link time*, avoiding declaring non-existant symbols /// This macro makes sure the declared symbol is defined *at link time*, avoiding declaring non-existant symbols
/// that could be silently ignored during linking if unused. /// that could be silently ignored during linking if unused.
/// ///
@ -153,11 +125,13 @@ pub enum MmapPerms {
// from include/exec/memop.h // from include/exec/memop.h
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[must_use]
pub fn memop_size(op: MemOp) -> u32 { pub fn memop_size(op: MemOp) -> u32 {
1 << op.bitand(MemOp_MO_SIZE).0 1 << op.bitand(MemOp_MO_SIZE).0
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[must_use]
pub fn memop_big_endian(op: MemOp) -> bool { pub fn memop_big_endian(op: MemOp) -> bool {
op.bitand(MemOp_MO_BSWAP) == MemOp_MO_BE op.bitand(MemOp_MO_BSWAP) == MemOp_MO_BE
} }
@ -165,6 +139,7 @@ pub fn memop_big_endian(op: MemOp) -> bool {
// from include/qemu/plugin.h // from include/qemu/plugin.h
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[must_use]
pub fn make_plugin_meminfo(oi: MemOpIdx, rw: qemu_plugin_mem_rw) -> qemu_plugin_meminfo_t { pub fn make_plugin_meminfo(oi: MemOpIdx, rw: qemu_plugin_mem_rw) -> qemu_plugin_meminfo_t {
oi | (rw.0 << 16) oi | (rw.0 << 16)
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
/* 1.83.0-nightly */ /* 1.83.0-nightly */
/* qemu git hash: d6637939526f453c69f4c6bfe4635feb5dc5c0be */ /* qemu git hash: d6637939526f453c69f4c6bfe4635feb5dc5c0be */
/* automatically generated by rust-bindgen 0.69.4 */ /* automatically generated by rust-bindgen 0.70.1 */
pub const LIBAFL_SYNC_EXIT_OPCODE: u32 = 1727150607; pub const LIBAFL_SYNC_EXIT_OPCODE: u32 = 1727150607;
pub const LIBAFL_BACKDOOR_OPCODE: u32 = 1156725263; pub const LIBAFL_BACKDOOR_OPCODE: u32 = 1156725263;
pub const LIBAFL_QEMU_TEST_VALUE: i64 = -2401053089206453570; pub const LIBAFL_QEMU_TEST_VALUE: u32 = 3405691582;
pub const LIBAFL_QEMU_HDR_VERSION_NUMBER: u32 = 73; pub const LIBAFL_QEMU_HDR_VERSION_NUMBER: u32 = 73;
pub const _STDIO_H: u32 = 1; pub const _STDIO_H: u32 = 1;
pub const _FEATURES_H: u32 = 1; pub const _FEATURES_H: u32 = 1;
@ -235,31 +235,12 @@ pub type __pid_t = ::std::os::raw::c_int;
pub struct __fsid_t { pub struct __fsid_t {
pub __val: [::std::os::raw::c_int; 2usize], pub __val: [::std::os::raw::c_int; 2usize],
} }
#[test] #[allow(clippy::unnecessary_operation, clippy::identity_op)]
fn bindgen_test_layout___fsid_t() { const _: () = {
const UNINIT: ::std::mem::MaybeUninit<__fsid_t> = ::std::mem::MaybeUninit::uninit(); ["Size of __fsid_t"][::std::mem::size_of::<__fsid_t>() - 8usize];
let ptr = UNINIT.as_ptr(); ["Alignment of __fsid_t"][::std::mem::align_of::<__fsid_t>() - 4usize];
assert_eq!( ["Offset of field: __fsid_t::__val"][::std::mem::offset_of!(__fsid_t, __val) - 0usize];
::std::mem::size_of::<__fsid_t>(), };
8usize,
concat!("Size of: ", stringify!(__fsid_t))
);
assert_eq!(
::std::mem::align_of::<__fsid_t>(),
4usize,
concat!("Alignment of ", stringify!(__fsid_t))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__val) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__fsid_t),
"::",
stringify!(__val)
)
);
}
pub type __clock_t = ::std::os::raw::c_long; pub type __clock_t = ::std::os::raw::c_long;
pub type __rlim_t = ::std::os::raw::c_ulong; pub type __rlim_t = ::std::os::raw::c_ulong;
pub type __rlim64_t = ::std::os::raw::c_ulong; pub type __rlim64_t = ::std::os::raw::c_ulong;
@ -300,42 +281,17 @@ pub union __mbstate_t__bindgen_ty_1 {
pub __wch: ::std::os::raw::c_uint, pub __wch: ::std::os::raw::c_uint,
pub __wchb: [::std::os::raw::c_char; 4usize], pub __wchb: [::std::os::raw::c_char; 4usize],
} }
#[test] #[allow(clippy::unnecessary_operation, clippy::identity_op)]
fn bindgen_test_layout___mbstate_t__bindgen_ty_1() { const _: () = {
const UNINIT: ::std::mem::MaybeUninit<__mbstate_t__bindgen_ty_1> = ["Size of __mbstate_t__bindgen_ty_1"]
::std::mem::MaybeUninit::uninit(); [::std::mem::size_of::<__mbstate_t__bindgen_ty_1>() - 4usize];
let ptr = UNINIT.as_ptr(); ["Alignment of __mbstate_t__bindgen_ty_1"]
assert_eq!( [::std::mem::align_of::<__mbstate_t__bindgen_ty_1>() - 4usize];
::std::mem::size_of::<__mbstate_t__bindgen_ty_1>(), ["Offset of field: __mbstate_t__bindgen_ty_1::__wch"]
4usize, [::std::mem::offset_of!(__mbstate_t__bindgen_ty_1, __wch) - 0usize];
concat!("Size of: ", stringify!(__mbstate_t__bindgen_ty_1)) ["Offset of field: __mbstate_t__bindgen_ty_1::__wchb"]
); [::std::mem::offset_of!(__mbstate_t__bindgen_ty_1, __wchb) - 0usize];
assert_eq!( };
::std::mem::align_of::<__mbstate_t__bindgen_ty_1>(),
4usize,
concat!("Alignment of ", stringify!(__mbstate_t__bindgen_ty_1))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__wch) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__mbstate_t__bindgen_ty_1),
"::",
stringify!(__wch)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__wchb) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__mbstate_t__bindgen_ty_1),
"::",
stringify!(__wchb)
)
);
}
impl Default for __mbstate_t__bindgen_ty_1 { impl Default for __mbstate_t__bindgen_ty_1 {
fn default() -> Self { fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit(); let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
@ -350,41 +306,15 @@ impl ::std::fmt::Debug for __mbstate_t__bindgen_ty_1 {
write!(f, "__mbstate_t__bindgen_ty_1 {{ union }}") write!(f, "__mbstate_t__bindgen_ty_1 {{ union }}")
} }
} }
#[test] #[allow(clippy::unnecessary_operation, clippy::identity_op)]
fn bindgen_test_layout___mbstate_t() { const _: () = {
const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit(); ["Size of __mbstate_t"][::std::mem::size_of::<__mbstate_t>() - 8usize];
let ptr = UNINIT.as_ptr(); ["Alignment of __mbstate_t"][::std::mem::align_of::<__mbstate_t>() - 4usize];
assert_eq!( ["Offset of field: __mbstate_t::__count"]
::std::mem::size_of::<__mbstate_t>(), [::std::mem::offset_of!(__mbstate_t, __count) - 0usize];
8usize, ["Offset of field: __mbstate_t::__value"]
concat!("Size of: ", stringify!(__mbstate_t)) [::std::mem::offset_of!(__mbstate_t, __value) - 4usize];
); };
assert_eq!(
::std::mem::align_of::<__mbstate_t>(),
4usize,
concat!("Alignment of ", stringify!(__mbstate_t))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__count) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__mbstate_t),
"::",
stringify!(__count)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__value) as usize - ptr as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(__mbstate_t),
"::",
stringify!(__value)
)
);
}
impl Default for __mbstate_t { impl Default for __mbstate_t {
fn default() -> Self { fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit(); let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
@ -409,41 +339,13 @@ pub struct _G_fpos_t {
pub __pos: __off_t, pub __pos: __off_t,
pub __state: __mbstate_t, pub __state: __mbstate_t,
} }
#[test] #[allow(clippy::unnecessary_operation, clippy::identity_op)]
fn bindgen_test_layout__G_fpos_t() { const _: () = {
const UNINIT: ::std::mem::MaybeUninit<_G_fpos_t> = ::std::mem::MaybeUninit::uninit(); ["Size of _G_fpos_t"][::std::mem::size_of::<_G_fpos_t>() - 16usize];
let ptr = UNINIT.as_ptr(); ["Alignment of _G_fpos_t"][::std::mem::align_of::<_G_fpos_t>() - 8usize];
assert_eq!( ["Offset of field: _G_fpos_t::__pos"][::std::mem::offset_of!(_G_fpos_t, __pos) - 0usize];
::std::mem::size_of::<_G_fpos_t>(), ["Offset of field: _G_fpos_t::__state"][::std::mem::offset_of!(_G_fpos_t, __state) - 8usize];
16usize, };
concat!("Size of: ", stringify!(_G_fpos_t))
);
assert_eq!(
::std::mem::align_of::<_G_fpos_t>(),
8usize,
concat!("Alignment of ", stringify!(_G_fpos_t))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__pos) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(_G_fpos_t),
"::",
stringify!(__pos)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__state) as usize - ptr as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(_G_fpos_t),
"::",
stringify!(__state)
)
);
}
impl Default for _G_fpos_t { impl Default for _G_fpos_t {
fn default() -> Self { fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit(); let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
@ -469,41 +371,14 @@ pub struct _G_fpos64_t {
pub __pos: __off64_t, pub __pos: __off64_t,
pub __state: __mbstate_t, pub __state: __mbstate_t,
} }
#[test] #[allow(clippy::unnecessary_operation, clippy::identity_op)]
fn bindgen_test_layout__G_fpos64_t() { const _: () = {
const UNINIT: ::std::mem::MaybeUninit<_G_fpos64_t> = ::std::mem::MaybeUninit::uninit(); ["Size of _G_fpos64_t"][::std::mem::size_of::<_G_fpos64_t>() - 16usize];
let ptr = UNINIT.as_ptr(); ["Alignment of _G_fpos64_t"][::std::mem::align_of::<_G_fpos64_t>() - 8usize];
assert_eq!( ["Offset of field: _G_fpos64_t::__pos"][::std::mem::offset_of!(_G_fpos64_t, __pos) - 0usize];
::std::mem::size_of::<_G_fpos64_t>(), ["Offset of field: _G_fpos64_t::__state"]
16usize, [::std::mem::offset_of!(_G_fpos64_t, __state) - 8usize];
concat!("Size of: ", stringify!(_G_fpos64_t)) };
);
assert_eq!(
::std::mem::align_of::<_G_fpos64_t>(),
8usize,
concat!("Alignment of ", stringify!(_G_fpos64_t))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__pos) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(_G_fpos64_t),
"::",
stringify!(__pos)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).__state) as usize - ptr as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(_G_fpos64_t),
"::",
stringify!(__state)
)
);
}
impl Default for _G_fpos64_t { impl Default for _G_fpos64_t {
fn default() -> Self { fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit(); let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
@ -574,311 +449,59 @@ pub struct _IO_FILE {
pub _mode: ::std::os::raw::c_int, pub _mode: ::std::os::raw::c_int,
pub _unused2: [::std::os::raw::c_char; 20usize], pub _unused2: [::std::os::raw::c_char; 20usize],
} }
#[test] #[allow(clippy::unnecessary_operation, clippy::identity_op)]
fn bindgen_test_layout__IO_FILE() { const _: () = {
const UNINIT: ::std::mem::MaybeUninit<_IO_FILE> = ::std::mem::MaybeUninit::uninit(); ["Size of _IO_FILE"][::std::mem::size_of::<_IO_FILE>() - 216usize];
let ptr = UNINIT.as_ptr(); ["Alignment of _IO_FILE"][::std::mem::align_of::<_IO_FILE>() - 8usize];
assert_eq!( ["Offset of field: _IO_FILE::_flags"][::std::mem::offset_of!(_IO_FILE, _flags) - 0usize];
::std::mem::size_of::<_IO_FILE>(), ["Offset of field: _IO_FILE::_IO_read_ptr"]
216usize, [::std::mem::offset_of!(_IO_FILE, _IO_read_ptr) - 8usize];
concat!("Size of: ", stringify!(_IO_FILE)) ["Offset of field: _IO_FILE::_IO_read_end"]
); [::std::mem::offset_of!(_IO_FILE, _IO_read_end) - 16usize];
assert_eq!( ["Offset of field: _IO_FILE::_IO_read_base"]
::std::mem::align_of::<_IO_FILE>(), [::std::mem::offset_of!(_IO_FILE, _IO_read_base) - 24usize];
8usize, ["Offset of field: _IO_FILE::_IO_write_base"]
concat!("Alignment of ", stringify!(_IO_FILE)) [::std::mem::offset_of!(_IO_FILE, _IO_write_base) - 32usize];
); ["Offset of field: _IO_FILE::_IO_write_ptr"]
assert_eq!( [::std::mem::offset_of!(_IO_FILE, _IO_write_ptr) - 40usize];
unsafe { ::std::ptr::addr_of!((*ptr)._flags) as usize - ptr as usize }, ["Offset of field: _IO_FILE::_IO_write_end"]
0usize, [::std::mem::offset_of!(_IO_FILE, _IO_write_end) - 48usize];
concat!( ["Offset of field: _IO_FILE::_IO_buf_base"]
"Offset of field: ", [::std::mem::offset_of!(_IO_FILE, _IO_buf_base) - 56usize];
stringify!(_IO_FILE), ["Offset of field: _IO_FILE::_IO_buf_end"]
"::", [::std::mem::offset_of!(_IO_FILE, _IO_buf_end) - 64usize];
stringify!(_flags) ["Offset of field: _IO_FILE::_IO_save_base"]
) [::std::mem::offset_of!(_IO_FILE, _IO_save_base) - 72usize];
); ["Offset of field: _IO_FILE::_IO_backup_base"]
assert_eq!( [::std::mem::offset_of!(_IO_FILE, _IO_backup_base) - 80usize];
unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_ptr) as usize - ptr as usize }, ["Offset of field: _IO_FILE::_IO_save_end"]
8usize, [::std::mem::offset_of!(_IO_FILE, _IO_save_end) - 88usize];
concat!( ["Offset of field: _IO_FILE::_markers"][::std::mem::offset_of!(_IO_FILE, _markers) - 96usize];
"Offset of field: ", ["Offset of field: _IO_FILE::_chain"][::std::mem::offset_of!(_IO_FILE, _chain) - 104usize];
stringify!(_IO_FILE), ["Offset of field: _IO_FILE::_fileno"][::std::mem::offset_of!(_IO_FILE, _fileno) - 112usize];
"::", ["Offset of field: _IO_FILE::_flags2"][::std::mem::offset_of!(_IO_FILE, _flags2) - 116usize];
stringify!(_IO_read_ptr) ["Offset of field: _IO_FILE::_old_offset"]
) [::std::mem::offset_of!(_IO_FILE, _old_offset) - 120usize];
); ["Offset of field: _IO_FILE::_cur_column"]
assert_eq!( [::std::mem::offset_of!(_IO_FILE, _cur_column) - 128usize];
unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_end) as usize - ptr as usize }, ["Offset of field: _IO_FILE::_vtable_offset"]
16usize, [::std::mem::offset_of!(_IO_FILE, _vtable_offset) - 130usize];
concat!( ["Offset of field: _IO_FILE::_shortbuf"]
"Offset of field: ", [::std::mem::offset_of!(_IO_FILE, _shortbuf) - 131usize];
stringify!(_IO_FILE), ["Offset of field: _IO_FILE::_lock"][::std::mem::offset_of!(_IO_FILE, _lock) - 136usize];
"::", ["Offset of field: _IO_FILE::_offset"][::std::mem::offset_of!(_IO_FILE, _offset) - 144usize];
stringify!(_IO_read_end) ["Offset of field: _IO_FILE::_codecvt"][::std::mem::offset_of!(_IO_FILE, _codecvt) - 152usize];
) ["Offset of field: _IO_FILE::_wide_data"]
); [::std::mem::offset_of!(_IO_FILE, _wide_data) - 160usize];
assert_eq!( ["Offset of field: _IO_FILE::_freeres_list"]
unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_base) as usize - ptr as usize }, [::std::mem::offset_of!(_IO_FILE, _freeres_list) - 168usize];
24usize, ["Offset of field: _IO_FILE::_freeres_buf"]
concat!( [::std::mem::offset_of!(_IO_FILE, _freeres_buf) - 176usize];
"Offset of field: ", ["Offset of field: _IO_FILE::_prevchain"]
stringify!(_IO_FILE), [::std::mem::offset_of!(_IO_FILE, _prevchain) - 184usize];
"::", ["Offset of field: _IO_FILE::_mode"][::std::mem::offset_of!(_IO_FILE, _mode) - 192usize];
stringify!(_IO_read_base) ["Offset of field: _IO_FILE::_unused2"][::std::mem::offset_of!(_IO_FILE, _unused2) - 196usize];
) };
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_base) as usize - ptr as usize },
32usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_IO_write_base)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_ptr) as usize - ptr as usize },
40usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_IO_write_ptr)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_end) as usize - ptr as usize },
48usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_IO_write_end)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._IO_buf_base) as usize - ptr as usize },
56usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_IO_buf_base)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._IO_buf_end) as usize - ptr as usize },
64usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_IO_buf_end)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._IO_save_base) as usize - ptr as usize },
72usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_IO_save_base)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._IO_backup_base) as usize - ptr as usize },
80usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_IO_backup_base)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._IO_save_end) as usize - ptr as usize },
88usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_IO_save_end)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._markers) as usize - ptr as usize },
96usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_markers)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._chain) as usize - ptr as usize },
104usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_chain)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._fileno) as usize - ptr as usize },
112usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_fileno)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._flags2) as usize - ptr as usize },
116usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_flags2)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._old_offset) as usize - ptr as usize },
120usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_old_offset)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._cur_column) as usize - ptr as usize },
128usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_cur_column)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._vtable_offset) as usize - ptr as usize },
130usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_vtable_offset)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._shortbuf) as usize - ptr as usize },
131usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_shortbuf)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._lock) as usize - ptr as usize },
136usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_lock)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._offset) as usize - ptr as usize },
144usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_offset)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._codecvt) as usize - ptr as usize },
152usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_codecvt)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._wide_data) as usize - ptr as usize },
160usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_wide_data)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._freeres_list) as usize - ptr as usize },
168usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_freeres_list)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._freeres_buf) as usize - ptr as usize },
176usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_freeres_buf)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._prevchain) as usize - ptr as usize },
184usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_prevchain)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._mode) as usize - ptr as usize },
192usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_mode)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr)._unused2) as usize - ptr as usize },
196usize,
concat!(
"Offset of field: ",
stringify!(_IO_FILE),
"::",
stringify!(_unused2)
)
);
}
impl Default for _IO_FILE { impl Default for _IO_FILE {
fn default() -> Self { fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit(); let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
@ -920,62 +543,21 @@ pub struct _IO_cookie_io_functions_t {
pub seek: cookie_seek_function_t, pub seek: cookie_seek_function_t,
pub close: cookie_close_function_t, pub close: cookie_close_function_t,
} }
#[test] #[allow(clippy::unnecessary_operation, clippy::identity_op)]
fn bindgen_test_layout__IO_cookie_io_functions_t() { const _: () = {
const UNINIT: ::std::mem::MaybeUninit<_IO_cookie_io_functions_t> = ["Size of _IO_cookie_io_functions_t"]
::std::mem::MaybeUninit::uninit(); [::std::mem::size_of::<_IO_cookie_io_functions_t>() - 32usize];
let ptr = UNINIT.as_ptr(); ["Alignment of _IO_cookie_io_functions_t"]
assert_eq!( [::std::mem::align_of::<_IO_cookie_io_functions_t>() - 8usize];
::std::mem::size_of::<_IO_cookie_io_functions_t>(), ["Offset of field: _IO_cookie_io_functions_t::read"]
32usize, [::std::mem::offset_of!(_IO_cookie_io_functions_t, read) - 0usize];
concat!("Size of: ", stringify!(_IO_cookie_io_functions_t)) ["Offset of field: _IO_cookie_io_functions_t::write"]
); [::std::mem::offset_of!(_IO_cookie_io_functions_t, write) - 8usize];
assert_eq!( ["Offset of field: _IO_cookie_io_functions_t::seek"]
::std::mem::align_of::<_IO_cookie_io_functions_t>(), [::std::mem::offset_of!(_IO_cookie_io_functions_t, seek) - 16usize];
8usize, ["Offset of field: _IO_cookie_io_functions_t::close"]
concat!("Alignment of ", stringify!(_IO_cookie_io_functions_t)) [::std::mem::offset_of!(_IO_cookie_io_functions_t, close) - 24usize];
); };
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).read) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(_IO_cookie_io_functions_t),
"::",
stringify!(read)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).write) as usize - ptr as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(_IO_cookie_io_functions_t),
"::",
stringify!(write)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).seek) as usize - ptr as usize },
16usize,
concat!(
"Offset of field: ",
stringify!(_IO_cookie_io_functions_t),
"::",
stringify!(seek)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).close) as usize - ptr as usize },
24usize,
concat!(
"Offset of field: ",
stringify!(_IO_cookie_io_functions_t),
"::",
stringify!(close)
)
);
}
pub type cookie_io_functions_t = _IO_cookie_io_functions_t; pub type cookie_io_functions_t = _IO_cookie_io_functions_t;
pub type va_list = __gnuc_va_list; pub type va_list = __gnuc_va_list;
pub type off_t = __off_t; pub type off_t = __off_t;
@ -1597,61 +1179,19 @@ pub struct __va_list_tag {
pub overflow_arg_area: *mut ::std::os::raw::c_void, pub overflow_arg_area: *mut ::std::os::raw::c_void,
pub reg_save_area: *mut ::std::os::raw::c_void, pub reg_save_area: *mut ::std::os::raw::c_void,
} }
#[test] #[allow(clippy::unnecessary_operation, clippy::identity_op)]
fn bindgen_test_layout___va_list_tag() { const _: () = {
const UNINIT: ::std::mem::MaybeUninit<__va_list_tag> = ::std::mem::MaybeUninit::uninit(); ["Size of __va_list_tag"][::std::mem::size_of::<__va_list_tag>() - 24usize];
let ptr = UNINIT.as_ptr(); ["Alignment of __va_list_tag"][::std::mem::align_of::<__va_list_tag>() - 8usize];
assert_eq!( ["Offset of field: __va_list_tag::gp_offset"]
::std::mem::size_of::<__va_list_tag>(), [::std::mem::offset_of!(__va_list_tag, gp_offset) - 0usize];
24usize, ["Offset of field: __va_list_tag::fp_offset"]
concat!("Size of: ", stringify!(__va_list_tag)) [::std::mem::offset_of!(__va_list_tag, fp_offset) - 4usize];
); ["Offset of field: __va_list_tag::overflow_arg_area"]
assert_eq!( [::std::mem::offset_of!(__va_list_tag, overflow_arg_area) - 8usize];
::std::mem::align_of::<__va_list_tag>(), ["Offset of field: __va_list_tag::reg_save_area"]
8usize, [::std::mem::offset_of!(__va_list_tag, reg_save_area) - 16usize];
concat!("Alignment of ", stringify!(__va_list_tag)) };
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).gp_offset) as usize - ptr as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(__va_list_tag),
"::",
stringify!(gp_offset)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).fp_offset) as usize - ptr as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(__va_list_tag),
"::",
stringify!(fp_offset)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).overflow_arg_area) as usize - ptr as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(__va_list_tag),
"::",
stringify!(overflow_arg_area)
)
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).reg_save_area) as usize - ptr as usize },
16usize,
concat!(
"Offset of field: ",
stringify!(__va_list_tag),
"::",
stringify!(reg_save_area)
)
);
}
impl Default for __va_list_tag { impl Default for __va_list_tag {
fn default() -> Self { fn default() -> Self {
let mut s = ::std::mem::MaybeUninit::<Self>::uninit(); let mut s = ::std::mem::MaybeUninit::<Self>::uninit();

View File

@ -84,7 +84,7 @@ impl crate::ArchExtras for crate::CPU {
{ {
let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?; let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?;
let mut ret_addr = [0; size_of::<GuestReg>()]; let mut ret_addr = [0; size_of::<GuestReg>()];
unsafe { self.read_mem(stack_ptr, &mut ret_addr) }; unsafe { self.read_mem_unchecked(stack_ptr, &mut ret_addr) };
Ok(GuestReg::from_le_bytes(ret_addr).into()) Ok(GuestReg::from_le_bytes(ret_addr).into())
} }
@ -95,7 +95,7 @@ impl crate::ArchExtras for crate::CPU {
let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?; let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?;
let val: GuestReg = val.into(); let val: GuestReg = val.into();
let ret_addr = val.to_le_bytes(); let ret_addr = val.to_le_bytes();
unsafe { self.write_mem(stack_ptr, &ret_addr) }; unsafe { self.write_mem_unchecked(stack_ptr, &ret_addr) };
Ok(()) Ok(())
} }

View File

@ -380,7 +380,10 @@ where
) -> Result<Option<EmulatorDriverResult<CM, ED, ET, S, SM>>, EmulatorDriverError> { ) -> Result<Option<EmulatorDriverResult<CM, ED, ET, S, SM>>, EmulatorDriverError> {
let qemu = emu.qemu(); let qemu = emu.qemu();
let ret_value = self.location.write(qemu, input.target_bytes().as_slice()); let ret_value = self
.location
.write(qemu, input.target_bytes().as_slice())
.unwrap();
if let Some(reg) = ret_reg { if let Some(reg) = ret_reg {
self.cpu.write_reg(reg, ret_value).unwrap(); self.cpu.write_reg(reg, ret_value).unwrap();
@ -443,7 +446,8 @@ where
// Write input to input location // Write input to input location
let ret_value = self let ret_value = self
.input_location .input_location
.write(qemu, input.target_bytes().as_slice()); .write(qemu, input.target_bytes().as_slice())
.unwrap();
// Unleash hooks if locked // Unleash hooks if locked
if emu.driver_mut().unlock_hooks() { if emu.driver_mut().unlock_hooks() {

View File

@ -298,7 +298,7 @@ where
let mem_chunk = let mem_chunk =
QemuMemoryChunk::virt(buf_addr as GuestVirtAddr, total_size as GuestReg, cpu); QemuMemoryChunk::virt(buf_addr as GuestVirtAddr, total_size as GuestReg, cpu);
mem_chunk.read(qemu, str_copy.as_slice_mut()); mem_chunk.read(qemu, str_copy.as_slice_mut())?;
let c_str: &CStr = CStr::from_bytes_with_nul(str_copy.as_slice()).unwrap(); let c_str: &CStr = CStr::from_bytes_with_nul(str_copy.as_slice()).unwrap();
@ -325,7 +325,7 @@ where
Ok(TestCommand::new( Ok(TestCommand::new(
received_value, received_value,
bindings::LIBAFL_QEMU_TEST_VALUE as GuestReg, GuestReg::from(bindings::LIBAFL_QEMU_TEST_VALUE),
)) ))
} }
} }

View File

@ -84,7 +84,8 @@ where
func(emulator_modules, target_sig); func(emulator_modules, target_sig);
} }
HookRepr::Closure(ptr) => { HookRepr::Closure(ptr) => {
let func: &mut CrashHookClosure<ET, S> = transmute(ptr); let func: &mut CrashHookClosure<ET, S> =
&mut *(ptr::from_mut::<FatPtr>(ptr) as *mut CrashHookClosure<ET, S>);
func(emulator_modules, target_sig); func(emulator_modules, target_sig);
} }
HookRepr::Empty => (), HookRepr::Empty => (),

View File

@ -56,8 +56,11 @@ where
first_exec: bool, first_exec: bool,
} }
/// # Safety
///
/// This should be used as a crash handler, and nothing else.
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
pub unsafe fn inproc_qemu_crash_handler( unsafe fn inproc_qemu_crash_handler(
signal: Signal, signal: Signal,
info: &mut siginfo_t, info: &mut siginfo_t,
mut context: Option<&mut ucontext_t>, mut context: Option<&mut ucontext_t>,
@ -329,6 +332,7 @@ where
Z: HasObjective<State = S>, Z: HasObjective<State = S>,
Z::Objective: Feedback<EM, S::Input, OT, S>, Z::Objective: Feedback<EM, S::Input, OT, S>,
{ {
#[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
emulator: Emulator<CM, ED, ET, S, SM>, emulator: Emulator<CM, ED, ET, S, SM>,
harness_fn: &'a mut H, harness_fn: &'a mut H,

View File

@ -4,7 +4,6 @@
/*! */ /*! */
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] #![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
#![forbid(unexpected_cfgs)]
// libafl_qemu only supports Linux currently // libafl_qemu only supports Linux currently
#![cfg(target_os = "linux")] #![cfg(target_os = "linux")]
// This lint triggers too often on the current GuestAddr type when emulating 64-bit targets because // This lint triggers too often on the current GuestAddr type when emulating 64-bit targets because
@ -13,16 +12,6 @@
any(cpu_target = "x86_64", cpu_target = "aarch64"), any(cpu_target = "x86_64", cpu_target = "aarch64"),
allow(clippy::useless_conversion) allow(clippy::useless_conversion)
)] )]
#![allow(clippy::needless_pass_by_value)]
#![allow(clippy::needless_pass_by_ref_mut)]
#![allow(clippy::transmute_ptr_to_ptr)]
#![allow(clippy::ptr_cast_constness)]
#![allow(clippy::too_many_arguments)]
// Till they fix this buggy lint in clippy
#![allow(clippy::borrow_as_ptr)]
#![allow(clippy::borrow_deref_ref)]
// Allow only ATM, it will be evetually removed
#![allow(clippy::missing_safety_doc)]
// libafl_qemu_sys export types with empty struct markers (e.g. struct {} start_init_save) // libafl_qemu_sys export types with empty struct markers (e.g. struct {} start_init_save)
// This causes bindgen to generate empty Rust struct that are generally not FFI-safe due to C++ having empty structs with size 1 // This causes bindgen to generate empty Rust struct that are generally not FFI-safe due to C++ having empty structs with size 1
// As the QEMU codebase is C, it is FFI-safe and we just ignore the warning // As the QEMU codebase is C, it is FFI-safe and we just ignore the warning

View File

@ -646,8 +646,9 @@ where
} }
} }
// # Safety /// # Safety
// Calling this concurrently for the same id is racey and may lose updates. ///
/// Calling this concurrently for the same id is racey and may lose updates.
pub unsafe extern "C" fn trace_edge_hitcount(_: *const (), id: u64) { pub unsafe extern "C" fn trace_edge_hitcount(_: *const (), id: u64) {
unsafe { unsafe {
EDGES_MAP[id as usize] = EDGES_MAP[id as usize].wrapping_add(1); EDGES_MAP[id as usize] = EDGES_MAP[id as usize].wrapping_add(1);

View File

@ -751,14 +751,14 @@ pub struct AsanModule {
impl AsanModule { impl AsanModule {
#[must_use] #[must_use]
pub fn default(rt: Pin<Box<AsanGiovese>>) -> Self { pub fn default(rt: Pin<Box<AsanGiovese>>) -> Self {
Self::new(rt, StdAddressFilter::default(), QemuAsanOptions::Snapshot) Self::new(rt, StdAddressFilter::default(), &QemuAsanOptions::Snapshot)
} }
#[must_use] #[must_use]
pub fn new( pub fn new(
mut rt: Pin<Box<AsanGiovese>>, mut rt: Pin<Box<AsanGiovese>>,
filter: StdAddressFilter, filter: StdAddressFilter,
options: QemuAsanOptions, options: &QemuAsanOptions,
) -> Self { ) -> Self {
assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)"); assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)");
let (snapshot, detect_leaks) = match options { let (snapshot, detect_leaks) = match options {
@ -782,7 +782,7 @@ impl AsanModule {
mut rt: Pin<Box<AsanGiovese>>, mut rt: Pin<Box<AsanGiovese>>,
filter: StdAddressFilter, filter: StdAddressFilter,
error_callback: AsanErrorCallback, error_callback: AsanErrorCallback,
options: QemuAsanOptions, options: &QemuAsanOptions,
) -> Self { ) -> Self {
assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)"); assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)");
let (snapshot, detect_leaks) = match options { let (snapshot, detect_leaks) = match options {
@ -808,12 +808,12 @@ impl AsanModule {
pub unsafe fn with_asan_report( pub unsafe fn with_asan_report(
rt: Pin<Box<AsanGiovese>>, rt: Pin<Box<AsanGiovese>>,
filter: StdAddressFilter, filter: StdAddressFilter,
options: QemuAsanOptions, options: &QemuAsanOptions,
) -> Self { ) -> Self {
Self::with_error_callback( Self::with_error_callback(
rt, rt,
filter, filter,
Box::new(|rt, qemu, pc, err| unsafe { asan_report(rt, qemu, pc, err) }), Box::new(|rt, qemu, pc, err| unsafe { asan_report(rt, qemu, pc, &err) }),
options, options,
) )
} }
@ -1536,7 +1536,7 @@ mod addr2line_legacy {
/// Calling this function concurrently might be racey. /// Calling this function concurrently might be racey.
#[allow(clippy::unnecessary_cast)] #[allow(clippy::unnecessary_cast)]
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: AsanError) { pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: &AsanError) {
let mut regions = HashMap::new(); let mut regions = HashMap::new();
for region in qemu.mappings() { for region in qemu.mappings() {
if let Some(path) = region.path() { if let Some(path) = region.path() {
@ -1668,7 +1668,7 @@ pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: Asan
} }
let addr = match err { let addr = match err {
AsanError::Read(addr, _) | AsanError::Write(addr, _) | AsanError::BadFree(addr, _) => { AsanError::Read(addr, _) | AsanError::Write(addr, _) | AsanError::BadFree(addr, _) => {
Some(addr) Some(*addr)
} }
AsanError::MemLeak(_) | AsanError::Signal(_) => None, AsanError::MemLeak(_) | AsanError::Signal(_) => None,
}; };

View File

@ -146,7 +146,7 @@ impl<F> AsanGuestModule<F> {
impl AsanGuestModule<StdAddressFilter> { impl AsanGuestModule<StdAddressFilter> {
#[must_use] #[must_use]
pub fn default(qemu: Qemu, asan: String) -> Self { pub fn default(qemu: Qemu, asan: &str) -> Self {
Self::new(qemu, asan, StdAddressFilter::default()) Self::new(qemu, asan, StdAddressFilter::default())
} }
} }
@ -156,7 +156,7 @@ where
F: AddressFilter, F: AddressFilter,
{ {
#[must_use] #[must_use]
pub fn new(qemu: Qemu, asan: String, filter: F) -> Self { pub fn new(qemu: Qemu, asan: &str, filter: F) -> Self {
for mapping in qemu.mappings() { for mapping in qemu.mappings() {
println!("mapping: {mapping:#?}"); println!("mapping: {mapping:#?}");
} }

View File

@ -343,6 +343,7 @@ where
} }
} }
#[allow(clippy::too_many_arguments)]
fn syscall_hook<ET, S>( fn syscall_hook<ET, S>(
emulator_modules: &mut EmulatorModules<ET, S>, // our instantiated QemuHooks emulator_modules: &mut EmulatorModules<ET, S>, // our instantiated QemuHooks
_state: Option<&mut S>, _state: Option<&mut S>,

View File

@ -208,7 +208,7 @@ impl SnapshotModule {
// TODO not just for R pages // TODO not just for R pages
unsafe { unsafe {
info.data = Some(Box::new(core::mem::zeroed())); info.data = Some(Box::new(core::mem::zeroed()));
qemu.read_mem(addr, &mut info.data.as_mut().unwrap()[..]); qemu.read_mem_unchecked(addr, &mut info.data.as_mut().unwrap()[..]);
} }
} }
self.pages.insert(addr, info); self.pages.insert(addr, info);
@ -299,7 +299,8 @@ impl SnapshotModule {
qemu.read_mem( qemu.read_mem(
addr, addr,
current_page_content.as_mut_ptr().as_mut().unwrap(), current_page_content.as_mut_ptr().as_mut().unwrap(),
); )
.unwrap();
} }
let current_page_content: &mut [u8; SNAPSHOT_PAGE_SIZE] = let current_page_content: &mut [u8; SNAPSHOT_PAGE_SIZE] =
@ -411,7 +412,7 @@ impl SnapshotModule {
return true; // Restore later return true; // Restore later
} }
unsafe { qemu.write_mem(*page, &data[..]) }; unsafe { qemu.write_mem_unchecked(*page, &data[..]) };
} else { } else {
panic!("Cannot restored a dirty but unsaved page"); panic!("Cannot restored a dirty but unsaved page");
} }
@ -446,7 +447,7 @@ impl SnapshotModule {
if let Some(info) = self.pages.get_mut(page) { if let Some(info) = self.pages.get_mut(page) {
// TODO avoid duplicated memcpy // TODO avoid duplicated memcpy
if let Some(data) = info.data.as_ref() { if let Some(data) = info.data.as_ref() {
unsafe { qemu.write_mem(*page, &data[..]) }; unsafe { qemu.write_mem_unchecked(*page, &data[..]) };
} else { } else {
panic!("Cannot restored a dirty but unsaved page"); panic!("Cannot restored a dirty but unsaved page");
} }

View File

@ -1,5 +1,7 @@
//! The high-level hooks //! The high-level hooks
#![allow(clippy::type_complexity, clippy::missing_transmute_annotations)] #![allow(clippy::type_complexity)]
#![allow(clippy::missing_transmute_annotations)]
#![allow(clippy::too_many_arguments)]
use core::{ffi::c_void, fmt::Debug, mem::transmute, ptr}; use core::{ffi::c_void, fmt::Debug, mem::transmute, ptr};
@ -52,6 +54,9 @@ impl<const N: usize, H: HookId> TcgHookState<N, H> {
} }
} }
/// # Safety
///
/// ids should be in sync with QEMU hooks ids.
pub unsafe fn set_id(&mut self, id: H) { pub unsafe fn set_id(&mut self, id: H) {
self.id = id; self.id = id;
} }
@ -66,6 +71,9 @@ impl<H: HookId> HookState<H> {
} }
} }
/// # Safety
///
/// ids should be in sync with QEMU hooks ids.
pub unsafe fn set_id(&mut self, id: H) { pub unsafe fn set_id(&mut self, id: H) {
self.id = id; self.id = id;
} }
@ -112,7 +120,7 @@ macro_rules! create_wrapper {
{ {
unsafe { unsafe {
let modules = EmulatorModules::<ET, S>::emulator_modules_mut_unchecked(); let modules = EmulatorModules::<ET, S>::emulator_modules_mut_unchecked();
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)> = transmute(hook); let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)> = &mut *(ptr::from_mut::<FatPtr>(hook) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)>);
func(modules, inprocess_get_state::<S>(), $($param),*); func(modules, inprocess_get_state::<S>(), $($param),*);
} }
} }
@ -137,7 +145,7 @@ macro_rules! create_wrapper {
{ {
unsafe { unsafe {
let modules = EmulatorModules::<ET, S>::emulator_modules_mut_unchecked(); let modules = EmulatorModules::<ET, S>::emulator_modules_mut_unchecked();
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> $ret_type> = transmute(hook); let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> $ret_type> = &mut *(ptr::from_mut::<FatPtr>(hook) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> $ret_type>);
func(modules, inprocess_get_state::<S>(), $($param),*) func(modules, inprocess_get_state::<S>(), $($param),*)
} }
} }
@ -164,7 +172,9 @@ macro_rules! create_pre_exec_wrapper {
HookRepr::Closure(ptr) => { HookRepr::Closure(ptr) => {
let func: &mut Box< let func: &mut Box<
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*), dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
> = transmute(ptr); > = &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
>);
func(modules, inprocess_get_state::<S>(), $($param),*) func(modules, inprocess_get_state::<S>(), $($param),*)
} }
_ => (), _ => (),
@ -194,7 +204,9 @@ macro_rules! create_post_exec_wrapper {
HookRepr::Closure(ptr) => { HookRepr::Closure(ptr) => {
let func: &mut Box< let func: &mut Box<
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*), dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
> = transmute(ptr); > = &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
>);
func(modules, inprocess_get_state::<S>(), $($param),*); func(modules, inprocess_get_state::<S>(), $($param),*);
} }
_ => (), _ => (),
@ -224,7 +236,7 @@ macro_rules! create_gen_wrapper {
HookRepr::Closure(ptr) => { HookRepr::Closure(ptr) => {
let func: &mut Box< let func: &mut Box<
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> Option<$ret_type>, dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> Option<$ret_type>,
> = transmute(ptr); > = &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> Option<$ret_type>>);
func(modules, inprocess_get_state::<S>(), $($param),*).map_or(SKIP_EXEC_HOOK, |id| id) func(modules, inprocess_get_state::<S>(), $($param),*).map_or(SKIP_EXEC_HOOK, |id| id)
} }
_ => 0, _ => 0,
@ -253,7 +265,7 @@ macro_rules! create_post_gen_wrapper {
HookRepr::Closure(ptr) => { HookRepr::Closure(ptr) => {
let func: &mut Box< let func: &mut Box<
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*), dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
> = transmute(ptr); > = &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)>);
func(modules, inprocess_get_state::<S>(), $($param),*); func(modules, inprocess_get_state::<S>(), $($param),*);
} }
_ => (), _ => (),
@ -280,7 +292,7 @@ macro_rules! create_exec_wrapper {
} }
HookRepr::Closure(ptr) => { HookRepr::Closure(ptr) => {
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)> = let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)> =
transmute(ptr); &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)>);
func(modules, inprocess_get_state::<S>(), $($param),*); func(modules, inprocess_get_state::<S>(), $($param),*);
} }
_ => (), _ => (),

View File

@ -18,8 +18,6 @@ use std::{
}; };
use libafl_bolts::os::unix_signals::Signal; use libafl_bolts::os::unix_signals::Signal;
#[cfg(emulation_mode = "usermode")]
use libafl_qemu_sys::{guest_base, VerifyAccess};
use libafl_qemu_sys::{ use libafl_qemu_sys::{
libafl_flush_jit, libafl_get_exit_reason, libafl_page_from_addr, libafl_qemu_add_gdb_cmd, libafl_flush_jit, libafl_get_exit_reason, libafl_page_from_addr, libafl_qemu_add_gdb_cmd,
libafl_qemu_cpu_index, libafl_qemu_current_cpu, libafl_qemu_gdb_reply, libafl_qemu_get_cpu, libafl_qemu_cpu_index, libafl_qemu_current_cpu, libafl_qemu_gdb_reply, libafl_qemu_get_cpu,
@ -52,6 +50,13 @@ pub use hooks::*;
static mut QEMU_IS_INITIALIZED: bool = false; static mut QEMU_IS_INITIALIZED: bool = false;
#[derive(Debug)]
pub enum QemuError {
Init(QemuInitError),
Exit(QemuExitError),
RW(QemuRWError),
}
#[derive(Debug)] #[derive(Debug)]
pub enum QemuInitError { pub enum QemuInitError {
MultipleInstances, MultipleInstances,
@ -92,6 +97,7 @@ pub enum QemuRWErrorCause {
WrongArgument(i32), WrongArgument(i32),
CurrentCpuNotFound, CurrentCpuNotFound,
Reg(i32), Reg(i32),
WrongMemoryLocation(GuestAddr, usize), // addr, size
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -108,6 +114,19 @@ impl QemuRWError {
Self { kind, cause, cpu } Self { kind, cause, cpu }
} }
pub fn wrong_mem_location(
kind: QemuRWErrorKind,
cpu: CPUStatePtr,
addr: GuestAddr,
size: usize,
) -> Self {
Self::new(
kind,
QemuRWErrorCause::WrongMemoryLocation(addr, size),
Some(cpu),
)
}
#[must_use] #[must_use]
pub fn current_cpu_not_found(kind: QemuRWErrorKind) -> Self { pub fn current_cpu_not_found(kind: QemuRWErrorKind) -> Self {
Self::new(kind, QemuRWErrorCause::CurrentCpuNotFound, None) Self::new(kind, QemuRWErrorCause::CurrentCpuNotFound, None)
@ -323,27 +342,6 @@ impl CPU {
} }
} }
#[cfg(emulation_mode = "usermode")]
#[must_use]
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
unsafe { (addr as usize + guest_base) as *mut T }
}
#[cfg(emulation_mode = "usermode")]
#[must_use]
pub fn h2g<T>(&self, addr: *const T) -> GuestAddr {
unsafe { (addr as usize - guest_base) as GuestAddr }
}
#[cfg(emulation_mode = "usermode")]
#[must_use]
pub fn access_ok(&self, kind: VerifyAccess, addr: GuestAddr, size: usize) -> bool {
unsafe {
// TODO add support for tagged GuestAddr
libafl_qemu_sys::page_check_range(addr, size as GuestAddr, kind.into())
}
}
// TODO expose tlb_set_dirty and tlb_reset_dirty // TODO expose tlb_set_dirty and tlb_reset_dirty
#[must_use] #[must_use]
@ -351,6 +349,31 @@ impl CPU {
unsafe { libafl_qemu_num_regs(self.ptr) } unsafe { libafl_qemu_num_regs(self.ptr) }
} }
pub fn read_reg<R, T>(&self, reg: R) -> Result<T, QemuRWError>
where
R: Into<i32> + Clone,
T: From<GuestReg>,
{
unsafe {
let reg_id = reg.clone().into();
let mut val = MaybeUninit::uninit();
let success = libafl_qemu_read_reg(self.ptr, reg_id, val.as_mut_ptr() as *mut u8);
if success == 0 {
Err(QemuRWError {
kind: QemuRWErrorKind::Write,
cause: QemuRWErrorCause::Reg(reg.into()),
cpu: Some(self.ptr),
})
} else {
#[cfg(feature = "be")]
return Ok(GuestReg::from_be(val.assume_init()).into());
#[cfg(not(feature = "be"))]
return Ok(GuestReg::from_le(val.assume_init()).into());
}
}
}
pub fn write_reg<R, T>(&self, reg: R, val: T) -> Result<(), QemuRWError> pub fn write_reg<R, T>(&self, reg: R, val: T) -> Result<(), QemuRWError>
where where
R: Into<i32> + Clone, R: Into<i32> + Clone,
@ -376,29 +399,54 @@ impl CPU {
} }
} }
pub fn read_reg<R, T>(&self, reg: R) -> Result<T, QemuRWError> /// Read a value from a guest address, taking into account the potential MMU / MPU.
where pub fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) -> Result<(), QemuRWError> {
R: Into<i32> + Clone, // TODO use gdbstub's target_cpu_memory_rw_debug
T: From<GuestReg>, let ret = unsafe {
{ libafl_qemu_sys::cpu_memory_rw_debug(
unsafe { self.ptr,
let reg_id = reg.clone().into(); addr as GuestVirtAddr,
let mut val = MaybeUninit::uninit(); buf.as_mut_ptr() as *mut _,
let success = libafl_qemu_read_reg(self.ptr, reg_id, val.as_mut_ptr() as *mut u8); buf.len(),
if success == 0 { false,
Err(QemuRWError { )
kind: QemuRWErrorKind::Write, };
cause: QemuRWErrorCause::Reg(reg.into()),
cpu: Some(self.ptr),
})
} else {
#[cfg(feature = "be")]
return Ok(GuestReg::from_be(val.assume_init()).into());
#[cfg(not(feature = "be"))] if ret != 0 {
return Ok(GuestReg::from_le(val.assume_init()).into()); Err(QemuRWError::wrong_mem_location(
QemuRWErrorKind::Read,
self.ptr,
addr,
buf.len(),
))
} else {
Ok(())
} }
} }
/// Write a value to a guest address, taking into account the potential MMU / MPU.
pub fn write_mem(&self, addr: GuestAddr, buf: &[u8]) -> Result<(), QemuRWError> {
// TODO use gdbstub's target_cpu_memory_rw_debug
let ret = unsafe {
libafl_qemu_sys::cpu_memory_rw_debug(
self.ptr,
addr as GuestVirtAddr,
buf.as_ptr() as *mut _,
buf.len(),
true,
)
};
if ret != 0 {
Err(QemuRWError::wrong_mem_location(
QemuRWErrorKind::Write,
self.ptr,
addr,
buf.len(),
))
} else {
Ok(())
}
} }
pub fn reset(&self) { pub fn reset(&self) {
@ -707,21 +755,48 @@ impl Qemu {
unsafe { libafl_page_from_addr(addr) } unsafe { libafl_page_from_addr(addr) }
} }
//#[must_use] /// Read a value from a guest address, taking into account the potential indirections with the current CPU.
/*pub fn page_size() -> GuestUsize { pub fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) -> Result<(), QemuRWError> {
unsafe { libafl_page_size }
}*/
pub unsafe fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
self.current_cpu() self.current_cpu()
.unwrap_or_else(|| self.cpu_from_index(0)) .unwrap_or_else(|| self.cpu_from_index(0))
.write_mem(addr, buf); .read_mem(addr, buf)
} }
pub unsafe fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) { /// Write a value to a guest address, taking into account the potential indirections with the current CPU.
pub fn write_mem(&self, addr: GuestAddr, buf: &[u8]) -> Result<(), QemuRWError> {
self.current_cpu() self.current_cpu()
.unwrap_or_else(|| self.cpu_from_index(0)) .unwrap_or_else(|| self.cpu_from_index(0))
.read_mem(addr, buf); .write_mem(addr, buf)
}
/// Read a value from a guest address.
///
/// # Safety
/// In usermode, this will read from a translated guest address.
/// This may only be safely used for valid guest addresses.
///
/// In any case, no check will be performed on the correctness of the operation.
///
/// Please refer to [`CPU::read_mem`] for more details.
pub unsafe fn read_mem_unchecked(&self, addr: GuestAddr, buf: &mut [u8]) {
self.current_cpu()
.unwrap_or_else(|| self.cpu_from_index(0))
.read_mem_unchecked(addr, buf);
}
/// Write a value to a guest address.
///
/// # Safety
/// In usermode, this will write to a translated guest address.
///
/// In any case, no check will be performed on the correctness of the operation.
///
/// This may only be safely used for valid guest addresses.
/// Please refer to [`CPU::write_mem`] for more details.
pub unsafe fn write_mem_unchecked(&self, addr: GuestAddr, buf: &[u8]) {
self.current_cpu()
.unwrap_or_else(|| self.cpu_from_index(0))
.write_mem_unchecked(addr, buf);
} }
#[must_use] #[must_use]
@ -779,12 +854,13 @@ impl Qemu {
} }
#[must_use] #[must_use]
pub fn remove_hook(&self, id: impl HookId, invalidate_block: bool) -> bool { pub fn remove_hook(&self, id: &impl HookId, invalidate_block: bool) -> bool {
id.remove(invalidate_block) id.remove(invalidate_block)
} }
// # Safety /// # Safety
// Calling this multiple times concurrently will access static variables and is unsafe. ///
/// Calling this multiple times concurrently will access static variables and is unsafe.
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub unsafe fn add_gdb_cmd(&self, callback: Box<dyn FnMut(&Self, &str) -> bool>) { pub unsafe fn add_gdb_cmd(&self, callback: Box<dyn FnMut(&Self, &str) -> bool>) {
let fat: Box<FatPtr> = Box::new(transmute::< let fat: Box<FatPtr> = Box::new(transmute::<
@ -929,7 +1005,7 @@ impl QemuMemoryChunk {
/// Returns the number of bytes effectively read. /// Returns the number of bytes effectively read.
/// output will get chunked at `size` bytes. /// output will get chunked at `size` bytes.
pub fn read(&self, qemu: Qemu, output: &mut [u8]) -> GuestReg { pub fn read(&self, qemu: Qemu, output: &mut [u8]) -> Result<GuestReg, QemuRWError> {
let max_len: usize = self.size.try_into().unwrap(); let max_len: usize = self.size.try_into().unwrap();
let output_sliced = if output.len() > max_len { let output_sliced = if output.len() > max_len {
@ -939,32 +1015,31 @@ impl QemuMemoryChunk {
}; };
match self.addr { match self.addr {
GuestAddrKind::Physical(hwaddr) => unsafe { GuestAddrKind::Physical(hwaddr) => {
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
{ {
// For now the default behaviour is to fall back to virtual addresses // For now the default behaviour is to fall back to virtual addresses
qemu.read_mem(hwaddr.try_into().unwrap(), output_sliced); qemu.read_mem(hwaddr.try_into().unwrap(), output_sliced)?;
} }
#[cfg(emulation_mode = "systemmode")] #[cfg(emulation_mode = "systemmode")]
{ unsafe {
qemu.read_phys_mem(hwaddr, output_sliced); qemu.read_phys_mem(hwaddr, output_sliced);
} }
}, }
GuestAddrKind::Virtual(vaddr) => unsafe { GuestAddrKind::Virtual(vaddr) => unsafe {
self.cpu self.cpu
.as_ref() .as_ref()
.unwrap() .unwrap()
.read_mem(vaddr.try_into().unwrap(), output_sliced); .read_mem_unchecked(vaddr.try_into().unwrap(), output_sliced);
}, },
}; };
output_sliced.len().try_into().unwrap() Ok(output_sliced.len().try_into().unwrap())
} }
/// Returns the number of bytes effectively written. /// Returns the number of bytes effectively written.
/// Input will get chunked at `size` bytes. /// Input will get chunked at `size` bytes.
#[must_use] pub fn write(&self, qemu: Qemu, input: &[u8]) -> Result<GuestReg, QemuRWError> {
pub fn write(&self, qemu: Qemu, input: &[u8]) -> GuestReg {
let max_len: usize = self.size.try_into().unwrap(); let max_len: usize = self.size.try_into().unwrap();
let input_sliced = if input.len() > max_len { let input_sliced = if input.len() > max_len {
@ -974,26 +1049,26 @@ impl QemuMemoryChunk {
}; };
match self.addr { match self.addr {
GuestAddrKind::Physical(hwaddr) => unsafe { GuestAddrKind::Physical(hwaddr) => {
#[cfg(emulation_mode = "usermode")] #[cfg(emulation_mode = "usermode")]
{ {
// For now the default behaviour is to fall back to virtual addresses // For now the default behaviour is to fall back to virtual addresses
qemu.write_mem(hwaddr.try_into().unwrap(), input_sliced); qemu.write_mem(hwaddr.try_into().unwrap(), input_sliced)?;
} }
#[cfg(emulation_mode = "systemmode")] #[cfg(emulation_mode = "systemmode")]
{ unsafe {
qemu.write_phys_mem(hwaddr, input_sliced); qemu.write_phys_mem(hwaddr, input_sliced);
} }
}, }
GuestAddrKind::Virtual(vaddr) => unsafe { GuestAddrKind::Virtual(vaddr) => {
self.cpu self.cpu
.as_ref() .as_ref()
.unwrap() .unwrap()
.write_mem(vaddr.try_into().unwrap(), input_sliced); .write_mem(vaddr.try_into().unwrap(), input_sliced)?;
}, }
}; };
input_sliced.len().try_into().unwrap() Ok(input_sliced.len().try_into().unwrap())
} }
} }
@ -1038,16 +1113,16 @@ pub mod pybind {
} }
fn write_mem(&self, addr: GuestAddr, buf: &[u8]) { fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
unsafe { self.qemu
self.qemu.write_mem(addr, buf); .write_mem(addr, buf)
} .expect("Write to memory failed.");
} }
fn read_mem(&self, addr: GuestAddr, size: usize) -> Vec<u8> { fn read_mem(&self, addr: GuestAddr, size: usize) -> Vec<u8> {
let mut buf = vec![0; size]; let mut buf = vec![0; size];
unsafe { self.qemu
self.qemu.read_mem(addr, &mut buf); .read_mem(addr, &mut buf)
} .expect("Read to memory failed.");
buf buf
} }

View File

@ -16,8 +16,8 @@ use libc::EXIT_SUCCESS;
use num_traits::Zero; use num_traits::Zero;
use crate::{ use crate::{
FastSnapshotPtr, GuestAddrKind, MemAccessInfo, Qemu, QemuMemoryChunk, QemuSnapshotCheckResult, FastSnapshotPtr, GuestAddrKind, MemAccessInfo, Qemu, QemuMemoryChunk, QemuRWError,
CPU, QemuRWErrorCause, QemuRWErrorKind, QemuSnapshotCheckResult, CPU,
}; };
pub(super) extern "C" fn qemu_cleanup_atexit() { pub(super) extern "C" fn qemu_cleanup_atexit() {
@ -140,38 +140,40 @@ impl CPU {
} }
} }
/// Write a value to a guest address. /// Read a value from a guest address, taking into account the potential MMU / MPU.
/// ///
/// # Safety /// # Safety
/// This will write to a translated guest address (using `g2h`). /// no check is done on the correctness of the operation.
/// It just adds `guest_base` and writes to that location, without checking the bounds. /// if a problem occurred during the operation, there will be no feedback
/// This may only be safely used for valid guest addresses! pub unsafe fn read_mem_unchecked(&self, addr: GuestAddr, buf: &mut [u8]) {
pub unsafe fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
// TODO use gdbstub's target_cpu_memory_rw_debug
libafl_qemu_sys::cpu_memory_rw_debug(
self.ptr,
addr as GuestVirtAddr,
buf.as_ptr() as *mut _,
buf.len(),
true,
);
}
/// Read a value from a guest address.
///
/// # Safety
/// This will read from a translated guest address (using `g2h`).
/// It just adds `guest_base` and writes to that location, without checking the bounds.
/// This may only be safely used for valid guest addresses!
pub unsafe fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) {
// TODO use gdbstub's target_cpu_memory_rw_debug // TODO use gdbstub's target_cpu_memory_rw_debug
unsafe {
libafl_qemu_sys::cpu_memory_rw_debug( libafl_qemu_sys::cpu_memory_rw_debug(
self.ptr, self.ptr,
addr as GuestVirtAddr, addr as GuestVirtAddr,
buf.as_mut_ptr() as *mut _, buf.as_mut_ptr() as *mut _,
buf.len(), buf.len(),
false, false,
); )
};
}
/// Write a value to a guest address, taking into account the potential MMU / MPU.
///
/// # Safety
/// no check is done on the correctness of the operation.
/// if a problem occurred during the operation, there will be no feedback
pub fn write_mem_unchecked(&self, addr: GuestAddr, buf: &[u8]) {
// TODO use gdbstub's target_cpu_memory_rw_debug
unsafe {
libafl_qemu_sys::cpu_memory_rw_debug(
self.ptr,
addr as GuestVirtAddr,
buf.as_ptr() as *mut _,
buf.len(),
true,
)
};
} }
} }
@ -182,6 +184,12 @@ impl Qemu {
} }
/// Write a value to a physical guest address, including ROM areas. /// Write a value to a physical guest address, including ROM areas.
///
/// # Safety
///
/// No check is done on the correctness of the operation at the moment.
/// Nothing bad will happen if the operation is incorrect, but it will be silently skipped.
// TODO: use address_space_rw and check for the result MemTxResult
pub unsafe fn write_phys_mem(&self, paddr: GuestPhysAddr, buf: &[u8]) { pub unsafe fn write_phys_mem(&self, paddr: GuestPhysAddr, buf: &[u8]) {
libafl_qemu_sys::cpu_physical_memory_rw( libafl_qemu_sys::cpu_physical_memory_rw(
paddr, paddr,
@ -191,7 +199,13 @@ impl Qemu {
); );
} }
/// Read a value from a physical guest address. /// Read a value from a physical guest address, including ROM areas.
///
/// # Safety
///
/// No check is done on the correctness of the operation at the moment.
/// Nothing bad will happen if the operation is incorrect, but it will be silently skipped.
// TODO: use address_space_rw and check for the result MemTxResult
pub unsafe fn read_phys_mem(&self, paddr: GuestPhysAddr, buf: &mut [u8]) { pub unsafe fn read_phys_mem(&self, paddr: GuestPhysAddr, buf: &mut [u8]) {
libafl_qemu_sys::cpu_physical_memory_rw( libafl_qemu_sys::cpu_physical_memory_rw(
paddr, paddr,

View File

@ -9,7 +9,7 @@ use libafl_qemu_sys::{
pageflags_get_root, read_self_maps, GuestAddr, GuestUsize, IntervalTreeNode, IntervalTreeRoot, pageflags_get_root, read_self_maps, GuestAddr, GuestUsize, IntervalTreeNode, IntervalTreeRoot,
MapInfo, MmapPerms, VerifyAccess, MapInfo, MmapPerms, VerifyAccess,
}; };
use libc::{c_char, c_int, c_uchar, strlen}; use libc::{c_int, c_uchar, strlen};
#[cfg(feature = "python")] #[cfg(feature = "python")]
use pyo3::{pyclass, pymethods, IntoPy, PyObject, PyRef, PyRefMut, Python}; use pyo3::{pyclass, pymethods, IntoPy, PyObject, PyRef, PyRefMut, Python};
@ -79,27 +79,47 @@ impl Drop for GuestMaps {
} }
impl CPU { impl CPU {
/// Write a value to a guest address.
///
/// # Safety
/// This will write to a translated guest address (using `g2h`).
/// It just adds `guest_base` and writes to that location, without checking the bounds.
/// This may only be safely used for valid guest addresses!
pub unsafe fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
let host_addr = Qemu::get().unwrap().g2h(addr);
copy_nonoverlapping(buf.as_ptr(), host_addr, buf.len());
}
/// Read a value from a guest address. /// Read a value from a guest address.
/// The input address is not checked for validity.
/// ///
/// # Safety /// # Safety
/// This will read from a translated guest address (using `g2h`). /// This will read from a translated guest address (using `g2h`).
/// It just adds `guest_base` and writes to that location, without checking the bounds. /// It just adds `guest_base` and writes to that location, without checking the bounds.
/// This may only be safely used for valid guest addresses! /// This may only be safely used for valid guest addresses!
pub unsafe fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) { pub unsafe fn read_mem_unchecked(&self, addr: GuestAddr, buf: &mut [u8]) {
let host_addr = Qemu::get().unwrap().g2h(addr); let host_addr = Qemu::get().unwrap().g2h(addr);
copy_nonoverlapping(host_addr, buf.as_mut_ptr(), buf.len()); copy_nonoverlapping(host_addr, buf.as_mut_ptr(), buf.len());
} }
/// Write a value to a guest address.
/// The input address in not checked for validity.
///
/// # Safety
/// This will write to a translated guest address (using `g2h`).
/// It just adds `guest_base` and writes to that location, without checking the bounds.
/// This may only be safely used for valid guest addresses!
pub unsafe fn write_mem_unchecked(&self, addr: GuestAddr, buf: &[u8]) {
let host_addr = Qemu::get().unwrap().g2h(addr);
copy_nonoverlapping(buf.as_ptr(), host_addr, buf.len());
}
#[must_use]
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
unsafe { (addr as usize + guest_base) as *mut T }
}
#[must_use]
pub fn h2g<T>(&self, addr: *const T) -> GuestAddr {
unsafe { (addr as usize - guest_base) as GuestAddr }
}
#[must_use]
pub fn access_ok(&self, kind: VerifyAccess, addr: GuestAddr, size: usize) -> bool {
unsafe {
// TODO add support for tagged GuestAddr
libafl_qemu_sys::page_check_range(addr, size as GuestAddr, kind.into())
}
}
} }
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
@ -141,7 +161,7 @@ impl Qemu {
unsafe { unsafe {
from_utf8_unchecked_mut(from_raw_parts_mut( from_utf8_unchecked_mut(from_raw_parts_mut(
exec_path as *mut c_uchar, exec_path as *mut c_uchar,
strlen(exec_path as *const c_char), strlen(exec_path.cast_const()),
)) ))
} }
} }

View File

@ -73,3 +73,6 @@ libafl_qemu = { path = "../libafl_qemu", version = "0.13.2" }
[lib] [lib]
name = "libafl_sugar" name = "libafl_sugar"
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
[lints]
workspace = true

View File

@ -1,22 +1,6 @@
//! Sugar API to simplify the life of users of `LibAFL` that just want to fuzz. //! Sugar API to simplify the life of users of `LibAFL` that just want to fuzz.
/*! */ /*! */
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] #![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![forbid(unexpected_cfgs)]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::unreadable_literal
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,

View File

@ -86,4 +86,6 @@ serde = { workspace = true, default-features = false, features = [
] } # serialization lib ] } # serialization lib
meminterval = { workspace = true, features = ["serde"], optional = true } meminterval = { workspace = true, features = ["serde"], optional = true }
ahash = { workspace = true, default-features = false, optional = true } ahash = { workspace = true, default-features = false, optional = true }
# serde-big-array = "0.3.2"
[lints]
workspace = true

View File

@ -1,24 +1,7 @@
//! `libafl_targets` contains runtime code, injected in the target itself during compilation. //! `libafl_targets` contains runtime code, injected in the target itself during compilation.
#![no_std] #![no_std]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![forbid(unexpected_cfgs)]
// For `std::simd` // For `std::simd`
#![cfg_attr(nightly, feature(portable_simd))] #![cfg_attr(nightly, feature(portable_simd))]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::pub_underscore_fields,
clippy::into_iter_without_iter, // broken
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,
@ -101,6 +84,8 @@ pub mod sanitizer_ifaces {
#![allow(missing_docs)] #![allow(missing_docs)]
#![allow(missing_debug_implementations)] #![allow(missing_debug_implementations)]
#![allow(unused_qualifications)] #![allow(unused_qualifications)]
#![allow(clippy::pub_underscore_fields)]
include!(concat!(env!("OUT_DIR"), "/sanitizer_interfaces.rs")); include!(concat!(env!("OUT_DIR"), "/sanitizer_interfaces.rs"));
} }

View File

@ -34,4 +34,7 @@ tinyinst = { git = "https://github.com/AFLplusplus/tinyinst-rs" }
log = { workspace = true } log = { workspace = true }
[build-dependencies] [build-dependencies]
cmake = "0.1.51" cmake = { workspace = true }
[lints]
workspace = true

View File

@ -2,25 +2,6 @@
The tinyinst module for `LibAFL`. The tinyinst module for `LibAFL`.
*/ */
#![warn(clippy::cargo)]
#![deny(clippy::cargo_common_metadata)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::all)]
#![deny(clippy::pedantic)]
#![forbid(unexpected_cfgs)]
#![allow(
clippy::unreadable_literal,
clippy::type_repetition_in_bounds,
clippy::missing_errors_doc,
clippy::cast_possible_truncation,
clippy::used_underscore_binding,
clippy::ptr_as_ptr,
clippy::missing_panics_doc,
clippy::missing_docs_in_private_items,
clippy::module_name_repetitions,
clippy::unreadable_literal,
clippy::negative_feature_names
)]
#![cfg_attr(not(test), warn( #![cfg_attr(not(test), warn(
missing_debug_implementations, missing_debug_implementations,
missing_docs, missing_docs,
@ -60,9 +41,6 @@ The tinyinst module for `LibAFL`.
while_true while_true
) )
)] )]
// Till they fix this buggy lint in clippy
#![allow(clippy::borrow_as_ptr)]
#![allow(clippy::borrow_deref_ref)]
/// Tinyinst executor /// Tinyinst executor
pub mod executor; pub mod executor;

View File

@ -3,6 +3,8 @@
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
cd "$SCRIPT_DIR/.." || exit 1 cd "$SCRIPT_DIR/.." || exit 1
CLIPPY_CMD="RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --no-deps --tests --examples --benches -- -Z macro-backtrace"
set -e set -e
# Function to run Clippy on a single directory # Function to run Clippy on a single directory
run_clippy() { run_clippy() {
@ -10,20 +12,7 @@ run_clippy() {
echo "Running Clippy on $dir" echo "Running Clippy on $dir"
pushd "$dir" || return 1 pushd "$dir" || return 1
RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --no-deps --tests --examples --benches -- -Z macro-backtrace \ eval "$CLIPPY_CMD"
-D clippy::all \
-D clippy::pedantic \
-W clippy::similar_names \
-A clippy::type_repetition_in_bounds \
-A clippy::missing-errors-doc \
-A clippy::cast-possible-truncation \
-A clippy::used-underscore-binding \
-A clippy::ptr-as-ptr \
-A clippy::missing-panics-doc \
-A clippy::missing-docs-in-private-items \
-A clippy::unseparated-literal-suffix \
-A clippy::module-name-repetitions \
-A clippy::unreadable-literal
popd || return 1 popd || return 1
} }
@ -52,21 +41,7 @@ else
fi fi
# First run it on all # First run it on all
RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --no-deps --tests --examples --benches -- -Z macro-backtrace \ eval "$CLIPPY_CMD"
-D clippy::all \
-D clippy::pedantic \
-W clippy::similar_names \
-A clippy::type_repetition_in_bounds \
-A clippy::missing-errors-doc \
-A clippy::cast-possible-truncation \
-A clippy::used-underscore-binding \
-A clippy::ptr-as-ptr \
-A clippy::missing-panics-doc \
-A clippy::missing-docs-in-private-items \
-A clippy::unseparated-literal-suffix \
-A clippy::module-name-repetitions \
-A clippy::unreadable-literal
# Loop through each project and run Clippy # Loop through each project and run Clippy
for project in "${PROJECTS[@]}"; do for project in "${PROJECTS[@]}"; do

View File

@ -1,9 +0,0 @@
#!/bin/bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
LIBAFL_DIR=$(realpath "$SCRIPT_DIR/..")
export LIBAFL_QEMU_GEN_STUBS=1
cd "${LIBAFL_DIR}/libafl_qemu" || exit 1
cargo build

11
scripts/update_bindings.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
cd "$SCRIPT_DIR/.." || exit 1
# Update LibAFL QEMU bindings
pushd libafl_qemu
LIBAFL_QEMU_GEN_STUBS=1 cargo +nightly build || exit 1
popd

View File

@ -10,5 +10,8 @@ keywords = ["ci"]
categories = ["development-tools::testing"] categories = ["development-tools::testing"]
[dependencies] [dependencies]
cargo_toml = "0.20" cargo_toml = "0.20.5"
walkdir = "2" walkdir = "2.5.0"
[lints]
workspace = true

View File

@ -23,8 +23,11 @@ categories = [
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
log = "0.4.20" log = { workspace = true }
[lib] [lib]
name = "deexit" name = "deexit"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[lints]
workspace = true

View File

@ -25,10 +25,12 @@ categories = [
[dependencies] [dependencies]
libafl = { path = "../../../libafl", default-features = false } libafl = { path = "../../../libafl", default-features = false }
serde_json = "1.0" serde_json = { workspace = true, default-features = true }
regex = "1" regex = { workspace = true }
postcard = { version = "1.0", features = [ postcard = { workspace = true, features = [
"alloc", "alloc",
], default-features = false } # no_std compatible serde serialization format ], default-features = false } # no_std compatible serde serialization format
clap = { version = "4.5", features = ["derive"] } clap = { workspace = true, features = ["derive"] }
# log = "0.4.20"
[lints]
workspace = true

View File

@ -21,15 +21,21 @@ categories = [
] ]
[dev-dependencies] [dev-dependencies]
criterion = "0.5" # Benchmarking
ahash = { version = "0.8", default-features = false } # The hash function already used in hashbrown
rustc-hash = { version = "1.1", default-features = false } # yet another hash
xxhash-rust = { version = "0.8.5", features = ["xxh3"] } # xxh3 hashing for rust
libafl_bolts = { path = "../../libafl_bolts", default-features = false, features = [ libafl_bolts = { path = "../../libafl_bolts", default-features = false, features = [
"xxh3", "xxh3",
"alloc", "alloc",
] } # libafl_bolts ] } # libafl_bolts
criterion = "0.5.1" # Benchmarking
ahash = { workspace = true, default-features = false } # The hash function already used in hashbrown
rustc-hash = { version = "2.0.0", default-features = false } # yet another hash
xxhash-rust = { version = "0.8.12", features = [
"xxh3",
] } # xxh3 hashing for rust
[lints]
workspace = true
[[bench]] [[bench]]
name = "rand_speeds" name = "rand_speeds"
harness = false harness = false