Commit e8180dcaa8470ceca21109f143876fdcd9fe050a
Committed by
Gleb Natapov
1 parent
ed829857b3
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
ARM: KVM: prevent NULL pointer dereferences with KVM VCPU ioctl
Some ARM KVM VCPU ioctls require the vCPU to be properly initialized with the KVM_ARM_VCPU_INIT ioctl before being used with further requests. KVM_RUN checks whether this initialization has been done, but other ioctls do not. Namely KVM_GET_REG_LIST will dereference an array with index -1 without initialization and thus leads to a kernel oops. Fix this by adding checks before executing the ioctl handlers. [ Removed superflous comment from static function - Christoffer ] Changes from v1: * moved check into a static function with a meaningful name Signed-off-by: Andre Przywara <andre.przywara@linaro.org> Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
Showing 1 changed file with 13 additions and 2 deletions Side-by-side Diff
arch/arm/kvm/arm.c
... | ... | @@ -492,6 +492,11 @@ |
492 | 492 | wait_event_interruptible(*wq, !vcpu->arch.pause); |
493 | 493 | } |
494 | 494 | |
495 | +static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu) | |
496 | +{ | |
497 | + return vcpu->arch.target >= 0; | |
498 | +} | |
499 | + | |
495 | 500 | /** |
496 | 501 | * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code |
497 | 502 | * @vcpu: The VCPU pointer |
... | ... | @@ -508,8 +513,7 @@ |
508 | 513 | int ret; |
509 | 514 | sigset_t sigsaved; |
510 | 515 | |
511 | - /* Make sure they initialize the vcpu with KVM_ARM_VCPU_INIT */ | |
512 | - if (unlikely(vcpu->arch.target < 0)) | |
516 | + if (unlikely(!kvm_vcpu_initialized(vcpu))) | |
513 | 517 | return -ENOEXEC; |
514 | 518 | |
515 | 519 | ret = kvm_vcpu_first_run_init(vcpu); |
... | ... | @@ -710,6 +714,10 @@ |
710 | 714 | case KVM_SET_ONE_REG: |
711 | 715 | case KVM_GET_ONE_REG: { |
712 | 716 | struct kvm_one_reg reg; |
717 | + | |
718 | + if (unlikely(!kvm_vcpu_initialized(vcpu))) | |
719 | + return -ENOEXEC; | |
720 | + | |
713 | 721 | if (copy_from_user(®, argp, sizeof(reg))) |
714 | 722 | return -EFAULT; |
715 | 723 | if (ioctl == KVM_SET_ONE_REG) |
... | ... | @@ -721,6 +729,9 @@ |
721 | 729 | struct kvm_reg_list __user *user_list = argp; |
722 | 730 | struct kvm_reg_list reg_list; |
723 | 731 | unsigned n; |
732 | + | |
733 | + if (unlikely(!kvm_vcpu_initialized(vcpu))) | |
734 | + return -ENOEXEC; | |
724 | 735 | |
725 | 736 | if (copy_from_user(®_list, user_list, sizeof(reg_list))) |
726 | 737 | return -EFAULT; |