make aux_buffer_size configurable

This commit is contained in:
Sergej Schumilo 2023-07-23 13:03:49 +02:00
parent c8a72dc3b3
commit cd8a22bca4
6 changed files with 75 additions and 11 deletions

View File

@ -7,6 +7,8 @@ use crate::loader::*;
use libc::fcntl;
const DEFAULT_AUX_BUFFER_SIZE: usize = 4096;
fn into_absolute_path(path_to_sharedir: &str, path_to_file: String) -> String {
let path_to_default_config = Path::new(&path_to_file);
@ -214,6 +216,9 @@ pub struct RuntimeConfig {
/* worker_id of the current QEMU Nyx instance */
worker_id: usize,
/* aux_buffer size */
aux_buffer_size: usize,
}
impl RuntimeConfig{
@ -224,6 +229,7 @@ impl RuntimeConfig{
reuse_snapshot_path: None,
debug_mode: false,
worker_id: 0,
aux_buffer_size: DEFAULT_AUX_BUFFER_SIZE,
}
}
@ -273,6 +279,20 @@ impl RuntimeConfig{
pub fn set_worker_id(&mut self, thread_id: usize){
self.worker_id = thread_id;
}
pub fn set_aux_buffer_size(&mut self, aux_buffer_size: usize) -> bool{
if aux_buffer_size < DEFAULT_AUX_BUFFER_SIZE || (aux_buffer_size & 0xfff) != 0 {
return false;
}
self.aux_buffer_size = aux_buffer_size;
return true
}
pub fn aux_buffer_size(&self) -> usize {
self.aux_buffer_size
}
}

View File

@ -46,11 +46,12 @@ pub struct AuxBuffer {
pub config: &'static mut auxilary_buffer_config_s,
pub result: &'static mut auxilary_buffer_result_s,
pub misc: &'static mut auxilary_buffer_misc_s,
size: usize, /* total size of the aux buffer */
}
impl AuxBuffer {
pub fn new_readonly(file: File, read_only: bool) -> Self {
pub fn new_readonly(file: File, read_only: bool, size: usize) -> Self {
let mut prot = ProtFlags::PROT_READ;
if !read_only{
@ -59,9 +60,9 @@ impl AuxBuffer {
let flags = MapFlags::MAP_SHARED;
let null_addr = std::num::NonZeroUsize::new(0);
let size = std::num::NonZeroUsize::new(AUX_BUFFER_SIZE).unwrap();
let aux_buffer_alloc_size = std::num::NonZeroUsize::new(size).unwrap();
unsafe {
let ptr = mmap(null_addr, size, prot, flags, file.into_raw_fd(), 0).unwrap();
let ptr = mmap(null_addr, aux_buffer_alloc_size, prot, flags, file.into_raw_fd(), 0).unwrap();
let header = (ptr.add(HEADER_OFFSET) as *mut auxilary_buffer_header_s)
.as_mut()
.unwrap();
@ -83,12 +84,27 @@ impl AuxBuffer {
config,
result,
misc,
size,
};
}
}
pub fn new(file: File) -> Self {
return AuxBuffer::new_readonly(file, false);
pub fn new(file: File, size: usize) -> Self {
return AuxBuffer::new_readonly(file, false, size);
}
pub fn size(&self) -> usize {
return self.size;
}
/* This is a somewhat hacky way of returning a slice of the total misc area */
pub fn misc_slice(&self) -> &[u8] {
return unsafe { std::slice::from_raw_parts(self.misc as *const auxilary_buffer_misc_s as *const u8, self.size - MISC_OFFSET) };
}
/* same... */
pub fn misc_data_slice(&self) -> &[u8] {
return unsafe { std::slice::from_raw_parts((self.misc as *const auxilary_buffer_misc_s as *const u8).offset(std::mem::size_of::<u16>() as isize), self.size - MISC_OFFSET - std::mem::size_of::<u16>()) };
}
pub fn validate_header(&self) -> Result<(), String> {
@ -199,6 +215,7 @@ fn inspect_bytes(bs: &[u8]) -> String {
}
visible
}
impl auxilary_buffer_misc_s{
pub fn as_slice(&self) -> &[u8]{
assert!(self.len as usize <= self.data.len());
@ -209,6 +226,7 @@ impl auxilary_buffer_misc_s{
}
}
/* FIXME: will fail if the aux_buffer is > 4KB in size */
impl fmt::Debug for auxilary_buffer_misc_s {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("auxilary_buffer_misc_s")

View File

@ -14,6 +14,7 @@ pub struct QemuParams {
pub cow_primary_size: Option<u64>,
pub hprintf_fd: Option<i32>,
pub aux_buffer_size: usize,
}
impl QemuParams {
@ -96,6 +97,7 @@ impl QemuParams {
nyx_ops += &format!(",worker_id={}", qemu_id);
nyx_ops += &format!(",workdir={}", workdir);
nyx_ops += &format!(",sharedir={}", sharedir);
nyx_ops += &format!(",aux_buffer_size={}", fuzzer_config.runtime.aux_buffer_size());
let mut i = 0;
for filter in fuzzer_config.fuzz.ipt_filters{
@ -185,6 +187,7 @@ impl QemuParams {
write_protected_input_buffer: fuzzer_config.fuzz.write_protected_input_buffer,
cow_primary_size: fuzzer_config.fuzz.cow_primary_size,
hprintf_fd: fuzzer_config.runtime.hprintf_fd(),
aux_buffer_size: fuzzer_config.runtime.aux_buffer_size(),
}
}

View File

@ -212,7 +212,7 @@ impl QemuProcess {
.open(&params.qemu_aux_buffer_filename)
.expect("couldn't open aux buffer file");
AuxBuffer::new(aux_shm_f)
AuxBuffer::new(aux_shm_f, params.aux_buffer_size)
};
match aux_buffer.validate_header(){
@ -373,16 +373,15 @@ impl QemuProcess {
}
}
match self.aux.result.exec_result_code {
NYX_HPRINTF => {
let len = self.aux.misc.len;
QemuProcess::output_hprintf(&mut self.hprintf_file, &String::from_utf8_lossy(&self.aux.misc.data[0..len as usize]).yellow());
QemuProcess::output_hprintf(&mut self.hprintf_file, &String::from_utf8_lossy(&self.aux.misc_data_slice()[0..len as usize]).yellow());
continue;
},
NYX_ABORT => {
let len = self.aux.misc.len;
println!("[!] libnyx: agent abort() -> \"{}\"", String::from_utf8_lossy(&self.aux.misc.data[0..len as usize]).red());
println!("[!] libnyx: agent abort() -> \"{}\"", String::from_utf8_lossy(&self.aux.misc_data_slice()[0..len as usize]).red());
break;
},
NYX_SUCCESS | NYX_CRASH | NYX_INPUT_WRITE | NYX_TIMEOUT => {

View File

@ -141,6 +141,17 @@ pub extern "C" fn nyx_config_set_reuse_snapshot_path(config: * mut c_void, reuse
}
}
/* FFI function to set the aux_buffer size */
#[no_mangle]
pub extern "C" fn nyx_config_set_aux_buffer_size(config: * mut c_void, aux_buffer_size: u32) -> bool {
let cfg = __nyx_config_check_ptr(config);
assert_eq!(aux_buffer_size > 0, true);
unsafe{
return NyxConfig::set_aux_buffer_size(&mut *cfg, aux_buffer_size as usize);
}
}
#[no_mangle]
pub extern "C" fn nyx_new(config: * mut c_void, worker_id: u32) -> * mut NyxProcess {

View File

@ -228,6 +228,11 @@ impl NyxConfig {
self.config.runtime.set_worker_id(worker_id);
}
/* Sets the QEMU-Nyx aux buffer size (must be a multiple of 4KB; default value is 4KB). */
pub fn set_aux_buffer_size(&mut self, size: usize) -> bool{
return self.config.runtime.set_aux_buffer_size(size);
}
pub fn dict(&self) -> Vec<Vec<u8>> {
self.config.fuzz.dict.clone()
}
@ -258,6 +263,10 @@ impl NyxProcess {
pub fn aux_buffer_as_mut_ptr(&self) -> *mut u8 {
std::ptr::addr_of!(self.process.aux_buffer().header.magic) as *mut u8
}
pub fn aux_buffer_size(&self) -> usize {
self.process.aux_buffer().size()
}
pub fn input_buffer(&self) -> &[u8] {
self.process.payload
@ -317,7 +326,11 @@ impl NyxProcess {
}
pub fn aux_misc(&self) -> Vec<u8>{
self.process.aux_buffer().misc.as_slice().to_vec()
self.process.aux_buffer().misc_slice().to_vec()
}
pub fn aux_data_misc(&self) -> Vec<u8>{
self.process.aux_buffer().misc_data_slice().to_vec()
}
pub fn aux_tmp_snapshot_created(&self) -> bool {
@ -326,7 +339,7 @@ impl NyxProcess {
pub fn aux_string(&self) -> String {
let len = self.process.aux_buffer().misc.len;
String::from_utf8_lossy(&self.process.aux_buffer().misc.data[0..len as usize]).to_string()
String::from_utf8_lossy(&self.process.aux_buffer().misc_data_slice()[0..len as usize]).to_string()
}
pub fn exec(&mut self) -> NyxReturnValue {