Merge pull request #20 from schumilo/qemu-nyx-4.2.0

various bug fixes from dev branch
This commit is contained in:
Sergej Schumilo 2022-05-11 18:03:52 +02:00 committed by GitHub
commit f66671d93b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 95 additions and 144 deletions

View File

@ -2451,9 +2451,7 @@ int kvm_cpu_exec(CPUState *cpu)
smp_rmb(); smp_rmb();
#ifdef QEMU_NYX #ifdef QEMU_NYX
if(arm_sigprof_timer(&GET_GLOBAL_STATE()->timeout_detector)){ arm_sigprof_timer(&GET_GLOBAL_STATE()->timeout_detector);
assert(false);
}
#endif #endif
run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0); run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);

1
exec.c
View File

@ -1368,7 +1368,6 @@ bool cpu_physical_memory_test_dirty(ram_addr_t start,
unsigned long end, page; unsigned long end, page;
bool dirty = false; bool dirty = false;
RAMBlock *ramblock; RAMBlock *ramblock;
uint64_t mr_offset, mr_size;
if (length == 0) { if (length == 0) {
return false; return false;

View File

@ -187,7 +187,7 @@ void set_pt_overflow_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer)
VOLATILE_WRITE_8(auxilary_buffer->result.pt_overflow, 1); VOLATILE_WRITE_8(auxilary_buffer->result.pt_overflow, 1);
} }
void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec, uint32_t num_dirty_pages){ void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint32_t sec, uint32_t usec, uint32_t num_dirty_pages){
VOLATILE_WRITE_8(auxilary_buffer->result.exec_done, 1); VOLATILE_WRITE_8(auxilary_buffer->result.exec_done, 1);
VOLATILE_WRITE_32(auxilary_buffer->result.runtime_sec, sec); VOLATILE_WRITE_32(auxilary_buffer->result.runtime_sec, sec);

View File

@ -155,7 +155,7 @@ void set_asan_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_timeout_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer); void set_timeout_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_reload_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer); void set_reload_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_pt_overflow_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer); void set_pt_overflow_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer);
void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t sec, uint32_t usec, uint32_t num_dirty_pages); void set_exec_done_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint32_t sec, uint32_t usec, uint32_t num_dirty_pages);
void set_state_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t state); void set_state_auxiliary_result_buffer(auxilary_buffer_t* auxilary_buffer, uint8_t state);
void set_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len); void set_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len);

View File

@ -349,8 +349,8 @@ void handle_hypercall_kafl_release(struct kvm_run *run, CPUState *cpu, uint64_t
if (init_state){ if (init_state){
init_state = false; init_state = false;
} else { } else {
//printf(CORE_PREFIX, "Got STARVED notification (num=%llu)\n", run->hypercall.args[0]); //printf(CORE_PREFIX, "Got STARVED notification (num=%llu)\n", hypercall_arg);
if (run->hypercall.args[0] > 0) { if (hypercall_arg > 0) {
GET_GLOBAL_STATE()->starved = 1; GET_GLOBAL_STATE()->starved = 1;
} else { } else {
GET_GLOBAL_STATE()->starved = 0; GET_GLOBAL_STATE()->starved = 0;
@ -561,7 +561,7 @@ static void handle_hypercall_kafl_create_tmp_snapshot(struct kvm_run *run, CPUSt
//handle_hypercall_kafl_acquire(run, cpu); //handle_hypercall_kafl_acquire(run, cpu);
//fprintf(stderr, "%s: CREATE DONE at %lx\n", __func__, get_rip(cpu)); //fprintf(stderr, "%s: CREATE DONE at %lx\n", __func__, get_rip(cpu));
handle_hypercall_kafl_release(run, cpu, (uint64_t)run->hypercall.args[0]); handle_hypercall_kafl_release(run, cpu, hypercall_arg);
} }
else{ else{
//fprintf(stderr, "%s: LOAD Continue at %lx\n", __func__, get_rip(cpu)); //fprintf(stderr, "%s: LOAD Continue at %lx\n", __func__, get_rip(cpu));

View File

@ -348,7 +348,6 @@ static void add_get(state_reallocation_t* self, void* fptr, void* opaque, size_t
qemu_get_buffer(f, (uint8_t*)data, size); qemu_get_buffer(f, (uint8_t*)data, size);
} }
else if(!strcmp(name, "virtio")){ else if(!strcmp(name, "virtio")){
fprintf(stderr, "WARNING: ATTEMPTING FAST GET for %s\n", name);
qemu_file_skip(f, size * -1); qemu_file_skip(f, size * -1);
handler = fast_virtio_device_get; handler = fast_virtio_device_get;
data = malloc(sizeof(uint8_t)*size); data = malloc(sizeof(uint8_t)*size);

View File

@ -26,134 +26,99 @@ volatile bool synchronization_reload_pending = false;
volatile bool synchronization_kvm_loop_waiting = false; volatile bool synchronization_kvm_loop_waiting = false;
/* new SIGALRM based timeout detection */ /* SIGALRM based timeout detection */
//#define DEBUG_TIMEOUT_DETECTOR //#define DEBUG_TIMEOUT_DETECTOR
void init_timeout_detector(timeout_detector_t* timer){
timer->kvm_tid = 0;
timer->detection_enabled = false;
void init_timeout_detector(timeout_detector_t* timeout_detector){ timer->config.tv_sec = 0;
timeout_detector->kvm_tid = 0; timer->config.tv_usec = 0;
timeout_detector->reload_pending = false;
timeout_detector->detection_enabled = false;
timeout_detector->timeout_sec = 0; timer->alarm.it_interval.tv_sec = 0;
timeout_detector->timeout_usec = 0; /* default: disabled */ timer->alarm.it_interval.tv_usec = 0;
timer->alarm.it_value.tv_sec = 0;
timeout_detector->arm_timeout.it_interval.tv_sec = 0; timer->alarm.it_value.tv_usec = 0;
timeout_detector->arm_timeout.it_interval.tv_usec = 0;
timeout_detector->arm_timeout.it_value.tv_sec = 0;
timeout_detector->arm_timeout.it_value.tv_usec = 0;
timeout_detector->disarm_timeout.it_interval.tv_sec = 0;
timeout_detector->disarm_timeout.it_interval.tv_usec = 0;
timeout_detector->arm_timeout.it_value.tv_sec = timeout_detector->timeout_sec;
timeout_detector->arm_timeout.it_value.tv_usec = timeout_detector->timeout_usec;
} }
static void sigalarm_handler(int signum) { static void sigalarm_handler(int signum) {
/* ensure that SIGALARM is ALWAYS handled by kvm thread */ /* ensure that SIGALARM is ALWAYS handled by kvm thread */
assert(GET_GLOBAL_STATE()->timeout_detector.kvm_tid == syscall(SYS_gettid)); assert(GET_GLOBAL_STATE()->timeout_detector.kvm_tid == syscall(SYS_gettid));
//GET_GLOBAL_STATE()->timeout_detector.reload_pending = true;
#ifdef DEBUG_TIMEOUT_DETECTOR #ifdef DEBUG_TIMEOUT_DETECTOR
fprintf(stderr, "Handled! %d %ld\n", signum, syscall(SYS_gettid));
#endif #endif
//fprintf(stderr, "Handled! %d %ld\n", signum, syscall(SYS_gettid));
} }
void install_timeout_detector(timeout_detector_t* timeout_detector){ void install_timeout_detector(timeout_detector_t* timer){
timeout_detector->kvm_tid = syscall(SYS_gettid); timer->kvm_tid = syscall(SYS_gettid);
if(signal(SIGALRM, sigalarm_handler) == SIG_ERR) { if (signal(SIGALRM, sigalarm_handler) == SIG_ERR) {
fprintf(stderr, "%s failed!\n", __func__); fprintf(stderr, "%s failed!\n", __func__);
assert(false); assert(false);
} }
//fprintf(stderr, "SIGALRM HANDLER INSTALLED! %ld\n", syscall(SYS_gettid)); #ifdef DEBUG_TIMEOUT_DETECTOR
fprintf(stderr, "SIGALRM HANDLER INSTALLED! tid=%ld\n", syscall(SYS_gettid));
#endif
} }
void reset_timeout_detector(timeout_detector_t* timeout_detector){ void reset_timeout_detector(timeout_detector_t* timer){
#ifdef DEBUG_TIMEOUT_DETECTOR #ifdef DEBUG_TIMEOUT_DETECTOR
fprintf(stderr, "%s!\n", __func__); fprintf(stderr, "%s!\n", __func__);
#endif #endif
timeout_detector->reload_pending = false;
if(timeout_detector->timeout_sec || timeout_detector->timeout_usec){ if (timer->config.tv_sec || timer->config.tv_usec) {
timeout_detector->arm_timeout.it_value.tv_sec = timeout_detector->timeout_sec; timer->alarm.it_value.tv_sec = timer->config.tv_sec;
timeout_detector->arm_timeout.it_value.tv_usec = timeout_detector->timeout_usec; timer->alarm.it_value.tv_usec = timer->config.tv_usec;
timeout_detector->detection_enabled = true; timer->detection_enabled = true;
} } else {
else{ timer->detection_enabled = false;
timeout_detector->detection_enabled = false;
} }
} }
void enable_timeout_detector(timeout_detector_t* timeout_detector){ void update_itimer(timeout_detector_t* timer, uint8_t sec, uint32_t usec)
timeout_detector->detection_enabled = true; {
} #ifdef DEBUG_TIMEOUT_DETECTOR
/*
static void disable_timeout_detector(timeout_detector_t* timeout_detector){
timeout_detector->detection_enabled = false;
struct itimerval tmp;
timeout_detector->disarm_timeout.it_interval.tv_sec = 0;
timeout_detector->disarm_timeout.it_interval.tv_usec = 0;
assert(setitimer(ITIMER_REAL, &timeout_detector->disarm_timeout, &tmp) == 0);
}
*/
void update_itimer(timeout_detector_t* timeout_detector, uint8_t sec, uint32_t usec){
//fprintf(stderr, "%s: %x %x\n", __func__, sec, usec); //fprintf(stderr, "%s: %x %x\n", __func__, sec, usec);
if(sec || usec){ #endif
timeout_detector->timeout_sec = (time_t) sec;
timeout_detector->timeout_usec = (suseconds_t) usec; if (sec || usec) {
timeout_detector->detection_enabled = true; timer->config.tv_sec = (time_t)sec;
} timer->config.tv_usec = (suseconds_t)usec;
else{ timer->detection_enabled = true;
timeout_detector->detection_enabled = false; } else {
timer->detection_enabled = false;
} }
} }
bool arm_sigprof_timer(timeout_detector_t* timeout_detector){ void arm_sigprof_timer(timeout_detector_t* timer){
//return false; #ifdef DEBUG_TIMEOUT_DETECTOR
if(timeout_detector->detection_enabled){ fprintf(stderr, "%s (%ld %ld)\n", __func__, timer->alarm.it_value.tv_sec, timer->alarm.it_value.tv_usec);
if(timeout_detector->reload_pending || (!timeout_detector->arm_timeout.it_value.tv_sec && !timeout_detector->arm_timeout.it_value.tv_usec)){ #endif
//assert(false);
fprintf(stderr, "TIMER EXPIRED 1! %d %ld %ld\n", timeout_detector->reload_pending, timeout_detector->arm_timeout.it_value.tv_sec, timeout_detector->arm_timeout.it_value.tv_usec); if (timer->detection_enabled) {
reset_timeout_detector(timeout_detector); if (timer->alarm.it_value.tv_usec == 0 && timer->alarm.it_value.tv_sec == 0) {
/* TODO: check if this function still works as expected even if we don't return at this point */ fprintf(stderr, "Attempting to re-arm an expired timer! => reset(%ld.%ld)\n",
timer->config.tv_sec, timer->config.tv_usec);
reset_timeout_detector(timer);
//return true; //return true;
} }
#ifdef DEBUG_TIMEOUT_DETECTOR assert(setitimer(ITIMER_REAL, &timer->alarm, NULL) == 0);
fprintf(stderr, "%s (%ld %ld)\n", __func__, timeout_detector->arm_timeout.it_value.tv_sec, timeout_detector->arm_timeout.it_value.tv_usec);
#endif
timeout_detector->arm_timeout.it_interval.tv_sec = 0;
timeout_detector->arm_timeout.it_interval.tv_usec = 0;
assert(setitimer(ITIMER_REAL, &timeout_detector->arm_timeout, 0) == 0);
} }
return false;
} }
bool disarm_sigprof_timer(timeout_detector_t* timeout_detector){ bool disarm_sigprof_timer(timeout_detector_t* timer){
//return false;
struct itimerval tmp;
if(timeout_detector->detection_enabled){
timeout_detector->disarm_timeout.it_interval.tv_sec = 0;
timeout_detector->disarm_timeout.it_interval.tv_usec = 0;
assert(setitimer(ITIMER_REAL, &timeout_detector->disarm_timeout, &tmp) == 0);
timeout_detector->arm_timeout.it_value.tv_sec = tmp.it_value.tv_sec;
timeout_detector->arm_timeout.it_value.tv_usec = tmp.it_value.tv_usec;
#ifdef DEBUG_TIMEOUT_DETECTOR #ifdef DEBUG_TIMEOUT_DETECTOR
fprintf(stderr, "%s (%ld %ld)\n", __func__, timeout_detector->arm_timeout.it_value.tv_sec, timeout_detector->arm_timeout.it_value.tv_usec); fprintf(stderr, "%s (%ld %ld)\n", __func__, timer->alarm.it_value.tv_sec, timer->alarm.it_value.tv_usec);
#endif #endif
if(timeout_detector->reload_pending || (!timeout_detector->arm_timeout.it_value.tv_sec && !timeout_detector->arm_timeout.it_value.tv_usec)){
//fprintf(stderr, "TIMER EXPIRED 2! %d %d %d\n", timeout_detector->reload_pending, timeout_detector->arm_timeout.it_value.tv_sec, timeout_detector->arm_timeout.it_value.tv_usec);
reset_timeout_detector(timeout_detector); if (timer->detection_enabled) {
//timeout_detector->detection_enabled = false; struct itimerval disable = {0};
assert(setitimer(ITIMER_REAL, &disable, &timer->alarm) == 0);
assert(timer->alarm.it_interval.tv_usec == 0);
if (timer->alarm.it_value.tv_usec == 0 && timer->alarm.it_value.tv_sec == 0) {
reset_timeout_detector(timer);
return true; return true;
} }
} }
@ -245,24 +210,27 @@ void synchronization_lock_hprintf(void){
} }
void synchronization_lock(void){ void synchronization_lock(void){
timeout_detector_t timer = GET_GLOBAL_STATE()->timeout_detector;
pthread_mutex_lock(&synchronization_lock_mutex); pthread_mutex_lock(&synchronization_lock_mutex);
run_counter++; run_counter++;
if(qemu_get_cpu(0)->intel_pt_run_trashed){ if(qemu_get_cpu(0)->intel_pt_run_trashed){
set_pt_overflow_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer); set_pt_overflow_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
} }
set_exec_done_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer,
GET_GLOBAL_STATE()->timeout_detector.timeout_sec - GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_sec, long runtime_sec = timer.config.tv_sec - timer.alarm.it_value.tv_sec;
GET_GLOBAL_STATE()->timeout_detector.timeout_usec - (uint32_t)GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_usec, long runtime_usec = timer.config.tv_usec - timer.alarm.it_value.tv_usec;
GET_GLOBAL_STATE()->num_dirty_pages);
/* if (runtime_usec < 0) {
if(last_timeout){ if (runtime_sec < 1) {
reset_timeout_detector_timeout(&(GET_GLOBAL_STATE()->timeout_detector)); fprintf(stderr, "Error: negative payload runtime?!\n");
} }
else{ runtime_sec -= 1;
*/ runtime_usec = timer.config.tv_usec - timer.alarm.it_value.tv_usec + 1000000;
reset_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector)); }
//} set_exec_done_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer,
runtime_sec, runtime_usec,
GET_GLOBAL_STATE()->num_dirty_pages);
if(synchronization_check_page_not_found()){ if(synchronization_check_page_not_found()){
set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 0); set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 0);
@ -373,7 +341,6 @@ void synchronization_lock_timeout_found(void){
handle_tmp_snapshot_state(); handle_tmp_snapshot_state();
set_timeout_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer); set_timeout_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer);
reset_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector));
perform_reload(); perform_reload();
@ -469,6 +436,5 @@ void synchronization_enter_fuzzing_loop(CPUState *cpu){
in_fuzzing_loop = true; in_fuzzing_loop = true;
reset_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector)); reset_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector));
//enable_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector));
} }

View File

@ -3,27 +3,19 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include <linux/kvm.h> #include <linux/kvm.h>
typedef struct timeout_detector_s{ typedef struct timeout_detector_s {
int kvm_tid; int kvm_tid;
volatile bool reload_pending;
volatile bool detection_enabled; volatile bool detection_enabled;
time_t timeout_sec; struct timeval config;
suseconds_t timeout_usec; struct itimerval alarm;
struct itimerval arm_timeout;
struct itimerval disarm_timeout;
struct timespec start_time;
struct timespec end_time;
} timeout_detector_t; } timeout_detector_t;
void init_timeout_detector(timeout_detector_t* timeout_detector); void init_timeout_detector(timeout_detector_t* timeout_detector);
void install_timeout_detector(timeout_detector_t* timeout_detector); void install_timeout_detector(timeout_detector_t* timeout_detector);
void reset_timeout_detector(timeout_detector_t* timeout_detector); void reset_timeout_detector(timeout_detector_t* timeout_detector);
bool arm_sigprof_timer(timeout_detector_t* timeout_detector); void arm_sigprof_timer(timeout_detector_t* timeout_detector);
bool disarm_sigprof_timer(timeout_detector_t* timeout_detector); bool disarm_sigprof_timer(timeout_detector_t* timeout_detector);
void update_itimer(timeout_detector_t* timeout_detector, uint8_t sec, uint32_t usec); void update_itimer(timeout_detector_t* timeout_detector, uint8_t sec, uint32_t usec);
void block_signals(void); void block_signals(void);
@ -44,6 +36,3 @@ void synchronization_cow_full_detected(void);
void synchronization_disable_pt(CPUState *cpu); void synchronization_disable_pt(CPUState *cpu);
void synchronization_enter_fuzzing_loop(CPUState *cpu); void synchronization_enter_fuzzing_loop(CPUState *cpu);
void synchronization_payload_buffer_write_detected(void); void synchronization_payload_buffer_write_detected(void);
void enable_timeout_detector(timeout_detector_t* timeout_detector);
void reset_timeout_detector_timeout(timeout_detector_t* timeout_detector);

2
vl.c
View File

@ -2928,7 +2928,7 @@ int main(int argc, char **argv, char **envp)
#ifdef QEMU_NYX #ifdef QEMU_NYX
bool fast_vm_reload = false; bool fast_vm_reload = false;
state_init_global(); state_init_global();
char *fast_vm_reload_opt_arg = NULL; const char *fast_vm_reload_opt_arg = NULL;
#endif #endif
int i; int i;