Skip to content

Commit

Permalink
Introduce a method create a Vec in place, using a closure.
Browse files Browse the repository at this point in the history
  • Loading branch information
rmalmain committed Jan 13, 2025
1 parent 9c878d7 commit 3795f3f
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 51 deletions.
10 changes: 9 additions & 1 deletion fuzzers/full_system/qemu_linux_kernel/Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,15 @@ ${LINUX_BUILDER_DIR}/update.sh
[tasks.build]
dependencies = ["target_dir"]
command = "cargo"
args = ["build", "--profile", "${PROFILE}", "--target-dir", "${TARGET_DIR}", "--features", "${FEATURE}"]
args = [
"build",
"--profile",
"${PROFILE}",
"--target-dir",
"${TARGET_DIR}",
"--features",
"${FEATURE}",
]

[tasks.run]
dependencies = ["build"]
Expand Down
52 changes: 24 additions & 28 deletions fuzzers/full_system/qemu_linux_kernel/setup/harness.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ static int harness_uevent(const struct device *dev,
return 0;
}


#ifdef USE_NYX
/**
* Allocate page-aligned memory
Expand Down Expand Up @@ -143,7 +142,7 @@ static void *malloc_resident_pages(size_t num_pages) {

static void hrange_submit(unsigned id, uintptr_t start, uintptr_t end) {
volatile uint64_t range_arg[3] __attribute__((aligned(PAGE_SIZE)));
memset((void*) range_arg, 0, sizeof(range_arg));
memset((void *)range_arg, 0, sizeof(range_arg));

range_arg[0] = start;
range_arg[1] = end;
Expand All @@ -165,12 +164,11 @@ static int agent_init(int verbose) {

if (verbose) {
printk("GET_HOST_CONFIG\n");
printk("\thost magic: 0x%x, version: 0x%x\n",
host_config.host_magic, host_config.host_version);
printk("\tbitmap size: 0x%x, ijon: 0x%x\n",
host_config.bitmap_size, host_config.ijon_bitmap_size);
printk("\tpayload size: %u KB\n",
host_config.payload_buffer_size / 1024);
printk("\thost magic: 0x%x, version: 0x%x\n", host_config.host_magic,
host_config.host_version);
printk("\tbitmap size: 0x%x, ijon: 0x%x\n", host_config.bitmap_size,
host_config.ijon_bitmap_size);
printk("\tpayload size: %u KB\n", host_config.payload_buffer_size / 1024);
printk("\tworker id: %d\n", host_config.worker_id);
}

Expand Down Expand Up @@ -268,9 +266,7 @@ static int harness_open(struct inode *inode, struct file *file) {
#elif defined(USE_NYX)
hprintf("harness: Device open. x509_fn_addr: 0x%lx", x509_fn_addr);

if (!x509_fn_addr || !asn1_ber_decoder_addr) {
habort("Invalid ranges");
}
if (!x509_fn_addr || !asn1_ber_decoder_addr) { habort("Invalid ranges"); }

kAFL_payload *pbuf = malloc_resident_pages(PAYLOAD_MAX_SIZE / PAGE_SIZE);

Expand All @@ -286,37 +282,37 @@ static int harness_open(struct inode *inode, struct file *file) {
hprintf("payload addr: %p", &pbuf->data);

#else
#error No API specified.
#error No API specified.
#endif

// int ret;
// uintptr_t start_addr = 0, end_addr = 0;

// ret = lqemu_symfinder_widen_range("x509_cert_parse", &start_addr, &end_addr);
// if (ret) {
// ret = lqemu_symfinder_widen_range("x509_cert_parse", &start_addr,
// &end_addr); if (ret) {
// printk("error while handling range");
// return ret;
// }

while (true) {
#if defined(USE_LQEMU)
uint8_t *data = input_buf;
size_t size = libafl_qemu_start_virt(data, PAYLOAD_MAX_SIZE);
#elif defined(USE_NYX)
kAFL_hypercall(HYPERCALL_KAFL_NEXT_PAYLOAD, 0);
kAFL_hypercall(HYPERCALL_KAFL_ACQUIRE, 0);
#if defined(USE_LQEMU)
uint8_t *data = input_buf;
size_t size = libafl_qemu_start_virt(data, PAYLOAD_MAX_SIZE);
#elif defined(USE_NYX)
kAFL_hypercall(HYPERCALL_KAFL_NEXT_PAYLOAD, 0);
kAFL_hypercall(HYPERCALL_KAFL_ACQUIRE, 0);

size_t size = pbuf->size;
uint8_t *data = pbuf->data;
#endif
size_t size = pbuf->size;
uint8_t *data = pbuf->data;
#endif

struct x509_certificate *cert_ret = x509_cert_parse(data, size);

#if defined(USE_LQEMU)
libafl_qemu_end(LIBAFL_QEMU_END_OK);
#elif defined(USE_NYX)
kAFL_hypercall(HYPERCALL_KAFL_RELEASE, 0);
#endif
#if defined(USE_LQEMU)
libafl_qemu_end(LIBAFL_QEMU_END_OK);
#elif defined(USE_NYX)
kAFL_hypercall(HYPERCALL_KAFL_RELEASE, 0);
#endif
}

return 0;
Expand Down
24 changes: 14 additions & 10 deletions fuzzers/full_system/qemu_linux_kernel/src/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
use core::time::Duration;
use std::{env, path::PathBuf, process};

#[cfg(not(feature = "nyx"))]
use libafl::state::{HasExecutions, State};
use libafl::{
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
events::{launcher::Launcher, EventConfig},
executors::ShadowExecutor,
feedback_or, feedback_or_fast,
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::BytesInput,
inputs::{BytesInput, HasTargetBytes, Input, UsesInput},
monitors::MultiMonitor,
mutators::{havoc_mutations, scheduled::StdScheduledMutator, I2SRandReplaceBinonly},
observers::{CanTrack, HitcountsMapObserver, TimeObserver, VariableMapObserver},
Expand All @@ -19,7 +21,6 @@ use libafl::{
state::{HasCorpus, StdState},
Error,
};
use libafl::{inputs::{HasTargetBytes, Input, UsesInput}};
use libafl_bolts::{
core_affinity::Cores,
current_nanos,
Expand All @@ -28,18 +29,21 @@ use libafl_bolts::{
shmem::{ShMemProvider, StdShMemProvider},
tuples::tuple_list,
};
use libafl_qemu::{emu::Emulator, executor::QemuExecutor, modules::{cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule, CmpLogModule}, FastSnapshotManager, NopSnapshotManager, QemuInitError, StdEmulatorDriver};
use libafl_qemu::command::StdCommandManager;
use libafl_qemu::modules::EmulatorModuleTuple;
use libafl_qemu::modules::utils::filters::LINUX_PROCESS_ADDRESS_RANGE;
use libafl_targets::{edges_map_mut_ptr, EDGES_MAP_DEFAULT_SIZE, MAX_EDGES_FOUND};

#[cfg(feature = "nyx")]
use libafl_qemu::{command::nyx::NyxCommandManager, NyxEmulatorDriver};
use libafl_qemu::{
command::StdCommandManager,
emu::Emulator,
executor::QemuExecutor,
modules::{
cmplog::CmpLogObserver, edges::StdEdgeCoverageClassicModule,
utils::filters::LINUX_PROCESS_ADDRESS_RANGE, CmpLogModule, EmulatorModuleTuple,
},
FastSnapshotManager, NopSnapshotManager, QemuInitError, StdEmulatorDriver,
};
#[cfg(not(feature = "nyx"))]
use libafl_qemu::{command::StdCommandManager, StdEmulatorDriver};
#[cfg(not(feature = "nyx"))]
use libafl::state::{HasExecutions, State};
use libafl_targets::{edges_map_mut_ptr, EDGES_MAP_DEFAULT_SIZE, MAX_EDGES_FOUND};

#[cfg(feature = "nyx")]
fn get_emulator<ET, S>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ int main() {
hprintf("payload size addr: %p", &pbuf->size);
hprintf("payload addr: %p", &pbuf->data);

while(true) {
while (true) {
kAFL_hypercall(HYPERCALL_KAFL_NEXT_PAYLOAD, 0);
kAFL_hypercall(HYPERCALL_KAFL_ACQUIRE, 0);

Expand Down
17 changes: 16 additions & 1 deletion fuzzers/full_system/qemu_linux_process/src/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@ use std::{env, path::PathBuf, process};

#[cfg(not(feature = "nyx"))]
use libafl::state::{HasExecutions, State};
use libafl::{corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig}, executors::{ExitKind, ShadowExecutor}, feedback_and_fast, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes, UsesInput}, monitors::MultiMonitor, mutators::{havoc_mutations, I2SRandReplaceBinonly, StdScheduledMutator}, observers::{CanTrack, HitcountsMapObserver, TimeObserver, VariableMapObserver}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::{ShadowTracingStage, StdMutationalStage}, state::{HasCorpus, StdState}, Error};
use libafl::{
corpus::{Corpus, InMemoryOnDiskCorpus, OnDiskCorpus},
events::{launcher::Launcher, EventConfig},
executors::{ExitKind, ShadowExecutor},
feedback_and_fast, feedback_or, feedback_or_fast,
feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes, UsesInput},
monitors::MultiMonitor,
mutators::{havoc_mutations, I2SRandReplaceBinonly, StdScheduledMutator},
observers::{CanTrack, HitcountsMapObserver, TimeObserver, VariableMapObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::{ShadowTracingStage, StdMutationalStage},
state::{HasCorpus, StdState},
Error,
};
use libafl_bolts::{
core_affinity::Cores,
current_nanos,
Expand Down
21 changes: 21 additions & 0 deletions libafl_bolts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,27 @@ pub mod pybind {
}
}

/// Create a [`Vec`] of the given type with nb_elts elements, initialized in place.
/// The closure must initialize [`Vec`] (of size nb_elts * sizeo_of::<T>()).
///
/// # Safety
///
/// The input closure should fully initialize the new [`Vec`], not leaving any uninitialized bytes.
// TODO: Use MaybeUninit API at some point.
pub unsafe fn vec_init<E, F, T>(nb_elts: usize, init_fn: F) -> Result<Vec<T>, E>
where
F: FnOnce(&mut Vec<T>) -> Result<(), E>,
{
let mut val_buf: Vec<T> = Vec::with_capacity(nb_elts);
unsafe {
val_buf.set_len(nb_elts);
}

init_fn(&mut val_buf)?;

Ok(val_buf)
}

#[cfg(test)]
mod tests {

Expand Down
8 changes: 4 additions & 4 deletions libafl_qemu/src/command/nyx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::{
ptr,
slice::from_raw_parts,
};

use enum_map::EnumMap;
use libafl::{
executors::ExitKind,
Expand All @@ -27,9 +28,9 @@ use crate::{
command::{
parser::nyx::{
AcquireCommandParser, GetHostConfigCommandParser, GetPayloadCommandParser,
NextPayloadCommandParser, PrintfCommandParser, RangeSubmitCommandParser,
ReleaseCommandParser, SetAgentConfigCommandParser, SubmitCR3CommandParser,
SubmitPanicCommandParser, UserAbortCommandParser,
NextPayloadCommandParser, PanicCommandParser, PrintfCommandParser,
RangeSubmitCommandParser, ReleaseCommandParser, SetAgentConfigCommandParser,
SubmitCR3CommandParser, SubmitPanicCommandParser, UserAbortCommandParser,
},
CommandError, CommandManager, IsCommand, NativeCommandParser,
},
Expand All @@ -39,7 +40,6 @@ use crate::{
Emulator, EmulatorDriverError, EmulatorDriverResult, GuestReg, InputLocation,
IsSnapshotManager, NyxEmulatorDriver, Qemu, QemuMemoryChunk, Regs,
};
use crate::command::parser::nyx::PanicCommandParser;

pub(crate) mod bindings {
#![allow(non_upper_case_globals)]
Expand Down
8 changes: 2 additions & 6 deletions libafl_qemu/src/qemu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub use systemmode::*;

mod hooks;
pub use hooks::*;
use libafl_bolts::vec_init;

static mut QEMU_IS_INITIALIZED: bool = false;

Expand Down Expand Up @@ -742,12 +743,7 @@ impl Qemu {
pub unsafe fn read_mem_val<T>(&self, addr: GuestAddr) -> Result<T, QemuRWError> {
// let mut val_buf: [u8; size_of::<T>()] = [0; size_of::<T>()];

let mut val_buf: Vec<u8> = Vec::with_capacity(size_of::<T>());
unsafe {
val_buf.set_len(size_of::<T>());
}

self.read_mem(addr, &mut val_buf)?;
let val_buf: Vec<u8> = vec_init(size_of::<T>(), |buf| self.read_mem(addr, buf))?;

Ok(ptr::read(val_buf.as_ptr() as *const T))
}
Expand Down

0 comments on commit 3795f3f

Please sign in to comment.