fixed examle, format

This commit is contained in:
Dominik Maier 2020-11-22 03:13:05 +01:00
parent f695684b03
commit 01d8b705c8
3 changed files with 117 additions and 121 deletions

View File

@ -5,12 +5,13 @@ use std::ptr;
use afl::events::llmp_translated::*; use afl::events::llmp_translated::*;
use std::convert::TryInto;
use std::{thread, time}; use std::{thread, time};
fn llmp_test_clientloop(client: *mut llmp_client, _data: *mut c_void) -> ! { fn llmp_test_clientloop(client: *mut llmp_client, _data: *mut c_void) -> ! {
let mut counter: u32 = 0; let mut counter: u32 = 0;
loop { loop {
counter += 10; counter += 1;
unsafe { unsafe {
let llmp_message = llmp_client_alloc_next(client, 10); let llmp_message = llmp_client_alloc_next(client, 10);
@ -28,34 +29,34 @@ fn llmp_test_clientloop(client: *mut llmp_client, _data: *mut c_void) -> ! {
} }
fn broker_message_hook( fn broker_message_hook(
broker: *mut llmp_broker_state, _broker: *mut llmp_broker_state,
client_metadata: *mut llmp_broker_client_metadata, client_metadata: *mut llmp_broker_client_metadata,
message: *mut llmp_message, message: *mut llmp_message,
_data: *mut c_void, _data: *mut c_void,
) -> LlmpMessageHookResult { ) -> LlmpMessageHookResult {
unsafe { unsafe {
match (*message).tag { match (*message).tag {
1 => { 1 => {
// TODO: use higher bits println!(
let counter_lowest = (std::slice::from_raw_parts((*message).buf.as_ptr(), 4))[3]; "Client {:?} sent message: {:?}",
println!( (*client_metadata).pid,
"Got message {:?} from client {:?}", u32::from_be_bytes(
counter_lowest, std::slice::from_raw_parts((*message).buf.as_ptr(), 4)
(*client_metadata).pid .try_into()
); .unwrap()
LlmpMessageHookResult::Handled ),
}, );
_ => { LlmpMessageHookResult::Handled
println!("Unknwon message id received!"); }
LlmpMessageHookResult::ForwardToClients _ => {
println!("Unknwon message id received!");
LlmpMessageHookResult::ForwardToClients
}
} }
} }
}
} }
fn main() { fn main() {
/* The main node has a broker, a tcp server, and a few worker threads */ /* The main node has a broker, a tcp server, and a few worker threads */
let mut broker = llmp_broker_state { let mut broker = llmp_broker_state {
@ -67,7 +68,7 @@ fn main() {
llmp_client_count: 0, llmp_client_count: 0,
llmp_clients: ptr::null_mut(), llmp_clients: ptr::null_mut(),
}; };
let thread_count = 4; let thread_count = 3;
unsafe { unsafe {
llmp_broker_init(&mut broker).expect("Could not init"); llmp_broker_init(&mut broker).expect("Could not init");
for i in 0..thread_count { for i in 0..thread_count {

View File

@ -54,10 +54,10 @@ use core::sync::atomic::{compiler_fence, Ordering};
use libc::{c_int, c_uint, c_ulong, c_ushort, c_void}; use libc::{c_int, c_uint, c_ulong, c_ushort, c_void};
use std::ffi::CStr; use std::ffi::CStr;
use crate::AflError;
use crate::utils::next_pow2; use crate::utils::next_pow2;
use crate::AflError;
use super::shmem_translated::{afl_shmem_deinit, afl_shmem_init, afl_shmem_by_str, afl_shmem}; use super::shmem_translated::{afl_shmem, afl_shmem_by_str, afl_shmem_deinit, afl_shmem_init};
extern "C" { extern "C" {
#[no_mangle] #[no_mangle]
@ -319,10 +319,7 @@ unsafe fn _llmp_next_msg_ptr(last_msg: *mut llmp_message) -> *mut llmp_message {
.offset((*last_msg).buf_len_padded as isize) as *mut llmp_message; .offset((*last_msg).buf_len_padded as isize) as *mut llmp_message;
} }
/* Read next message. */ /* Read next message. */
pub unsafe fn llmp_recv( pub unsafe fn llmp_recv(page: *mut llmp_page, last_msg: *mut llmp_message) -> *mut llmp_message {
page: *mut llmp_page,
last_msg: *mut llmp_message,
) -> *mut llmp_message {
/* DBG("llmp_recv %p %p\n", page, last_msg); */ /* DBG("llmp_recv %p %p\n", page, last_msg); */
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
if (*page).current_msg_id == 0 { if (*page).current_msg_id == 0 {
@ -894,7 +891,7 @@ pub unsafe fn llmp_broker_once(broker: *mut llmp_broker_state) {
} }
/* The broker walks all pages and looks for changes, then broadcasts them on /* The broker walks all pages and looks for changes, then broadcasts them on
* its own shared page */ * its own shared page */
pub unsafe fn llmp_broker_loop(broker: *mut llmp_broker_state) -> !{ pub unsafe fn llmp_broker_loop(broker: *mut llmp_broker_state) -> ! {
loop { loop {
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
llmp_broker_once(broker); llmp_broker_once(broker);
@ -922,9 +919,7 @@ unsafe fn llmp_clientrigger_new_out_page_hooks(client: *mut llmp_client) {
} }
} }
/* A wrapper around unpacking the data, calling through to the loop */ /* A wrapper around unpacking the data, calling through to the loop */
unsafe fn _llmp_client_wrapped_loop( unsafe fn _llmp_client_wrapped_loop(llmp_client_broker_metadata_ptr: *mut c_void) -> ! {
llmp_client_broker_metadata_ptr: *mut c_void,
) -> ! {
let metadata: *mut llmp_broker_client_metadata = let metadata: *mut llmp_broker_client_metadata =
llmp_client_broker_metadata_ptr as *mut llmp_broker_client_metadata; llmp_client_broker_metadata_ptr as *mut llmp_broker_client_metadata;
/* Before doing anything else:, notify registered hooks about the new page we're about to use */ /* Before doing anything else:, notify registered hooks about the new page we're about to use */
@ -986,7 +981,9 @@ pub unsafe fn llmp_broker_launch_client(
//return 1 as c_int != 0; //return 1 as c_int != 0;
} }
pub unsafe fn llmp_broker_launch_clientloops(broker: *mut llmp_broker_state) -> Result<(), AflError> { pub unsafe fn llmp_broker_launch_clientloops(
broker: *mut llmp_broker_state,
) -> Result<(), AflError> {
let mut i: c_ulong = 0; let mut i: c_ulong = 0;
while i < (*broker).llmp_client_count { while i < (*broker).llmp_client_count {
if (*(*broker).llmp_clients.offset(i as isize)).client_type as c_uint if (*(*broker).llmp_clients.offset(i as isize)).client_type as c_uint
@ -994,7 +991,7 @@ pub unsafe fn llmp_broker_launch_clientloops(broker: *mut llmp_broker_state) ->
{ {
if !llmp_broker_launch_client(broker, &mut *(*broker).llmp_clients.offset(i as isize)) { if !llmp_broker_launch_client(broker, &mut *(*broker).llmp_clients.offset(i as isize)) {
println!("[!] WARNING: Could not launch all clients"); println!("[!] WARNING: Could not launch all clients");
return Err(AflError::Unknown("Failed to launch clients".into())) return Err(AflError::Unknown("Failed to launch clients".into()));
} }
} }
i = i.wrapping_add(1) i = i.wrapping_add(1)
@ -1154,10 +1151,7 @@ pub unsafe fn llmp_client_recv_blocking(client: *mut llmp_client) -> *mut llmp_m
} }
/* The current page could have changed in recv (EOP) */ /* The current page could have changed in recv (EOP) */
/* Alloc the next message, internally handling end of page by allocating a new one. */ /* Alloc the next message, internally handling end of page by allocating a new one. */
pub unsafe fn llmp_client_alloc_next( pub unsafe fn llmp_client_alloc_next(client: *mut llmp_client, size: c_ulong) -> *mut llmp_message {
client: *mut llmp_client,
size: c_ulong,
) -> *mut llmp_message {
if client.is_null() { if client.is_null() {
panic!("Client is NULL"); panic!("Client is NULL");
} }
@ -1231,10 +1225,7 @@ pub unsafe fn llmp_client_cancel(client: *mut llmp_client, mut msg: *mut llmp_me
) as c_ulong; ) as c_ulong;
} }
/* Commits a msg to the client's out ringbuf */ /* Commits a msg to the client's out ringbuf */
pub unsafe fn llmp_client_send( pub unsafe fn llmp_client_send(mut client_state: *mut llmp_client, msg: *mut llmp_message) -> bool {
mut client_state: *mut llmp_client,
msg: *mut llmp_message,
) -> bool {
let page: *mut llmp_page = shmem2page( let page: *mut llmp_page = shmem2page(
&mut *(*client_state).out_maps.offset( &mut *(*client_state).out_maps.offset(
(*client_state) (*client_state)
@ -1334,8 +1325,11 @@ pub unsafe fn llmp_broker_register_childprocess_clientloop(
{ {
return Err(AflError::Unknown("Alloc".into())); return Err(AflError::Unknown("Alloc".into()));
} }
let mut client: *mut llmp_broker_client_metadata = let mut client: *mut llmp_broker_client_metadata = llmp_broker_register_client(
llmp_broker_register_client(broker, CStr::from_ptr(&client_map.shm_str as *const i8), client_map.map_size); broker,
CStr::from_ptr(&client_map.shm_str as *const i8),
client_map.map_size,
);
if client.is_null() { if client.is_null() {
afl_shmem_deinit(&mut client_map); afl_shmem_deinit(&mut client_map);
return Err(AflError::Unknown("Something in clients failed".into())); return Err(AflError::Unknown("Something in clients failed".into()));

View File

@ -1,31 +1,24 @@
use ::libc; use ::libc;
use libc::{c_int, c_uint, c_char, c_uchar, c_ushort, c_long, c_ulong, c_void}; use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_ushort, c_void};
use std::ffi::CStr; use std::ffi::CStr;
extern "C" { extern "C" {
#[no_mangle] #[no_mangle]
fn snprintf(_: *mut c_char, _: c_ulong, fn snprintf(_: *mut c_char, _: c_ulong, _: *const c_char, _: ...) -> c_int;
_: *const c_char, _: ...) -> c_int;
#[no_mangle] #[no_mangle]
fn strncpy(_: *mut c_char, _: *const c_char, _: c_ulong) fn strncpy(_: *mut c_char, _: *const c_char, _: c_ulong) -> *mut c_char;
-> *mut c_char;
#[no_mangle] #[no_mangle]
fn strlen(_: *const c_char) -> c_ulong; fn strlen(_: *const c_char) -> c_ulong;
#[no_mangle] #[no_mangle]
fn shmctl(__shmid: c_int, __cmd: c_int, __buf: *mut shmid_ds) fn shmctl(__shmid: c_int, __cmd: c_int, __buf: *mut shmid_ds) -> c_int;
-> c_int;
#[no_mangle] #[no_mangle]
fn shmget(__key: c_int, __size: c_ulong, __shmflg: c_int) fn shmget(__key: c_int, __size: c_ulong, __shmflg: c_int) -> c_int;
-> c_int;
#[no_mangle] #[no_mangle]
fn shmat(__shmid: c_int, __shmaddr: *const c_void, fn shmat(__shmid: c_int, __shmaddr: *const c_void, __shmflg: c_int) -> *mut c_void;
__shmflg: c_int) -> *mut c_void;
#[no_mangle] #[no_mangle]
fn strtol(_: *const c_char, _: *mut *mut c_char, fn strtol(_: *const c_char, _: *mut *mut c_char, _: c_int) -> c_long;
_: c_int) -> c_long;
#[no_mangle] #[no_mangle]
fn setenv(__name: *const c_char, __value: *const c_char, fn setenv(__name: *const c_char, __value: *const c_char, __replace: c_int) -> c_int;
__replace: c_int) -> c_int;
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
@ -95,104 +88,112 @@ pub unsafe fn afl_shmem_deinit(mut shm: *mut afl_shmem) {
if shm.is_null() || (*shm).map.is_null() { if shm.is_null() || (*shm).map.is_null() {
/* Serialized map id */ /* Serialized map id */
// Not set or not initialized; // Not set or not initialized;
return return;
} }
(*shm).shm_str[0 as usize] = (*shm).shm_str[0 as usize] = '\u{0}' as c_char;
'\u{0}' as c_char;
shmctl((*shm).shm_id, 0 as c_int, 0 as *mut shmid_ds); shmctl((*shm).shm_id, 0 as c_int, 0 as *mut shmid_ds);
(*shm).map = 0 as *mut c_uchar; (*shm).map = 0 as *mut c_uchar;
} }
// Functions to create Shared memory region, for observation channels and // Functions to create Shared memory region, for observation channels and
// opening inputs and stuff. // opening inputs and stuff.
pub unsafe fn afl_shmem_init(mut shm: *mut afl_shmem, pub unsafe fn afl_shmem_init(mut shm: *mut afl_shmem, map_size: c_ulong) -> *mut c_uchar {
map_size: c_ulong) -> *mut c_uchar {
(*shm).map_size = map_size; (*shm).map_size = map_size;
(*shm).map = 0 as *mut c_uchar; (*shm).map = 0 as *mut c_uchar;
(*shm).shm_id = (*shm).shm_id = shmget(
shmget(0 as c_int, map_size, 0 as c_int,
0o1000 as c_int | 0o2000 as c_int | map_size,
0o600 as c_int); 0o1000 as c_int | 0o2000 as c_int | 0o600 as c_int,
);
if (*shm).shm_id < 0 as c_int { if (*shm).shm_id < 0 as c_int {
(*shm).shm_str[0] = (*shm).shm_str[0] = '\u{0}' as c_char;
'\u{0}' as c_char; return 0 as *mut c_uchar;
return 0 as *mut c_uchar
} }
snprintf((*shm).shm_str.as_mut_ptr() as *mut i8, snprintf(
::std::mem::size_of::<[c_char; 20]>() as c_ulong, (*shm).shm_str.as_mut_ptr() as *mut i8,
b"%d\x00" as *const u8 as *const c_char, (*shm).shm_id); ::std::mem::size_of::<[c_char; 20]>() as c_ulong,
(*shm).shm_str[(::std::mem::size_of::<[c_char; 20]>() as b"%d\x00" as *const u8 as *const c_char,
c_ulong).wrapping_sub(1 as c_int as (*shm).shm_id,
c_ulong) as );
usize] = '\u{0}' as c_char; (*shm).shm_str[(::std::mem::size_of::<[c_char; 20]>() as c_ulong)
(*shm).map = .wrapping_sub(1 as c_int as c_ulong) as usize] = '\u{0}' as c_char;
shmat((*shm).shm_id, 0 as *const c_void, 0 as c_int) as (*shm).map = shmat((*shm).shm_id, 0 as *const c_void, 0 as c_int) as *mut c_uchar;
*mut c_uchar; if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar || (*shm).map.is_null() {
if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar ||
(*shm).map.is_null() {
shmctl((*shm).shm_id, 0 as c_int, 0 as *mut shmid_ds); shmctl((*shm).shm_id, 0 as c_int, 0 as *mut shmid_ds);
(*shm).shm_id = -(1 as c_int); (*shm).shm_id = -(1 as c_int);
(*shm).shm_str[0 as c_int as usize] = (*shm).shm_str[0 as c_int as usize] = '\u{0}' as c_char;
'\u{0}' as c_char; return 0 as *mut c_uchar;
return 0 as *mut c_uchar
} }
return (*shm).map; return (*shm).map;
} }
pub unsafe fn afl_shmem_by_str(mut shm: *mut afl_shmem, pub unsafe fn afl_shmem_by_str(
shm_str: &CStr, mut shm: *mut afl_shmem,
map_size: c_ulong) -> *mut c_uchar { shm_str: &CStr,
map_size: c_ulong,
) -> *mut c_uchar {
if shm.is_null() || shm_str.to_bytes().len() == 0 || map_size == 0 { if shm.is_null() || shm_str.to_bytes().len() == 0 || map_size == 0 {
return 0 as *mut c_uchar return 0 as *mut c_uchar;
} }
(*shm).map = 0 as *mut c_uchar; (*shm).map = 0 as *mut c_uchar;
(*shm).map_size = map_size; (*shm).map_size = map_size;
strncpy((*shm).shm_str.as_mut_ptr() as *mut c_char, shm_str.as_ptr() as *const c_char, strncpy(
(::std::mem::size_of::<[c_char; 20]>() as (*shm).shm_str.as_mut_ptr() as *mut c_char,
c_ulong).wrapping_sub(1 as c_int as shm_str.as_ptr() as *const c_char,
c_ulong)); (::std::mem::size_of::<[c_char; 20]>() as c_ulong).wrapping_sub(1 as c_int as c_ulong),
(*shm).shm_id = shm_str.to_str().expect(&format!("illegal shm_str {:?}", shm_str)).parse::<i32>().unwrap(); );
(*shm).map = (*shm).shm_id = shm_str
shmat((*shm).shm_id, 0 as *const c_void, 0 as c_int) as .to_str()
*mut c_uchar; .expect(&format!("illegal shm_str {:?}", shm_str))
.parse::<i32>()
.unwrap();
(*shm).map = shmat((*shm).shm_id, 0 as *const c_void, 0 as c_int) as *mut c_uchar;
if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar { if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar {
(*shm).map = 0 as *mut c_uchar; (*shm).map = 0 as *mut c_uchar;
(*shm).map_size = 0 as c_int as c_ulong; (*shm).map_size = 0 as c_int as c_ulong;
(*shm).shm_str[0 as c_int as usize] = (*shm).shm_str[0 as c_int as usize] = '\u{0}' as c_char;
'\u{0}' as c_char; return 0 as *mut c_uchar;
return 0 as *mut c_uchar
} }
return (*shm).map; return (*shm).map;
} }
/* Write sharedmap as env var */ /* Write sharedmap as env var */
/* Write sharedmap as env var and the size as name#_SIZE */ /* Write sharedmap as env var and the size as name#_SIZE */
pub unsafe fn afl_shmem_to_env_var(shmem: &afl_shmem, pub unsafe fn afl_shmem_to_env_var(shmem: &afl_shmem, env_name: &CStr) -> c_uint {
env_name: &CStr)
-> c_uint {
let env_len = env_name.to_bytes().len(); let env_len = env_name.to_bytes().len();
if env_len == 0 || env_len > 200 || if env_len == 0 || env_len > 200 || (*shmem).shm_str[0 as c_int as usize] == 0 {
(*shmem).shm_str[0 as c_int as usize] == 0 { return AFL_RET_NULL_PTR;
return AFL_RET_NULL_PTR
} }
let mut shm_str: [c_char; 256] = [0; 256]; let mut shm_str: [c_char; 256] = [0; 256];
snprintf(shm_str.as_mut_ptr(), snprintf(
::std::mem::size_of::<[c_char; 256]>() as c_ulong, shm_str.as_mut_ptr(),
b"%d\x00" as *const u8 as *const c_char, (*shmem).shm_id); ::std::mem::size_of::<[c_char; 256]>() as c_ulong,
if setenv(env_name.as_ptr() as *const c_char, shm_str.as_mut_ptr(), 1 as c_int) < b"%d\x00" as *const u8 as *const c_char,
0 as c_int { (*shmem).shm_id,
return AFL_RET_ERRNO );
if setenv(
env_name.as_ptr() as *const c_char,
shm_str.as_mut_ptr(),
1 as c_int,
) < 0 as c_int
{
return AFL_RET_ERRNO;
} }
/* Write the size to env, too */ /* Write the size to env, too */
let mut size_env_name: [c_char; 256] = [0; 256]; let mut size_env_name: [c_char; 256] = [0; 256];
snprintf(size_env_name.as_mut_ptr(), snprintf(
::std::mem::size_of::<[c_char; 256]>() as c_ulong, size_env_name.as_mut_ptr(),
b"%s_SIZE\x00" as *const u8 as *const c_char, env_name); ::std::mem::size_of::<[c_char; 256]>() as c_ulong,
snprintf(shm_str.as_mut_ptr(), b"%s_SIZE\x00" as *const u8 as *const c_char,
::std::mem::size_of::<[c_char; 256]>() as c_ulong, env_name,
b"%d\x00" as *const u8 as *const c_char, (*shmem).shm_id); );
if setenv(size_env_name.as_mut_ptr(), shm_str.as_mut_ptr(), snprintf(
1 as c_int) < 0 as c_int { shm_str.as_mut_ptr(),
return AFL_RET_ERRNO ::std::mem::size_of::<[c_char; 256]>() as c_ulong,
b"%d\x00" as *const u8 as *const c_char,
(*shmem).shm_id,
);
if setenv(size_env_name.as_mut_ptr(), shm_str.as_mut_ptr(), 1 as c_int) < 0 as c_int {
return AFL_RET_ERRNO;
} }
return AFL_RET_SUCCESS; return AFL_RET_SUCCESS;
} }