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/nyx/synchronization.c b/nyx/synchronization.c index 8aa1ade89a..48e758c9b4 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){ @@ -264,16 +229,10 @@ void synchronization_lock(void){ runtime_usec = timer.config.tv_usec - timer.alarm.it_value.tv_usec + 1000000; } set_exec_done_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, - runtime_sec, runtime_usec, - GET_GLOBAL_STATE()->num_dirty_pages); - /* - if(last_timeout){ - reset_timeout_detector_timeout(&(GET_GLOBAL_STATE()->timeout_detector)); - } - else{ - */ + runtime_sec, runtime_usec, + GET_GLOBAL_STATE()->num_dirty_pages); + reset_timeout_detector(&(GET_GLOBAL_STATE()->timeout_detector)); - //} if(synchronization_check_page_not_found()){ set_success_auxiliary_result_buffer(GET_GLOBAL_STATE()->auxilary_buffer, 0); @@ -480,6 +439,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);