diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 0254410cda..0f64d90085 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2451,9 +2451,7 @@ int kvm_cpu_exec(CPUState *cpu) smp_rmb(); #ifdef QEMU_NYX - if(arm_sigprof_timer(&GET_GLOBAL_STATE()->timeout_detector)){ - assert(false); - } + arm_sigprof_timer(&GET_GLOBAL_STATE()->timeout_detector); #endif run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0); diff --git a/exec.c b/exec.c index 7548497217..8525f8cf63 100644 --- a/exec.c +++ b/exec.c @@ -1368,7 +1368,6 @@ bool cpu_physical_memory_test_dirty(ram_addr_t start, unsigned long end, page; bool dirty = false; RAMBlock *ramblock; - uint64_t mr_offset, mr_size; if (length == 0) { return false; diff --git a/nyx/auxiliary_buffer.c b/nyx/auxiliary_buffer.c index 7ba076de3e..afbe400531 100644 --- a/nyx/auxiliary_buffer.c +++ b/nyx/auxiliary_buffer.c @@ -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); } -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_32(auxilary_buffer->result.runtime_sec, sec); diff --git a/nyx/auxiliary_buffer.h b/nyx/auxiliary_buffer.h index 0ac87ce8c2..90dda2f31c 100644 --- a/nyx/auxiliary_buffer.h +++ b/nyx/auxiliary_buffer.h @@ -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_reload_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_hprintf_auxiliary_buffer(auxilary_buffer_t* auxilary_buffer, char* msg, uint32_t len); diff --git a/nyx/hypercall/hypercall.c b/nyx/hypercall/hypercall.c index 6267c8a953..dd5598c73e 100644 --- a/nyx/hypercall/hypercall.c +++ b/nyx/hypercall/hypercall.c @@ -349,8 +349,8 @@ void handle_hypercall_kafl_release(struct kvm_run *run, CPUState *cpu, uint64_t if (init_state){ init_state = false; } else { - //printf(CORE_PREFIX, "Got STARVED notification (num=%llu)\n", run->hypercall.args[0]); - if (run->hypercall.args[0] > 0) { + //printf(CORE_PREFIX, "Got STARVED notification (num=%llu)\n", hypercall_arg); + if (hypercall_arg > 0) { GET_GLOBAL_STATE()->starved = 1; } else { 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); //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{ //fprintf(stderr, "%s: LOAD Continue at %lx\n", __func__, get_rip(cpu)); diff --git a/nyx/snapshot/devices/state_reallocation.c b/nyx/snapshot/devices/state_reallocation.c index c9edfa7433..120dccd619 100644 --- a/nyx/snapshot/devices/state_reallocation.c +++ b/nyx/snapshot/devices/state_reallocation.c @@ -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); } else if(!strcmp(name, "virtio")){ - fprintf(stderr, "WARNING: ATTEMPTING FAST GET for %s\n", name); qemu_file_skip(f, size * -1); handler = fast_virtio_device_get; data = malloc(sizeof(uint8_t)*size); diff --git a/nyx/synchronization.c b/nyx/synchronization.c index c502f89138..676bb83c82 100644 --- a/nyx/synchronization.c +++ b/nyx/synchronization.c @@ -26,138 +26,103 @@ volatile bool synchronization_reload_pending = false; volatile bool synchronization_kvm_loop_waiting = false; -/* new SIGALRM based timeout detection */ - +/* SIGALRM based timeout detection */ //#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){ - timeout_detector->kvm_tid = 0; - timeout_detector->reload_pending = false; - timeout_detector->detection_enabled = false; + timer->config.tv_sec = 0; + timer->config.tv_usec = 0; - timeout_detector->timeout_sec = 0; - timeout_detector->timeout_usec = 0; /* default: disabled */ - - timeout_detector->arm_timeout.it_interval.tv_sec = 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; + timer->alarm.it_interval.tv_sec = 0; + timer->alarm.it_interval.tv_usec = 0; + timer->alarm.it_value.tv_sec = 0; + timer->alarm.it_value.tv_usec = 0; } static void sigalarm_handler(int signum) { - /* ensure that SIGALARM is ALWAYS handled by kvm thread */ - assert(GET_GLOBAL_STATE()->timeout_detector.kvm_tid == syscall(SYS_gettid)); - //GET_GLOBAL_STATE()->timeout_detector.reload_pending = true; + /* ensure that SIGALARM is ALWAYS handled by kvm thread */ + assert(GET_GLOBAL_STATE()->timeout_detector.kvm_tid == syscall(SYS_gettid)); #ifdef DEBUG_TIMEOUT_DETECTOR + fprintf(stderr, "Handled! %d %ld\n", signum, syscall(SYS_gettid)); #endif - //fprintf(stderr, "Handled! %d %ld\n", signum, syscall(SYS_gettid)); } -void install_timeout_detector(timeout_detector_t* timeout_detector){ - timeout_detector->kvm_tid = syscall(SYS_gettid); - if(signal(SIGALRM, sigalarm_handler) == SIG_ERR) { - fprintf(stderr, "%s failed!\n", __func__); - assert(false); - } - //fprintf(stderr, "SIGALRM HANDLER INSTALLED! %ld\n", syscall(SYS_gettid)); -} - -void reset_timeout_detector(timeout_detector_t* timeout_detector){ -#ifdef DEBUG_TIMEOUT_DETECTOR - fprintf(stderr, "%s!\n", __func__); -#endif - timeout_detector->reload_pending = false; - if(timeout_detector->timeout_sec || timeout_detector->timeout_usec){ - timeout_detector->arm_timeout.it_value.tv_sec = timeout_detector->timeout_sec; - timeout_detector->arm_timeout.it_value.tv_usec = timeout_detector->timeout_usec; - timeout_detector->detection_enabled = true; +void install_timeout_detector(timeout_detector_t* timer){ + timer->kvm_tid = syscall(SYS_gettid); + if (signal(SIGALRM, sigalarm_handler) == SIG_ERR) { + fprintf(stderr, "%s failed!\n", __func__); + assert(false); } - else{ - timeout_detector->detection_enabled = false; +#ifdef DEBUG_TIMEOUT_DETECTOR + fprintf(stderr, "SIGALRM HANDLER INSTALLED! tid=%ld\n", syscall(SYS_gettid)); +#endif +} + +void reset_timeout_detector(timeout_detector_t* timer){ +#ifdef DEBUG_TIMEOUT_DETECTOR + fprintf(stderr, "%s!\n", __func__); +#endif + + if (timer->config.tv_sec || timer->config.tv_usec) { + timer->alarm.it_value.tv_sec = timer->config.tv_sec; + timer->alarm.it_value.tv_usec = timer->config.tv_usec; + timer->detection_enabled = true; + } else { + timer->detection_enabled = false; } } -void enable_timeout_detector(timeout_detector_t* timeout_detector){ - timeout_detector->detection_enabled = true; -} - -/* -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){ +void update_itimer(timeout_detector_t* timer, uint8_t sec, uint32_t usec) +{ +#ifdef DEBUG_TIMEOUT_DETECTOR //fprintf(stderr, "%s: %x %x\n", __func__, sec, usec); - if(sec || usec){ - timeout_detector->timeout_sec = (time_t) sec; - timeout_detector->timeout_usec = (suseconds_t) usec; - timeout_detector->detection_enabled = true; - } - else{ - timeout_detector->detection_enabled = false; +#endif + + if (sec || usec) { + timer->config.tv_sec = (time_t)sec; + timer->config.tv_usec = (suseconds_t)usec; + timer->detection_enabled = true; + } else { + timer->detection_enabled = false; } } -bool arm_sigprof_timer(timeout_detector_t* timeout_detector){ - //return false; - if(timeout_detector->detection_enabled){ - if(timeout_detector->reload_pending || (!timeout_detector->arm_timeout.it_value.tv_sec && !timeout_detector->arm_timeout.it_value.tv_usec)){ - //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); - reset_timeout_detector(timeout_detector); - /* TODO: check if this function still works as expected even if we don't return at this point */ - //return true; - } +void arm_sigprof_timer(timeout_detector_t* timer){ #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 - 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; + if (timer->detection_enabled) { + if (timer->alarm.it_value.tv_usec == 0 && timer->alarm.it_value.tv_sec == 0) { + 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; + } + assert(setitimer(ITIMER_REAL, &timer->alarm, NULL) == 0); + } } -bool disarm_sigprof_timer(timeout_detector_t* timeout_detector){ - //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; +bool disarm_sigprof_timer(timeout_detector_t* timer){ #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 - 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); - //timeout_detector->detection_enabled = false; - return true; - } - } - return false; + + if (timer->detection_enabled) { + 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 false; } void block_signals(void){ @@ -245,24 +210,27 @@ void synchronization_lock_hprintf(void){ } void synchronization_lock(void){ + timeout_detector_t timer = GET_GLOBAL_STATE()->timeout_detector; pthread_mutex_lock(&synchronization_lock_mutex); run_counter++; if(qemu_get_cpu(0)->intel_pt_run_trashed){ 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, - GET_GLOBAL_STATE()->timeout_detector.timeout_usec - (uint32_t)GET_GLOBAL_STATE()->timeout_detector.arm_timeout.it_value.tv_usec, - GET_GLOBAL_STATE()->num_dirty_pages); - /* - if(last_timeout){ - reset_timeout_detector_timeout(&(GET_GLOBAL_STATE()->timeout_detector)); + + long runtime_sec = timer.config.tv_sec - timer.alarm.it_value.tv_sec; + long runtime_usec = timer.config.tv_usec - timer.alarm.it_value.tv_usec; + + if (runtime_usec < 0) { + if (runtime_sec < 1) { + fprintf(stderr, "Error: negative payload runtime?!\n"); + } + runtime_sec -= 1; + runtime_usec = timer.config.tv_usec - timer.alarm.it_value.tv_usec + 1000000; } - else{ - */ - 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()){ 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(); set_timeout_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer); - reset_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector)); perform_reload(); @@ -469,6 +436,5 @@ void synchronization_enter_fuzzing_loop(CPUState *cpu){ in_fuzzing_loop = true; reset_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector)); - //enable_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector)); } diff --git a/nyx/synchronization.h b/nyx/synchronization.h index 802d6f080c..204cb6c080 100644 --- a/nyx/synchronization.h +++ b/nyx/synchronization.h @@ -3,27 +3,19 @@ #include "qemu/osdep.h" #include -typedef struct timeout_detector_s{ +typedef struct timeout_detector_s { int kvm_tid; - volatile bool reload_pending; volatile bool detection_enabled; - time_t timeout_sec; - suseconds_t timeout_usec; - - struct itimerval arm_timeout; - struct itimerval disarm_timeout; - - struct timespec start_time; - struct timespec end_time; + struct timeval config; + struct itimerval alarm; } timeout_detector_t; void init_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); -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); - void update_itimer(timeout_detector_t* timeout_detector, uint8_t sec, uint32_t usec); void block_signals(void); @@ -44,6 +36,3 @@ void synchronization_cow_full_detected(void); void synchronization_disable_pt(CPUState *cpu); void synchronization_enter_fuzzing_loop(CPUState *cpu); 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); diff --git a/vl.c b/vl.c index 02ee5a4dd7..3cc95f5411 100644 --- a/vl.c +++ b/vl.c @@ -2928,7 +2928,7 @@ int main(int argc, char **argv, char **envp) #ifdef QEMU_NYX bool fast_vm_reload = false; state_init_global(); - char *fast_vm_reload_opt_arg = NULL; + const char *fast_vm_reload_opt_arg = NULL; #endif int i;