Commit ff5c2c03 authored by Sasha Levin's avatar Sasha Levin Committed by Avi Kivity

KVM: Use memdup_user instead of kmalloc/copy_from_user

Switch to using memdup_user when possible. This makes code more
smaller and compact, and prevents errors.
Signed-off-by: default avatarSasha Levin <levinsasha928@gmail.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent cdfca7b3
...@@ -1309,12 +1309,11 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data) ...@@ -1309,12 +1309,11 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data)
if (page_num >= blob_size) if (page_num >= blob_size)
goto out; goto out;
r = -ENOMEM; r = -ENOMEM;
page = kzalloc(PAGE_SIZE, GFP_KERNEL); page = memdup_user(blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE);
if (!page) if (IS_ERR(page)) {
r = PTR_ERR(page);
goto out; goto out;
r = -EFAULT; }
if (copy_from_user(page, blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE))
goto out_free;
if (kvm_write_guest(kvm, page_addr, page, PAGE_SIZE)) if (kvm_write_guest(kvm, page_addr, page, PAGE_SIZE))
goto out_free; goto out_free;
r = 0; r = 0;
...@@ -1988,15 +1987,12 @@ static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs, ...@@ -1988,15 +1987,12 @@ static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs,
if (msrs.nmsrs >= MAX_IO_MSRS) if (msrs.nmsrs >= MAX_IO_MSRS)
goto out; goto out;
r = -ENOMEM;
size = sizeof(struct kvm_msr_entry) * msrs.nmsrs; size = sizeof(struct kvm_msr_entry) * msrs.nmsrs;
entries = kmalloc(size, GFP_KERNEL); entries = memdup_user(user_msrs->entries, size);
if (!entries) if (IS_ERR(entries)) {
r = PTR_ERR(entries);
goto out; goto out;
}
r = -EFAULT;
if (copy_from_user(entries, user_msrs->entries, size))
goto out_free;
r = n = __msr_io(vcpu, &msrs, entries, do_msr); r = n = __msr_io(vcpu, &msrs, entries, do_msr);
if (r < 0) if (r < 0)
...@@ -2533,13 +2529,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp, ...@@ -2533,13 +2529,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = -EINVAL; r = -EINVAL;
if (!vcpu->arch.apic) if (!vcpu->arch.apic)
goto out; goto out;
u.lapic = kmalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL); u.lapic = memdup_user(argp, sizeof(*u.lapic));
r = -ENOMEM; if (IS_ERR(u.lapic)) {
if (!u.lapic) r = PTR_ERR(u.lapic);
goto out;
r = -EFAULT;
if (copy_from_user(u.lapic, argp, sizeof(struct kvm_lapic_state)))
goto out; goto out;
}
r = kvm_vcpu_ioctl_set_lapic(vcpu, u.lapic); r = kvm_vcpu_ioctl_set_lapic(vcpu, u.lapic);
if (r) if (r)
goto out; goto out;
...@@ -2718,14 +2713,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp, ...@@ -2718,14 +2713,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
break; break;
} }
case KVM_SET_XSAVE: { case KVM_SET_XSAVE: {
u.xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); u.xsave = memdup_user(argp, sizeof(*u.xsave));
r = -ENOMEM; if (IS_ERR(u.xsave)) {
if (!u.xsave) r = PTR_ERR(u.xsave);
break; goto out;
}
r = -EFAULT;
if (copy_from_user(u.xsave, argp, sizeof(struct kvm_xsave)))
break;
r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, u.xsave); r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, u.xsave);
break; break;
...@@ -2746,15 +2738,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp, ...@@ -2746,15 +2738,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
break; break;
} }
case KVM_SET_XCRS: { case KVM_SET_XCRS: {
u.xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); u.xcrs = memdup_user(argp, sizeof(*u.xcrs));
r = -ENOMEM; if (IS_ERR(u.xcrs)) {
if (!u.xcrs) r = PTR_ERR(u.xcrs);
break; goto out;
}
r = -EFAULT;
if (copy_from_user(u.xcrs, argp,
sizeof(struct kvm_xcrs)))
break;
r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs); r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs);
break; break;
...@@ -3190,14 +3178,14 @@ long kvm_arch_vm_ioctl(struct file *filp, ...@@ -3190,14 +3178,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
} }
case KVM_GET_IRQCHIP: { case KVM_GET_IRQCHIP: {
/* 0: PIC master, 1: PIC slave, 2: IOAPIC */ /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL); struct kvm_irqchip *chip;
r = -ENOMEM; chip = memdup_user(argp, sizeof(*chip));
if (!chip) if (IS_ERR(chip)) {
r = PTR_ERR(chip);
goto out; goto out;
r = -EFAULT; }
if (copy_from_user(chip, argp, sizeof *chip))
goto get_irqchip_out;
r = -ENXIO; r = -ENXIO;
if (!irqchip_in_kernel(kvm)) if (!irqchip_in_kernel(kvm))
goto get_irqchip_out; goto get_irqchip_out;
...@@ -3216,14 +3204,14 @@ long kvm_arch_vm_ioctl(struct file *filp, ...@@ -3216,14 +3204,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
} }
case KVM_SET_IRQCHIP: { case KVM_SET_IRQCHIP: {
/* 0: PIC master, 1: PIC slave, 2: IOAPIC */ /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL); struct kvm_irqchip *chip;
r = -ENOMEM; chip = memdup_user(argp, sizeof(*chip));
if (!chip) if (IS_ERR(chip)) {
r = PTR_ERR(chip);
goto out; goto out;
r = -EFAULT; }
if (copy_from_user(chip, argp, sizeof *chip))
goto set_irqchip_out;
r = -ENXIO; r = -ENXIO;
if (!irqchip_in_kernel(kvm)) if (!irqchip_in_kernel(kvm))
goto set_irqchip_out; goto set_irqchip_out;
......
...@@ -1821,12 +1821,11 @@ static long kvm_vcpu_ioctl(struct file *filp, ...@@ -1821,12 +1821,11 @@ static long kvm_vcpu_ioctl(struct file *filp,
struct kvm_regs *kvm_regs; struct kvm_regs *kvm_regs;
r = -ENOMEM; r = -ENOMEM;
kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL); kvm_regs = memdup_user(argp, sizeof(*kvm_regs));
if (!kvm_regs) if (IS_ERR(kvm_regs)) {
r = PTR_ERR(kvm_regs);
goto out; goto out;
r = -EFAULT; }
if (copy_from_user(kvm_regs, argp, sizeof(struct kvm_regs)))
goto out_free2;
r = kvm_arch_vcpu_ioctl_set_regs(vcpu, kvm_regs); r = kvm_arch_vcpu_ioctl_set_regs(vcpu, kvm_regs);
if (r) if (r)
goto out_free2; goto out_free2;
...@@ -1850,13 +1849,11 @@ static long kvm_vcpu_ioctl(struct file *filp, ...@@ -1850,13 +1849,11 @@ static long kvm_vcpu_ioctl(struct file *filp,
break; break;
} }
case KVM_SET_SREGS: { case KVM_SET_SREGS: {
kvm_sregs = kmalloc(sizeof(struct kvm_sregs), GFP_KERNEL); kvm_sregs = memdup_user(argp, sizeof(*kvm_sregs));
r = -ENOMEM; if (IS_ERR(kvm_sregs)) {
if (!kvm_sregs) r = PTR_ERR(kvm_sregs);
goto out;
r = -EFAULT;
if (copy_from_user(kvm_sregs, argp, sizeof(struct kvm_sregs)))
goto out; goto out;
}
r = kvm_arch_vcpu_ioctl_set_sregs(vcpu, kvm_sregs); r = kvm_arch_vcpu_ioctl_set_sregs(vcpu, kvm_sregs);
if (r) if (r)
goto out; goto out;
...@@ -1952,13 +1949,11 @@ static long kvm_vcpu_ioctl(struct file *filp, ...@@ -1952,13 +1949,11 @@ static long kvm_vcpu_ioctl(struct file *filp,
break; break;
} }
case KVM_SET_FPU: { case KVM_SET_FPU: {
fpu = kmalloc(sizeof(struct kvm_fpu), GFP_KERNEL); fpu = memdup_user(argp, sizeof(*fpu));
r = -ENOMEM; if (IS_ERR(fpu)) {
if (!fpu) r = PTR_ERR(fpu);
goto out;
r = -EFAULT;
if (copy_from_user(fpu, argp, sizeof(struct kvm_fpu)))
goto out; goto out;
}
r = kvm_arch_vcpu_ioctl_set_fpu(vcpu, fpu); r = kvm_arch_vcpu_ioctl_set_fpu(vcpu, fpu);
if (r) if (r)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment