Commit ff5c2c0316ff0e3e2dba3ca14167d994453df093
Committed by
Avi Kivity
1 parent
cdfca7b346
Exists in
master
and in
6 other branches
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: Sasha Levin <levinsasha928@gmail.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Showing 2 changed files with 47 additions and 64 deletions Side-by-side Diff
arch/x86/kvm/x86.c
... | ... | @@ -1309,12 +1309,11 @@ |
1309 | 1309 | if (page_num >= blob_size) |
1310 | 1310 | goto out; |
1311 | 1311 | r = -ENOMEM; |
1312 | - page = kzalloc(PAGE_SIZE, GFP_KERNEL); | |
1313 | - if (!page) | |
1312 | + page = memdup_user(blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE); | |
1313 | + if (IS_ERR(page)) { | |
1314 | + r = PTR_ERR(page); | |
1314 | 1315 | goto out; |
1315 | - r = -EFAULT; | |
1316 | - if (copy_from_user(page, blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE)) | |
1317 | - goto out_free; | |
1316 | + } | |
1318 | 1317 | if (kvm_write_guest(kvm, page_addr, page, PAGE_SIZE)) |
1319 | 1318 | goto out_free; |
1320 | 1319 | r = 0; |
1321 | 1320 | |
1322 | 1321 | |
1323 | 1322 | |
... | ... | @@ -1988,16 +1987,13 @@ |
1988 | 1987 | if (msrs.nmsrs >= MAX_IO_MSRS) |
1989 | 1988 | goto out; |
1990 | 1989 | |
1991 | - r = -ENOMEM; | |
1992 | 1990 | size = sizeof(struct kvm_msr_entry) * msrs.nmsrs; |
1993 | - entries = kmalloc(size, GFP_KERNEL); | |
1994 | - if (!entries) | |
1991 | + entries = memdup_user(user_msrs->entries, size); | |
1992 | + if (IS_ERR(entries)) { | |
1993 | + r = PTR_ERR(entries); | |
1995 | 1994 | goto out; |
1995 | + } | |
1996 | 1996 | |
1997 | - r = -EFAULT; | |
1998 | - if (copy_from_user(entries, user_msrs->entries, size)) | |
1999 | - goto out_free; | |
2000 | - | |
2001 | 1997 | r = n = __msr_io(vcpu, &msrs, entries, do_msr); |
2002 | 1998 | if (r < 0) |
2003 | 1999 | goto out_free; |
2004 | 2000 | |
... | ... | @@ -2533,13 +2529,12 @@ |
2533 | 2529 | r = -EINVAL; |
2534 | 2530 | if (!vcpu->arch.apic) |
2535 | 2531 | goto out; |
2536 | - u.lapic = kmalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL); | |
2537 | - r = -ENOMEM; | |
2538 | - if (!u.lapic) | |
2532 | + u.lapic = memdup_user(argp, sizeof(*u.lapic)); | |
2533 | + if (IS_ERR(u.lapic)) { | |
2534 | + r = PTR_ERR(u.lapic); | |
2539 | 2535 | goto out; |
2540 | - r = -EFAULT; | |
2541 | - if (copy_from_user(u.lapic, argp, sizeof(struct kvm_lapic_state))) | |
2542 | - goto out; | |
2536 | + } | |
2537 | + | |
2543 | 2538 | r = kvm_vcpu_ioctl_set_lapic(vcpu, u.lapic); |
2544 | 2539 | if (r) |
2545 | 2540 | goto out; |
2546 | 2541 | |
... | ... | @@ -2718,15 +2713,12 @@ |
2718 | 2713 | break; |
2719 | 2714 | } |
2720 | 2715 | case KVM_SET_XSAVE: { |
2721 | - u.xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); | |
2722 | - r = -ENOMEM; | |
2723 | - if (!u.xsave) | |
2724 | - break; | |
2716 | + u.xsave = memdup_user(argp, sizeof(*u.xsave)); | |
2717 | + if (IS_ERR(u.xsave)) { | |
2718 | + r = PTR_ERR(u.xsave); | |
2719 | + goto out; | |
2720 | + } | |
2725 | 2721 | |
2726 | - r = -EFAULT; | |
2727 | - if (copy_from_user(u.xsave, argp, sizeof(struct kvm_xsave))) | |
2728 | - break; | |
2729 | - | |
2730 | 2722 | r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, u.xsave); |
2731 | 2723 | break; |
2732 | 2724 | } |
2733 | 2725 | |
... | ... | @@ -2746,16 +2738,12 @@ |
2746 | 2738 | break; |
2747 | 2739 | } |
2748 | 2740 | case KVM_SET_XCRS: { |
2749 | - u.xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); | |
2750 | - r = -ENOMEM; | |
2751 | - if (!u.xcrs) | |
2752 | - break; | |
2741 | + u.xcrs = memdup_user(argp, sizeof(*u.xcrs)); | |
2742 | + if (IS_ERR(u.xcrs)) { | |
2743 | + r = PTR_ERR(u.xcrs); | |
2744 | + goto out; | |
2745 | + } | |
2753 | 2746 | |
2754 | - r = -EFAULT; | |
2755 | - if (copy_from_user(u.xcrs, argp, | |
2756 | - sizeof(struct kvm_xcrs))) | |
2757 | - break; | |
2758 | - | |
2759 | 2747 | r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs); |
2760 | 2748 | break; |
2761 | 2749 | } |
2762 | 2750 | |
2763 | 2751 | |
... | ... | @@ -3190,14 +3178,14 @@ |
3190 | 3178 | } |
3191 | 3179 | case KVM_GET_IRQCHIP: { |
3192 | 3180 | /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ |
3193 | - struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL); | |
3181 | + struct kvm_irqchip *chip; | |
3194 | 3182 | |
3195 | - r = -ENOMEM; | |
3196 | - if (!chip) | |
3183 | + chip = memdup_user(argp, sizeof(*chip)); | |
3184 | + if (IS_ERR(chip)) { | |
3185 | + r = PTR_ERR(chip); | |
3197 | 3186 | goto out; |
3198 | - r = -EFAULT; | |
3199 | - if (copy_from_user(chip, argp, sizeof *chip)) | |
3200 | - goto get_irqchip_out; | |
3187 | + } | |
3188 | + | |
3201 | 3189 | r = -ENXIO; |
3202 | 3190 | if (!irqchip_in_kernel(kvm)) |
3203 | 3191 | goto get_irqchip_out; |
3204 | 3192 | |
3205 | 3193 | |
... | ... | @@ -3216,14 +3204,14 @@ |
3216 | 3204 | } |
3217 | 3205 | case KVM_SET_IRQCHIP: { |
3218 | 3206 | /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ |
3219 | - struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL); | |
3207 | + struct kvm_irqchip *chip; | |
3220 | 3208 | |
3221 | - r = -ENOMEM; | |
3222 | - if (!chip) | |
3209 | + chip = memdup_user(argp, sizeof(*chip)); | |
3210 | + if (IS_ERR(chip)) { | |
3211 | + r = PTR_ERR(chip); | |
3223 | 3212 | goto out; |
3224 | - r = -EFAULT; | |
3225 | - if (copy_from_user(chip, argp, sizeof *chip)) | |
3226 | - goto set_irqchip_out; | |
3213 | + } | |
3214 | + | |
3227 | 3215 | r = -ENXIO; |
3228 | 3216 | if (!irqchip_in_kernel(kvm)) |
3229 | 3217 | goto set_irqchip_out; |
virt/kvm/kvm_main.c
... | ... | @@ -1821,12 +1821,11 @@ |
1821 | 1821 | struct kvm_regs *kvm_regs; |
1822 | 1822 | |
1823 | 1823 | r = -ENOMEM; |
1824 | - kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL); | |
1825 | - if (!kvm_regs) | |
1824 | + kvm_regs = memdup_user(argp, sizeof(*kvm_regs)); | |
1825 | + if (IS_ERR(kvm_regs)) { | |
1826 | + r = PTR_ERR(kvm_regs); | |
1826 | 1827 | goto out; |
1827 | - r = -EFAULT; | |
1828 | - if (copy_from_user(kvm_regs, argp, sizeof(struct kvm_regs))) | |
1829 | - goto out_free2; | |
1828 | + } | |
1830 | 1829 | r = kvm_arch_vcpu_ioctl_set_regs(vcpu, kvm_regs); |
1831 | 1830 | if (r) |
1832 | 1831 | goto out_free2; |
1833 | 1832 | |
... | ... | @@ -1850,13 +1849,11 @@ |
1850 | 1849 | break; |
1851 | 1850 | } |
1852 | 1851 | case KVM_SET_SREGS: { |
1853 | - kvm_sregs = kmalloc(sizeof(struct kvm_sregs), GFP_KERNEL); | |
1854 | - r = -ENOMEM; | |
1855 | - if (!kvm_sregs) | |
1852 | + kvm_sregs = memdup_user(argp, sizeof(*kvm_sregs)); | |
1853 | + if (IS_ERR(kvm_sregs)) { | |
1854 | + r = PTR_ERR(kvm_sregs); | |
1856 | 1855 | goto out; |
1857 | - r = -EFAULT; | |
1858 | - if (copy_from_user(kvm_sregs, argp, sizeof(struct kvm_sregs))) | |
1859 | - goto out; | |
1856 | + } | |
1860 | 1857 | r = kvm_arch_vcpu_ioctl_set_sregs(vcpu, kvm_sregs); |
1861 | 1858 | if (r) |
1862 | 1859 | goto out; |
1863 | 1860 | |
... | ... | @@ -1952,13 +1949,11 @@ |
1952 | 1949 | break; |
1953 | 1950 | } |
1954 | 1951 | case KVM_SET_FPU: { |
1955 | - fpu = kmalloc(sizeof(struct kvm_fpu), GFP_KERNEL); | |
1956 | - r = -ENOMEM; | |
1957 | - if (!fpu) | |
1952 | + fpu = memdup_user(argp, sizeof(*fpu)); | |
1953 | + if (IS_ERR(fpu)) { | |
1954 | + r = PTR_ERR(fpu); | |
1958 | 1955 | goto out; |
1959 | - r = -EFAULT; | |
1960 | - if (copy_from_user(fpu, argp, sizeof(struct kvm_fpu))) | |
1961 | - goto out; | |
1956 | + } | |
1962 | 1957 | r = kvm_arch_vcpu_ioctl_set_fpu(vcpu, fpu); |
1963 | 1958 | if (r) |
1964 | 1959 | goto out; |