From a09d3ae2e66cfe82884a227ea872e48dd2c2ad25 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Mon, 17 Jul 2023 20:34:01 +0200 Subject: [PATCH] add support to configure aux buffer size via args --- nyx/auxiliary_buffer.c | 35 ++++++++++++++++++++++++----------- nyx/auxiliary_buffer.h | 7 +++++-- nyx/hypercall/hypercall.c | 27 ++++++++++++--------------- nyx/interface.c | 16 +++++++++++++--- nyx/state/state.c | 26 +++++++++++++++++++------- nyx/state/state.h | 4 ++++ 6 files changed, 77 insertions(+), 38 deletions(-) diff --git a/nyx/auxiliary_buffer.c b/nyx/auxiliary_buffer.c index c5222e3919..9a594b87de 100644 --- a/nyx/auxiliary_buffer.c +++ b/nyx/auxiliary_buffer.c @@ -43,6 +43,16 @@ along with QEMU-PT. If not, see . #define VOLATILE_READ_16(dst, src) dst = *((volatile uint16_t *)(&src)) #define VOLATILE_READ_8(dst, src) dst = *((volatile uint8_t *)(&src)) +uint32_t misc_size(void) +{ + return GET_GLOBAL_STATE()->auxilary_buffer_size - (HEADER_SIZE + CAP_SIZE + CONFIG_SIZE + STATE_SIZE); +} + +uint32_t misc_data_size(void) +{ + return misc_size() - sizeof(uint16_t); +} + static void volatile_memset(void *dst, uint8_t ch, size_t count) { for (size_t i = 0; i < count; i++) { @@ -57,10 +67,10 @@ static void volatile_memcpy(void *dst, void *src, size_t size) } } -void init_auxiliary_buffer(auxilary_buffer_t *auxilary_buffer) +void init_auxiliary_buffer(auxilary_buffer_t *auxilary_buffer, uint32_t aux_buffer_size) { nyx_trace(); - volatile_memset((void *)auxilary_buffer, 0, sizeof(auxilary_buffer_t)); + volatile_memset((void *)auxilary_buffer, 0, aux_buffer_size); VOLATILE_WRITE_16(auxilary_buffer->header.version, QEMU_PT_VERSION); @@ -233,9 +243,10 @@ void set_hprintf_auxiliary_buffer(auxilary_buffer_t *auxilary_buffer, char *msg, uint32_t len) { - VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE - 2)); + uint32_t misc_data_size_value = misc_data_size(); + VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, misc_data_size_value)); volatile_memcpy((void *)&auxilary_buffer->misc.data, (void *)msg, - (size_t)MIN(len, MISC_SIZE - 2)); + (size_t)MIN(len, misc_data_size_value)); VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_hprintf); } @@ -243,9 +254,10 @@ void set_crash_reason_auxiliary_buffer(auxilary_buffer_t *auxilary_buffer, char *msg, uint32_t len) { - VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE - 2)); + uint32_t misc_data_size_value = misc_data_size(); + VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, misc_data_size_value)); volatile_memcpy((void *)&auxilary_buffer->misc.data, (void *)msg, - (size_t)MIN(len, MISC_SIZE - 2)); + (size_t)MIN(len, misc_data_size_value)); VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_crash); } @@ -253,9 +265,10 @@ void set_abort_reason_auxiliary_buffer(auxilary_buffer_t *auxilary_buffer, char *msg, uint32_t len) { - VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE - 2)); + uint32_t misc_data_size_value = misc_data_size(); + VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, misc_data_size_value)); volatile_memcpy((void *)&auxilary_buffer->misc.data, (void *)msg, - (size_t)MIN(len, MISC_SIZE - 2)); + (size_t)MIN(len, misc_data_size_value)); VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_aborted); } @@ -295,13 +308,13 @@ void set_success_auxiliary_result_buffer(auxilary_buffer_t *auxilary_buffer, void set_payload_buffer_write_reason_auxiliary_buffer( auxilary_buffer_t *auxilary_buffer, char *msg, uint32_t len) { - VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, MISC_SIZE - 2)); + uint32_t misc_data_size_value = misc_data_size(); + VOLATILE_WRITE_16(auxilary_buffer->misc.len, MIN(len, misc_data_size_value)); volatile_memcpy((void *)&auxilary_buffer->misc.data, (void *)msg, - (size_t)MIN(len, MISC_SIZE - 2)); + (size_t)MIN(len, misc_data_size_value)); VOLATILE_WRITE_8(auxilary_buffer->result.exec_result_code, rc_input_buffer_write); } - void set_tmp_snapshot_created(auxilary_buffer_t *auxilary_buffer, uint8_t value) { VOLATILE_WRITE_8(auxilary_buffer->result.tmp_snapshot_created, value); diff --git a/nyx/auxiliary_buffer.h b/nyx/auxiliary_buffer.h index 41355598f1..1e334cd3bf 100644 --- a/nyx/auxiliary_buffer.h +++ b/nyx/auxiliary_buffer.h @@ -24,7 +24,7 @@ along with QEMU-PT. If not, see . #include #include -#define AUX_BUFFER_SIZE 4096 +#define DEFAULT_AUX_BUFFER_SIZE 4096 #define AUX_MAGIC 0x54502d554d4551 @@ -158,7 +158,7 @@ typedef struct auxilary_buffer_s { sizeof(auxilary_buffer_result_t) +\ sizeof(auxilary_buffer_misc_t)) % 0xFFFF) -void init_auxiliary_buffer(auxilary_buffer_t *auxilary_buffer); +void init_auxiliary_buffer(auxilary_buffer_t *auxilary_buffer, uint32_t aux_buffer_size); void check_auxiliary_config_buffer(auxilary_buffer_t *auxilary_buffer, auxilary_buffer_config_t *shadow_config); @@ -203,3 +203,6 @@ void set_result_bb_coverage(auxilary_buffer_t *auxilary_buffer, uint32_t value); void set_payload_buffer_write_reason_auxiliary_buffer( auxilary_buffer_t *auxilary_buffer, char *msg, uint32_t len); + +uint32_t misc_size(void); +uint32_t misc_data_size(void); diff --git a/nyx/hypercall/hypercall.c b/nyx/hypercall/hypercall.c index 7fe74a8d1c..fa06af3201 100644 --- a/nyx/hypercall/hypercall.c +++ b/nyx/hypercall/hypercall.c @@ -52,11 +52,7 @@ along with QEMU-PT. If not, see . #include "nyx/state/state.h" #include "nyx/synchronization.h" -#define HPRINTF_SIZE 0x1000 /* FIXME: take from nyx.h */ - bool hypercall_enabled = false; -char hprintf_buffer[HPRINTF_SIZE]; - static bool init_state = true; void skip_init(void) @@ -536,17 +532,18 @@ static void handle_hypercall_kafl_panic_extended(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg) { - read_virtual_memory(hypercall_arg, (uint8_t *)hprintf_buffer, HPRINTF_SIZE, cpu); + uint32_t hprintf_size = misc_data_size(); + read_virtual_memory(hypercall_arg, (uint8_t *)GET_GLOBAL_STATE()->hprintf_tmp_buffer, hprintf_size, cpu); if (fast_reload_snapshot_exists(get_fast_reload_snapshot()) && GET_GLOBAL_STATE()->in_fuzzing_mode) { set_crash_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, - hprintf_buffer, strlen(hprintf_buffer)); + GET_GLOBAL_STATE()->hprintf_tmp_buffer, strnlen(GET_GLOBAL_STATE()->hprintf_tmp_buffer, hprintf_size)); synchronization_lock_crash_found(); } else { nyx_abort("Agent has crashed before initializing the fuzzing loop: %s", - hprintf_buffer); + GET_GLOBAL_STATE()->hprintf_tmp_buffer); } } @@ -587,12 +584,11 @@ static void handle_hypercall_kafl_printf(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg) { - read_virtual_memory(hypercall_arg, (uint8_t *)hprintf_buffer, HPRINTF_SIZE, cpu); - // hprintf_buffer[HPRINTF_SIZE] = 0; - // nyx_debug("%s: %s\n", __func__, hprintf_buffer); + uint32_t hprintf_size = misc_data_size(); + read_virtual_memory(hypercall_arg, (uint8_t *)GET_GLOBAL_STATE()->hprintf_tmp_buffer, hprintf_size, cpu); - set_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, hprintf_buffer, - strnlen(hprintf_buffer, HPRINTF_SIZE)); + set_hprintf_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, GET_GLOBAL_STATE()->hprintf_tmp_buffer, + strnlen(GET_GLOBAL_STATE()->hprintf_tmp_buffer, hprintf_size)); synchronization_lock(); } @@ -672,10 +668,11 @@ static void handle_hypercall_kafl_user_abort(struct kvm_run *run, CPUState *cpu, uint64_t hypercall_arg) { - read_virtual_memory(hypercall_arg, (uint8_t *)hprintf_buffer, HPRINTF_SIZE, cpu); + uint32_t hprintf_size = misc_data_size(); + read_virtual_memory(hypercall_arg, (uint8_t *)GET_GLOBAL_STATE()->hprintf_tmp_buffer, hprintf_size, cpu); set_abort_reason_auxiliary_buffer(GET_GLOBAL_STATE()->auxilary_buffer, - hprintf_buffer, - strnlen(hprintf_buffer, HPRINTF_SIZE)); + GET_GLOBAL_STATE()->hprintf_tmp_buffer, + strnlen(GET_GLOBAL_STATE()->hprintf_tmp_buffer, hprintf_size)); synchronization_lock(); } diff --git a/nyx/interface.c b/nyx/interface.c index 6973bcab50..e3b0bed8e4 100644 --- a/nyx/interface.c +++ b/nyx/interface.c @@ -54,9 +54,9 @@ along with QEMU-PT. If not, see . #include "nyx/state/state.h" #include "nyx/synchronization.h" #include "nyx/trace_dump.h" -#include "pt.h" - -#include "redqueen.h" +#include "nyx/pt.h" +#include "nyx/redqueen.h" +#include "nyx/auxiliary_buffer.h" #define CONVERT_UINT64(x) (uint64_t)(strtoull(x, NULL, 16)) @@ -94,6 +94,7 @@ typedef struct nyx_interface_state { bool redqueen; + uint32_t aux_buffer_size; } nyx_interface_state; static void nyx_interface_event(void *opaque, int event) @@ -399,6 +400,11 @@ static void nyx_realize(DeviceState *dev, Error **errp) s->bitmap_size = DEFAULT_NYX_BITMAP_SIZE; } + if (s->aux_buffer_size < 0x1000 || (s->aux_buffer_size & 0xFFF) != 0) { + fprintf(stderr, "Invalid aux buffer size (%d)...\n", s->aux_buffer_size); + exit(1); + } + set_aux_buffer_size(s->aux_buffer_size); if (s->worker_id == 0xFFFF) { nyx_abort("Invalid worker id...\n"); @@ -462,6 +468,10 @@ static Property nyx_interface_properties[] = { DEFAULT_NYX_BITMAP_SIZE), DEFINE_PROP_BOOL("dump_pt_trace", nyx_interface_state, dump_pt_trace, false), DEFINE_PROP_BOOL("edge_cb_trace", nyx_interface_state, edge_cb_trace, false), + DEFINE_PROP_UINT32("aux_buffer_size", + nyx_interface_state, + aux_buffer_size, + DEFAULT_AUX_BUFFER_SIZE), DEFINE_PROP_END_OF_LIST(), diff --git a/nyx/state/state.c b/nyx/state/state.c index 8820c61164..e02c47ca20 100644 --- a/nyx/state/state.c +++ b/nyx/state/state.c @@ -98,6 +98,7 @@ void state_init_global(void) global_state.shutdown_requested = false; global_state.cow_cache_full = false; + global_state.auxilary_buffer_size = DEFAULT_AUX_BUFFER_SIZE; global_state.auxilary_buffer = NULL; memset(&global_state.shadow_config, 0x0, sizeof(auxilary_buffer_config_t)); @@ -211,20 +212,20 @@ redqueen_t *get_redqueen_state(void) return global_state.redqueen_state; } -static void *alloc_auxiliary_buffer(const char *file) +static void *alloc_auxiliary_buffer(const char *file, uint32_t aux_buffer_size) { void *ptr; struct stat st; int fd = open(file, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); - assert(ftruncate(fd, AUX_BUFFER_SIZE) == 0); + assert(ftruncate(fd, aux_buffer_size) == 0); stat(file, &st); nyx_debug_p(INTERFACE_PREFIX, "new aux buffer file: (max size: %x) %lx\n", - AUX_BUFFER_SIZE, st.st_size); + aux_buffer_size, st.st_size); - assert(AUX_BUFFER_SIZE == st.st_size); - ptr = mmap(0, AUX_BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + assert(aux_buffer_size == st.st_size); + ptr = mmap(0, aux_buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { nyx_error("aux buffer allocation failed!\n"); return (void *)-1; @@ -235,8 +236,11 @@ static void *alloc_auxiliary_buffer(const char *file) void init_aux_buffer(const char *filename) { global_state.auxilary_buffer = - (auxilary_buffer_t *)alloc_auxiliary_buffer(filename); - init_auxiliary_buffer(global_state.auxilary_buffer); + (auxilary_buffer_t *)alloc_auxiliary_buffer(filename, global_state.auxilary_buffer_size); + init_auxiliary_buffer(global_state.auxilary_buffer, global_state.auxilary_buffer_size); + + global_state.hprintf_tmp_buffer = (char *)malloc(misc_size()); + memset(global_state.hprintf_tmp_buffer, 0, misc_size()); } void set_payload_buffer(uint64_t payload_buffer) @@ -261,3 +265,11 @@ void set_workdir_path(char *workdir) assert(workdir && !global_state.workdir_path); assert(asprintf(&global_state.workdir_path, "%s", workdir) != -1); } + +void set_aux_buffer_size(uint32_t aux_buffer_size) +{ + assert(aux_buffer_size >= DEFAULT_AUX_BUFFER_SIZE && (aux_buffer_size & 0xfff) == 0 ); + assert(global_state.auxilary_buffer == NULL); + + global_state.auxilary_buffer_size = aux_buffer_size; +} \ No newline at end of file diff --git a/nyx/state/state.h b/nyx/state/state.h index 049d55c056..50ddef39f1 100644 --- a/nyx/state/state.h +++ b/nyx/state/state.h @@ -142,6 +142,9 @@ typedef struct qemu_nyx_state_s { uint64_t mem_mapping_low; uint64_t mem_mapping_high; + uint32_t auxilary_buffer_size; + char* hprintf_tmp_buffer; + /* capabilites */ uint8_t cap_timeout_detection; uint8_t cap_only_reload_mode; @@ -187,3 +190,4 @@ void set_payload_buffer(uint64_t payload_buffer); void set_payload_pages(uint64_t *payload_pages, uint32_t pages); void set_workdir_path(char *workdir); +void set_aux_buffer_size(uint32_t aux_buffer_size);