Skip to content

Commit

Permalink
Merge remote-tracking branch 'nyx/qemu-nyx-4.2.0' into kafl_stable
Browse files Browse the repository at this point in the history
  • Loading branch information
Wenzel committed Aug 3, 2023
2 parents 61cb6cc + a09d3ae commit d59d5d2
Show file tree
Hide file tree
Showing 10 changed files with 224 additions and 44 deletions.
48 changes: 32 additions & 16 deletions nyx/auxiliary_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#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++) {
Expand All @@ -57,18 +67,14 @@ 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);

uint16_t hash =
(sizeof(auxilary_buffer_header_t) + sizeof(auxilary_buffer_cap_t) +
sizeof(auxilary_buffer_config_t) + sizeof(auxilary_buffer_result_t) +
sizeof(auxilary_buffer_misc_t)) %
0xFFFF;
uint16_t hash = AUX_BUFFER_HASH;

VOLATILE_WRITE_16(auxilary_buffer->header.hash, hash);

Expand All @@ -83,6 +89,13 @@ void check_auxiliary_config_buffer(auxilary_buffer_t *auxilary_buffer,
if (changed) {
uint8_t aux_byte;

/* sanitiy check to verify that the buffer is not corrupted */
uint16_t _hash = AUX_BUFFER_HASH;
uint64_t _magic = AUX_MAGIC;

assert(memcmp(&auxilary_buffer->header.magic, &_magic, sizeof(auxilary_buffer->header.magic)) == 0);
assert(memcmp(&auxilary_buffer->header.hash, &_hash, sizeof(auxilary_buffer->header.hash)) == 0);

VOLATILE_READ_8(aux_byte, auxilary_buffer->configuration.redqueen_mode);
if (aux_byte) {
/* enable redqueen mode */
Expand Down Expand Up @@ -230,29 +243,32 @@ 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);
}

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);
}

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);
}

Expand Down Expand Up @@ -292,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);
Expand Down
13 changes: 11 additions & 2 deletions nyx/auxiliary_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#include <stdbool.h>
#include <stdint.h>

#define AUX_BUFFER_SIZE 4096
#define DEFAULT_AUX_BUFFER_SIZE 4096

#define AUX_MAGIC 0x54502d554d4551

Expand Down Expand Up @@ -152,7 +152,13 @@ typedef struct auxilary_buffer_s {

} __attribute__((packed)) auxilary_buffer_t;

void init_auxiliary_buffer(auxilary_buffer_t *auxilary_buffer);
#define AUX_BUFFER_HASH (( sizeof(auxilary_buffer_header_t) +\
sizeof(auxilary_buffer_cap_t) +\
sizeof(auxilary_buffer_config_t) +\
sizeof(auxilary_buffer_result_t) +\
sizeof(auxilary_buffer_misc_t)) % 0xFFFF)

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);

Expand Down Expand Up @@ -197,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);
13 changes: 13 additions & 0 deletions nyx/fast_vm_reload_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "nyx/fast_vm_reload.h"
#include "nyx/kvm_nested.h"
#include "nyx/state/state.h"
#include "nyx/state/snapshot_state.h"

extern int save_snapshot(const char *name, Error **errp);
extern int load_snapshot(const char *name, Error **errp);
Expand Down Expand Up @@ -131,11 +132,23 @@ static inline void create_root_snapshot(void)
fast_reload_create_in_memory(get_fast_reload_snapshot());
fast_reload_serialize_to_file(get_fast_reload_snapshot(),
GET_GLOBAL_STATE()->fast_reload_path, false);

serialize_root_snapshot_meta_data(GET_GLOBAL_STATE()->fast_reload_path);
}
} else {
nyx_debug("===> GET_GLOBAL_STATE()->fast_reload_enabled: FALSE\n");
/* so we haven't set a path for our snapshot files - just store everything in memory */
fast_reload_create_in_memory(get_fast_reload_snapshot());

/* Even if we don't serialize the snapshot we still want to have the
* option to export the meta data of the root snapshot as yaml file.
* This might be useful for the fuzzing frontend in charge; thus it
* is also up to the frontend to set a path for the snapshot directory.
* If the path is not set, we just skip this step.
*/
if (GET_GLOBAL_STATE()->fast_reload_path != NULL) {
serialize_root_snapshot_meta_data(GET_GLOBAL_STATE()->fast_reload_path);
}
}
}

Expand Down
27 changes: 12 additions & 15 deletions nyx/hypercall/hypercall.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#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)
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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();
}

Expand Down
16 changes: 13 additions & 3 deletions nyx/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ along with QEMU-PT. If not, see <http://www.gnu.org/licenses/>.
#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))

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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(),
Expand Down
Loading

0 comments on commit d59d5d2

Please sign in to comment.