Format desyscall (#2316)

* f

* clippy and stuff

* no apple
This commit is contained in:
Dongjia "toka" Zhang 2024-06-16 13:20:08 +02:00 committed by GitHub
parent 888079aea5
commit 51db18eea8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 80 additions and 47 deletions

View File

@ -20,6 +20,7 @@ members = [
"utils/deexit",
"utils/libafl_benches",
"utils/gramatron/construct_automata",
"utils/desyscall",
]
default-members = [
"libafl",

View File

@ -12,7 +12,6 @@
// For `std::simd`
#![cfg_attr(nightly, feature(portable_simd))]
// For `core::error`
#![cfg_attr(nightly, feature(error_in_core))]
#![warn(clippy::cargo)]
#![allow(ambiguous_glob_reexports)]
#![deny(clippy::cargo_common_metadata)]

View File

@ -1,4 +1,4 @@
/* 1.80.0-nightly */
/* 1.81.0-nightly */
/* automatically generated by rust-bindgen 0.69.4 */
#[repr(C)]
@ -2341,6 +2341,7 @@ pub type DeviceReset = ::std::option::Option<unsafe extern "C" fn(dev: *mut Devi
#[derive(Debug, Copy, Clone)]
pub struct DeviceClass {
pub parent_class: ObjectClass,
#[doc = " @categories: device categories device belongs to"]
pub categories: [::std::os::raw::c_ulong; 1usize],
#[doc = " @fw_name: name used to identify device to firmware interfaces"]
pub fw_name: *const ::std::os::raw::c_char,

View File

@ -1,4 +1,4 @@
/* 1.80.0-nightly */
/* 1.81.0-nightly */
/* automatically generated by rust-bindgen 0.69.4 */
pub const _STDINT_H: u32 = 1;
@ -36,7 +36,7 @@ pub const __STDC_IEC_60559_COMPLEX__: u32 = 201404;
pub const __STDC_ISO_10646__: u32 = 201706;
pub const __GNU_LIBRARY__: u32 = 6;
pub const __GLIBC__: u32 = 2;
pub const __GLIBC_MINOR__: u32 = 39;
pub const __GLIBC_MINOR__: u32 = 38;
pub const _SYS_CDEFS_H: u32 = 1;
pub const __glibc_c99_flexarr_available: u32 = 1;
pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0;
@ -60,7 +60,6 @@ pub const _BITS_TIME64_H: u32 = 1;
pub const _BITS_WCHAR_H: u32 = 1;
pub const _BITS_STDINT_INTN_H: u32 = 1;
pub const _BITS_STDINT_UINTN_H: u32 = 1;
pub const _BITS_STDINT_LEAST_H: u32 = 1;
pub const INT8_MIN: i32 = -128;
pub const INT16_MIN: i32 = -32768;
pub const INT32_MIN: i32 = -2147483648;

View File

@ -2,6 +2,11 @@
name = "desyscall"
version = "0.1.0"
edition = "2021"
description = "DeSyscall: Hooks syscalls for reduces overhead during in-process fuzzing"
repository = "https://github.com/AFLplusplus/LibAFL/"
license = "MIT OR Apache-2.0"
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
keywords = ["fuzzing", "libafl", "ldpreload"]
[dependencies]
meminterval = "0.3"

View File

@ -3,6 +3,11 @@
use std::env;
fn main() {
if cfg!(not(target_os = "linux")) {
println!("Not supported!");
return;
}
let out_dir = env::var_os("OUT_DIR").unwrap();
let out_dir = out_dir.to_string_lossy().to_string();

View File

@ -9,8 +9,11 @@ extern "C" {
fn __libafl_raw_read(fd: c_int, buf: Pointer, count: size_t) -> ssize_t;
}
/// # Safety
/// Call to functions using syscalls
#[allow(clippy::cast_possible_wrap)]
#[no_mangle]
pub unsafe fn write(fd: c_int, buf: Pointer, count: size_t) -> ssize_t {
pub unsafe extern "C" fn write(fd: c_int, buf: Pointer, count: size_t) -> ssize_t {
let ctx = Context::get();
if ctx.enabled && (fd == 1 || fd == 2) {
@ -20,11 +23,13 @@ pub unsafe fn write(fd: c_int, buf: Pointer, count: size_t) -> ssize_t {
}
}
/// # Safety
/// Call to functions using syscalls
#[no_mangle]
pub unsafe fn read(fd: c_int, buf: Pointer, count: size_t) -> ssize_t {
pub unsafe extern "C" fn read(fd: c_int, buf: Pointer, count: size_t) -> ssize_t {
let ctx = Context::get();
if ctx.enabled && fd >= 0 && fd <= 2 {
if ctx.enabled && (0..=2).contains(&fd) {
0
} else {
__libafl_raw_read(fd, buf, count)

View File

@ -1,6 +1,7 @@
use std::{mem::MaybeUninit, sync::Once};
use libc::{c_int, c_void};
use meminterval::IntervalTree;
use std::{mem::MaybeUninit, sync::Once};
pub mod file;
pub mod mmap;
@ -20,7 +21,14 @@ pub struct Context {
exit_hook: Option<Box<dyn FnMut(i32)>>,
}
impl Default for Context {
fn default() -> Self {
Self::new()
}
}
impl Context {
#[must_use]
pub fn new() -> Self {
Self {
enabled: false,
@ -73,13 +81,15 @@ extern "C" {
}
// void _exit(int status);
/// # Safety
/// Call to function using syscalls
#[no_mangle]
pub unsafe fn _exit(status: c_int) {
pub unsafe extern "C" fn _exit(status: c_int) {
let ctx = Context::get();
if ctx.enabled {
if let Some(hook) = &mut ctx.exit_hook {
(hook)(status as i32);
(hook)(status);
}
}

View File

@ -1,6 +1,7 @@
use std::ptr;
use libc::{c_int, c_void, off_t, size_t};
use meminterval::Interval;
use std::ptr;
use crate::{Context, Mapping, Pointer};
@ -36,8 +37,11 @@ extern "C" {
fn __libafl_raw_madvise(addr: *mut c_void, length: size_t, advice: c_int) -> c_int;
}
/// # Safety
/// Call to functions using syscalls
#[no_mangle]
pub unsafe fn mmap(
#[allow(clippy::too_many_lines)]
pub unsafe extern "C" fn mmap(
addr: Pointer,
length: size_t,
prot: c_int,
@ -66,7 +70,7 @@ pub unsafe fn mmap(
continue;
}
if length <= entry.interval.end as usize - entry.interval.start as usize {
candidate = Some((entry.interval.clone(), entry.value.clone()));
candidate = Some((*entry.interval, entry.value.clone()));
break;
}
}
@ -76,7 +80,7 @@ pub unsafe fn mmap(
if length < size {
ctx.mappings.delete(cand.0);
let end = cand.0.start.offset(length as isize);
let end = cand.0.start.add(length);
ctx.mappings.insert(
cand.0.start..end,
Mapping {
@ -100,7 +104,7 @@ pub unsafe fn mmap(
let ret = __libafl_raw_mmap(addr, length, prot, flags, fd, offset) as Pointer;
if ret != libc::MAP_FAILED as Pointer {
let end = ret.offset(length as isize);
let end = ret.add(length);
ctx.mappings.insert(
ret..end,
Mapping {
@ -119,7 +123,7 @@ pub unsafe fn mmap(
return ret;
}
let end = addr.offset(length as isize);
let end = addr.add(length);
let mut prev: Option<(_, _)> = None;
let mut fail = false;
@ -133,13 +137,11 @@ pub unsafe fn mmap(
if entry.interval.start != p.0 {
fail = true;
}
} else {
if entry.interval.start > addr {
} else if entry.interval.start > addr {
fail = true;
} else if entry.interval.start < addr {
reminder = Some((entry.interval.start, entry.value.clone()));
}
}
if entry.value.prot != prot {
fail = true;
}
@ -148,12 +150,13 @@ pub unsafe fn mmap(
already_mapped = true;
}
intervals.push(entry.interval.clone());
intervals.push(*entry.interval);
prev = Some((entry.interval.end, entry.value));
}
let mut reminder_next = None;
#[allow(clippy::comparison_chain)]
if let Some(p) = prev.take() {
if p.0 < end {
fail = true;
@ -216,8 +219,10 @@ pub unsafe fn mmap(
ret
}
/// # Safety
/// Call to functions using syscalls
#[no_mangle]
pub unsafe fn munmap(addr: *mut c_void, length: size_t) -> c_int {
pub unsafe extern "C" fn munmap(addr: *mut c_void, length: size_t) -> c_int {
let ctx = Context::get();
if !ctx.enabled {
@ -234,7 +239,7 @@ pub unsafe fn munmap(addr: *mut c_void, length: size_t) -> c_int {
} else {
length
};
let end = addr.offset(aligned_length as isize);
let end = addr.add(aligned_length);
ctx.disable();
@ -286,7 +291,7 @@ pub unsafe fn munmap(addr: *mut c_void, length: size_t) -> c_int {
new_entries.push((Interval::new(end, entry.interval.end), entry.value.clone()));
}
intervals.push(entry.interval.clone());
intervals.push(*entry.interval);
}
for interval in intervals {
@ -302,8 +307,10 @@ pub unsafe fn munmap(addr: *mut c_void, length: size_t) -> c_int {
0
}
/// # Safety
/// Calling to functions using syscalls
#[no_mangle]
pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: c_int) -> c_int {
pub unsafe extern "C" fn mprotect(addr: *mut c_void, length: size_t, prot: c_int) -> c_int {
let ctx = Context::get();
if !ctx.enabled {
@ -316,7 +323,7 @@ pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: c_int) -> c_int
} else {
length
};
let end = addr.offset(aligned_length as isize);
let end = addr.add(aligned_length);
ctx.disable();
@ -324,12 +331,10 @@ pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: c_int) -> c_int
if let Some(mut entry) = query_iter.next() {
// cache the repeated mprotects on the same region
if entry.interval.start == addr && entry.interval.end == end {
if entry.value.prot == prot {
if entry.interval.start == addr && entry.interval.end == end && entry.value.prot == prot {
ctx.enable();
return 0;
}
}
let ret = __libafl_raw_mprotect(addr, length, prot);
// return on error
@ -385,7 +390,7 @@ pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: c_int) -> c_int
new_entries.push((Interval::new(end, entry.interval.end), entry.value.clone()));
}
intervals.push(entry.interval.clone());
intervals.push(*entry.interval);
if let Some(next) = query_iter.next() {
entry = next;
@ -427,8 +432,10 @@ pub unsafe fn mprotect(addr: *mut c_void, length: size_t, prot: c_int) -> c_int
}
}
/// # Safety
/// Call to functions using syscalls
#[no_mangle]
pub unsafe fn madvise(addr: *mut c_void, length: size_t, advice: c_int) -> c_int {
pub unsafe extern "C" fn madvise(addr: *mut c_void, length: size_t, advice: c_int) -> c_int {
let ctx = Context::get();
if ctx.enabled && advice == libc::MADV_DONTNEED {
@ -440,8 +447,9 @@ pub unsafe fn madvise(addr: *mut c_void, length: size_t, advice: c_int) -> c_int
#[cfg(test)]
mod tests {
use super::*;
use rusty_fork::rusty_fork_test;
use super::*;
// cargo test -- --nocapture --test-threads=1
rusty_fork_test! {
@ -453,7 +461,7 @@ mod tests {
let p = mmap(0x7ffff9f9e000usize as Pointer, 4096, 0x7, 0x22, 0, 0);
assert!(p as isize != -1);
println!("Pre {:?}", p);
println!("Pre {p:?}", );
Context::get().print_mappings();
let r = munmap(p, 1);
@ -474,10 +482,10 @@ mod tests {
let p = mmap(0x7ffff9f9e000usize as Pointer, PAGE_SIZE*4, 0x7, 0x22, 0, 0);
assert!(p as isize != -1);
println!("Pre {:?}", p);
println!("Pre {p:?}",);
Context::get().print_mappings();
let r = munmap(p.offset(PAGE_SIZE as isize), PAGE_SIZE*2);
let r = munmap(p.add(PAGE_SIZE), PAGE_SIZE*2);
assert!(r == 0);
println!("Post");
@ -495,19 +503,19 @@ mod tests {
let p = mmap(0x7ffff9f9e000usize as Pointer, PAGE_SIZE*4, 0x7, 0x22, 0, 0);
assert!(p as isize != -1);
println!("Pre {:?}", p);
println!("Pre {p:?}");
Context::get().print_mappings();
let r = munmap(p.offset(PAGE_SIZE as isize), PAGE_SIZE*2);
let r = munmap(p.add(PAGE_SIZE), PAGE_SIZE*2);
assert!(r == 0);
println!("Post");
Context::get().print_mappings();
let p = mmap(p.offset(PAGE_SIZE as isize), PAGE_SIZE, 0x1, 0x22, 0, 0);
let p = mmap(p.add(PAGE_SIZE), PAGE_SIZE, 0x1, 0x22, 0, 0);
assert!(p as isize != -1);
println!("Remap {:?}", p);
println!("Remap {p:?}");
Context::get().print_mappings();
}
}
@ -522,10 +530,10 @@ mod tests {
let p = mmap(0 as Pointer, PAGE_SIZE*4, 0x7, 0x22, 0, 0);
assert!(p as isize != -1);
println!("Pre {:?}", p);
println!("Pre {p:?}");
Context::get().print_mappings();
let r = munmap(p.offset(PAGE_SIZE as isize), PAGE_SIZE*2);
let r = munmap(p.add(PAGE_SIZE), PAGE_SIZE*2);
assert!(r == 0);
println!("Post");
@ -534,7 +542,7 @@ mod tests {
let p = mmap(0 as Pointer, PAGE_SIZE, 0x7, 0x22, 0, 0);
assert!(p as isize != -1);
println!("Remap {:?}", p);
println!("Remap {p:?}");
Context::get().print_mappings();
}
}