kvm_cpu_thread()'s panic path uses the kernel's exit_reason to index kvm_exit_reasons[] without checking it against the array's size. The table does not cover every exit reason KVM can return, so a reason past its last entry reads out of bounds. KVM_EXIT_SYSTEM_EVENT and KVM_EXIT_ARM_NISV are both past it. Move the table behind kvm__exit_reason_str(), which checks the index first. The array now has a single caller inside kvm.c, so make it static const. Signed-off-by: Fuad Tabba --- builtin-run.c | 2 +- include/kvm/kvm.h | 2 +- kvm.c | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/builtin-run.c b/builtin-run.c index 81f255f..f36d3e2 100644 --- a/builtin-run.c +++ b/builtin-run.c @@ -298,7 +298,7 @@ static void *kvm_cpu_thread(void *arg) panic_kvm: pr_err("KVM exit reason: %u (\"%s\")", current_kvm_cpu->kvm_run->exit_reason, - kvm_exit_reasons[current_kvm_cpu->kvm_run->exit_reason]); + kvm__exit_reason_str(current_kvm_cpu->kvm_run->exit_reason)); if (current_kvm_cpu->kvm_run->exit_reason == KVM_EXIT_UNKNOWN) { pr_err("KVM exit code: %llu", diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h index a9376b6..8619070 100644 --- a/include/kvm/kvm.h +++ b/include/kvm/kvm.h @@ -255,7 +255,7 @@ int kvm__for_each_mem_bank(struct kvm *kvm, enum kvm_mem_type type, */ void kvm__dump_mem(struct kvm *kvm, unsigned long addr, unsigned long size, int debug_fd); -extern const char *kvm_exit_reasons[]; +const char *kvm__exit_reason_str(__u32 exit_reason); static inline bool host_ptr_in_ram(struct kvm *kvm, void *p) { diff --git a/kvm.c b/kvm.c index 96583f9..b416f6f 100644 --- a/kvm.c +++ b/kvm.c @@ -33,7 +33,7 @@ #define DEFINE_KVM_EXIT_REASON(reason) [reason] = #reason -const char *kvm_exit_reasons[] = { +static const char * const kvm_exit_reasons[] = { DEFINE_KVM_EXIT_REASON(KVM_EXIT_UNKNOWN), DEFINE_KVM_EXIT_REASON(KVM_EXIT_EXCEPTION), DEFINE_KVM_EXIT_REASON(KVM_EXIT_IO), @@ -57,6 +57,14 @@ const char *kvm_exit_reasons[] = { #endif }; +const char *kvm__exit_reason_str(__u32 exit_reason) +{ + if (exit_reason >= ARRAY_SIZE(kvm_exit_reasons)) + return "UNKNOWN"; + + return kvm_exit_reasons[exit_reason]; +} + static int pause_event; static DEFINE_MUTEX(pause_lock); static struct kvm_cpu *pause_req_cpu; -- 2.39.5