Updated rust custom mutator bindgen, fixed clippy lints

This commit is contained in:
Dominik Maier
2023-01-05 12:12:01 +00:00
parent a8b6365a90
commit 462e55da0c
6 changed files with 57 additions and 57 deletions

View File

@ -1,12 +1,12 @@
[package] [package]
name = "custom_mutator-sys" name = "custom_mutator-sys"
version = "0.1.0" version = "0.1.1"
authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"] authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"]
edition = "2018" edition = "2021"
# 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]
[build-dependencies] [build-dependencies]
bindgen = "0.56" bindgen = "0.63"

View File

@ -15,8 +15,8 @@ fn main() {
// The input header we would like to generate // The input header we would like to generate
// bindings for. // bindings for.
.header("wrapper.h") .header("wrapper.h")
.whitelist_type("afl_state_t") .allowlist_type("afl_state_t")
.blacklist_type(r"u\d+") .blocklist_type(r"u\d+")
.opaque_type(r"_.*") .opaque_type(r"_.*")
.opaque_type("FILE") .opaque_type("FILE")
.opaque_type("in_addr(_t)?") .opaque_type("in_addr(_t)?")

View File

@ -1,5 +1,7 @@
#![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)]
#![allow(clippy::too_many_lines)]
#![allow(clippy::used_underscore_binding)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs")); include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

View File

@ -2,7 +2,7 @@
name = "custom_mutator" name = "custom_mutator"
version = "0.1.0" version = "0.1.0"
authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"] authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"]
edition = "2018" edition = "2021"
# 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

View File

@ -20,7 +20,7 @@
//! This binding is panic-safe in that it will prevent panics from unwinding into AFL++. Any panic will `abort` at the boundary between the custom mutator and AFL++. //! This binding is panic-safe in that it will prevent panics from unwinding into AFL++. Any panic will `abort` at the boundary between the custom mutator and AFL++.
//! //!
//! # Access to AFL++ internals //! # Access to AFL++ internals
//! This crate has an optional feature "afl_internals", which gives access to AFL++'s internal state. //! This crate has an optional feature "`afl_internals`", which gives access to AFL++'s internal state.
//! The state is passed to [`CustomMutator::init`], when the feature is activated. //! The state is passed to [`CustomMutator::init`], when the feature is activated.
//! //!
//! _This is completely unsafe and uses automatically generated types extracted from the AFL++ source._ //! _This is completely unsafe and uses automatically generated types extracted from the AFL++ source._
@ -115,7 +115,7 @@ pub mod wrappers {
impl<M: RawCustomMutator> FFIContext<M> { impl<M: RawCustomMutator> FFIContext<M> {
fn from(ptr: *mut c_void) -> ManuallyDrop<Box<Self>> { fn from(ptr: *mut c_void) -> ManuallyDrop<Box<Self>> {
assert!(!ptr.is_null()); assert!(!ptr.is_null());
ManuallyDrop::new(unsafe { Box::from_raw(ptr as *mut Self) }) ManuallyDrop::new(unsafe { Box::from_raw(ptr.cast::<Self>()) })
} }
fn into_ptr(self: Box<Self>) -> *const c_void { fn into_ptr(self: Box<Self>) -> *const c_void {
@ -141,27 +141,28 @@ pub mod wrappers {
} }
/// panic handler called for every panic /// panic handler called for every panic
fn panic_handler(method: &str, panic_info: Box<dyn Any + Send + 'static>) -> ! { fn panic_handler(method: &str, panic_info: &Box<dyn Any + Send + 'static>) -> ! {
use std::ops::Deref; use std::ops::Deref;
let cause = panic_info let cause = panic_info.downcast_ref::<String>().map_or_else(
.downcast_ref::<String>() || {
.map(String::deref)
.unwrap_or_else(|| {
panic_info panic_info
.downcast_ref::<&str>() .downcast_ref::<&str>()
.copied() .copied()
.unwrap_or("<cause unknown>") .unwrap_or("<cause unknown>")
}); },
eprintln!("A panic occurred at {}: {}", method, cause); String::deref,
);
eprintln!("A panic occurred at {method}: {cause}");
abort() abort()
} }
/// Internal function used in the macro /// Internal function used in the macro
#[cfg(not(feature = "afl_internals"))] #[cfg(not(feature = "afl_internals"))]
#[must_use]
pub fn afl_custom_init_<M: RawCustomMutator>(seed: u32) -> *const c_void { pub fn afl_custom_init_<M: RawCustomMutator>(seed: u32) -> *const c_void {
match catch_unwind(|| FFIContext::<M>::new(seed).into_ptr()) { match catch_unwind(|| FFIContext::<M>::new(seed).into_ptr()) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_init", err), Err(err) => panic_handler("afl_custom_init", &err),
} }
} }
@ -176,7 +177,7 @@ pub mod wrappers {
FFIContext::<M>::new(afl, seed).into_ptr() FFIContext::<M>::new(afl, seed).into_ptr()
}) { }) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_init", err), Err(err) => panic_handler("afl_custom_init", &err),
} }
} }
@ -196,32 +197,27 @@ pub mod wrappers {
) -> usize { ) -> usize {
match catch_unwind(|| { match catch_unwind(|| {
let mut context = FFIContext::<M>::from(data); let mut context = FFIContext::<M>::from(data);
if buf.is_null() {
panic!("null buf passed to afl_custom_fuzz") assert!(!buf.is_null(), "null buf passed to afl_custom_fuzz");
} assert!(!out_buf.is_null(), "null out_buf passed to afl_custom_fuzz");
if out_buf.is_null() {
panic!("null out_buf passed to afl_custom_fuzz")
}
let buff_slice = slice::from_raw_parts_mut(buf, buf_size); let buff_slice = slice::from_raw_parts_mut(buf, buf_size);
let add_buff_slice = if add_buf.is_null() { let add_buff_slice = if add_buf.is_null() {
None None
} else { } else {
Some(slice::from_raw_parts(add_buf, add_buf_size)) Some(slice::from_raw_parts(add_buf, add_buf_size))
}; };
match context.mutator.fuzz(buff_slice, add_buff_slice, max_size) { if let Some(buffer) = context.mutator.fuzz(buff_slice, add_buff_slice, max_size) {
Some(buffer) => { *out_buf = buffer.as_ptr();
*out_buf = buffer.as_ptr(); buffer.len()
buffer.len() } else {
} // return the input buffer with 0-length to let AFL skip this mutation attempt
None => { *out_buf = buf;
// return the input buffer with 0-length to let AFL skip this mutation attempt 0
*out_buf = buf;
0
}
} }
}) { }) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_fuzz", err), Err(err) => panic_handler("afl_custom_fuzz", &err),
} }
} }
@ -237,9 +233,8 @@ pub mod wrappers {
) -> u32 { ) -> u32 {
match catch_unwind(|| { match catch_unwind(|| {
let mut context = FFIContext::<M>::from(data); let mut context = FFIContext::<M>::from(data);
if buf.is_null() { assert!(!buf.is_null(), "null buf passed to afl_custom_fuzz");
panic!("null buf passed to afl_custom_fuzz")
}
let buf_slice = slice::from_raw_parts(buf, buf_size); let buf_slice = slice::from_raw_parts(buf, buf_size);
// see https://doc.rust-lang.org/nomicon/borrow-splitting.html // see https://doc.rust-lang.org/nomicon/borrow-splitting.html
let ctx = &mut **context; let ctx = &mut **context;
@ -247,7 +242,7 @@ pub mod wrappers {
mutator.fuzz_count(buf_slice) mutator.fuzz_count(buf_slice)
}) { }) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_fuzz_count", err), Err(err) => panic_handler("afl_custom_fuzz_count", &err),
} }
} }
@ -259,25 +254,27 @@ pub mod wrappers {
) -> bool { ) -> bool {
match catch_unwind(|| { match catch_unwind(|| {
let mut context = FFIContext::<M>::from(data); let mut context = FFIContext::<M>::from(data);
if filename_new_queue.is_null() { assert!(
panic!("received null filename_new_queue in afl_custom_queue_new_entry"); !filename_new_queue.is_null(),
} "received null filename_new_queue in afl_custom_queue_new_entry"
);
let filename_new_queue = Path::new(OsStr::from_bytes( let filename_new_queue = Path::new(OsStr::from_bytes(
unsafe { CStr::from_ptr(filename_new_queue) }.to_bytes(), unsafe { CStr::from_ptr(filename_new_queue) }.to_bytes(),
)); ));
let filename_orig_queue = if !filename_orig_queue.is_null() { let filename_orig_queue = if filename_orig_queue.is_null() {
None
} else {
Some(Path::new(OsStr::from_bytes( Some(Path::new(OsStr::from_bytes(
unsafe { CStr::from_ptr(filename_orig_queue) }.to_bytes(), unsafe { CStr::from_ptr(filename_orig_queue) }.to_bytes(),
))) )))
} else {
None
}; };
context context
.mutator .mutator
.queue_new_entry(filename_new_queue, filename_orig_queue) .queue_new_entry(filename_new_queue, filename_orig_queue)
}) { }) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_queue_new_entry", err), Err(err) => panic_handler("afl_custom_queue_new_entry", &err),
} }
} }
@ -292,7 +289,7 @@ pub mod wrappers {
ManuallyDrop::into_inner(FFIContext::<M>::from(data)); ManuallyDrop::into_inner(FFIContext::<M>::from(data));
}) { }) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_deinit", err), Err(err) => panic_handler("afl_custom_deinit", &err),
} }
} }
@ -306,13 +303,13 @@ pub mod wrappers {
buf.extend_from_slice(res.as_bytes()); buf.extend_from_slice(res.as_bytes());
buf.push(0); buf.push(0);
// unwrapping here, as the error case should be extremely rare // unwrapping here, as the error case should be extremely rare
CStr::from_bytes_with_nul(&buf).unwrap().as_ptr() CStr::from_bytes_with_nul(buf).unwrap().as_ptr()
} else { } else {
null() null()
} }
}) { }) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_introspection", err), Err(err) => panic_handler("afl_custom_introspection", &err),
} }
} }
@ -329,13 +326,13 @@ pub mod wrappers {
buf.extend_from_slice(res.as_bytes()); buf.extend_from_slice(res.as_bytes());
buf.push(0); buf.push(0);
// unwrapping here, as the error case should be extremely rare // unwrapping here, as the error case should be extremely rare
CStr::from_bytes_with_nul(&buf).unwrap().as_ptr() CStr::from_bytes_with_nul(buf).unwrap().as_ptr()
} else { } else {
null() null()
} }
}) { }) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_describe", err), Err(err) => panic_handler("afl_custom_describe", &err),
} }
} }
@ -348,12 +345,12 @@ pub mod wrappers {
let mut context = FFIContext::<M>::from(data); let mut context = FFIContext::<M>::from(data);
assert!(!filename.is_null()); assert!(!filename.is_null());
context.mutator.queue_get(Path::new(OsStr::from_bytes( u8::from(context.mutator.queue_get(Path::new(OsStr::from_bytes(
unsafe { CStr::from_ptr(filename) }.to_bytes(), unsafe { CStr::from_ptr(filename) }.to_bytes(),
))) as u8 ))))
}) { }) {
Ok(ret) => ret, Ok(ret) => ret,
Err(err) => panic_handler("afl_custom_queue_get", err), Err(err) => panic_handler("afl_custom_queue_get", &err),
} }
} }
} }
@ -373,7 +370,7 @@ macro_rules! _define_afl_custom_init {
}; };
} }
/// An exported macro to defined afl_custom_init meant for insternal usage /// An exported macro to defined `afl_custom_init` meant for internal usage
#[cfg(not(feature = "afl_internals"))] #[cfg(not(feature = "afl_internals"))]
#[macro_export] #[macro_export]
macro_rules! _define_afl_custom_init { macro_rules! _define_afl_custom_init {
@ -520,9 +517,10 @@ mod sanity_test {
export_mutator!(ExampleMutator); export_mutator!(ExampleMutator);
} }
#[allow(unused_variables)]
/// A custom mutator. /// A custom mutator.
/// [`CustomMutator::handle_error`] will be called in case any method returns an [`Result::Err`]. /// [`CustomMutator::handle_error`] will be called in case any method returns an [`Result::Err`].
#[allow(unused_variables)]
#[allow(clippy::missing_errors_doc)]
pub trait CustomMutator { pub trait CustomMutator {
/// The error type. All methods must return the same error type. /// The error type. All methods must return the same error type.
type Error: Debug; type Error: Debug;
@ -537,7 +535,7 @@ pub trait CustomMutator {
.map(|v| !v.is_empty()) .map(|v| !v.is_empty())
.unwrap_or(false) .unwrap_or(false)
{ {
eprintln!("Error in custom mutator: {:?}", err) eprintln!("Error in custom mutator: {err:?}");
} }
} }

View File

@ -2,7 +2,7 @@
name = "example_mutator" name = "example_mutator"
version = "0.1.0" version = "0.1.0"
authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"] authors = ["Julius Hohnerlein <julihoh@users.noreply.github.com>"]
edition = "2018" edition = "2021"
# 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