Skip to content

Commit

Permalink
ARM: KVM: prevent NULL pointer dereferences with KVM VCPU ioctl
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andre Przywara authored and Gleb Natapov committed Jun 3, 2013
1 parent ed82985 commit e8180dc
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions arch/arm/kvm/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,11 @@ static void vcpu_pause(struct kvm_vcpu *vcpu)
wait_event_interruptible(*wq, !vcpu->arch.pause);
}

static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
{
return vcpu->arch.target >= 0;
}

/**
* kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
* @vcpu: The VCPU pointer
Expand All @@ -508,8 +513,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
int ret;
sigset_t sigsaved;

/* Make sure they initialize the vcpu with KVM_ARM_VCPU_INIT */
if (unlikely(vcpu->arch.target < 0))
if (unlikely(!kvm_vcpu_initialized(vcpu)))
return -ENOEXEC;

ret = kvm_vcpu_first_run_init(vcpu);
Expand Down Expand Up @@ -710,6 +714,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
case KVM_SET_ONE_REG:
case KVM_GET_ONE_REG: {
struct kvm_one_reg reg;

if (unlikely(!kvm_vcpu_initialized(vcpu)))
return -ENOEXEC;

if (copy_from_user(&reg, argp, sizeof(reg)))
return -EFAULT;
if (ioctl == KVM_SET_ONE_REG)
Expand All @@ -722,6 +730,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_reg_list reg_list;
unsigned n;

if (unlikely(!kvm_vcpu_initialized(vcpu)))
return -ENOEXEC;

if (copy_from_user(&reg_list, user_list, sizeof(reg_list)))
return -EFAULT;
n = reg_list.n;
Expand Down

0 comments on commit e8180dc

Please sign in to comment.