Skip to content

Commit 83676e9

Browse files
bonzinirkrcmar
authored andcommitted
KVM: x86: avoid vmalloc(0) in the KVM_SET_CPUID
This causes an ugly dmesg splat. Beautified syzkaller testcase: #include <unistd.h> #include <sys/syscall.h> #include <sys/ioctl.h> #include <fcntl.h> #include <linux/kvm.h> long r[8]; int main() { struct kvm_cpuid2 c = { 0 }; r[2] = open("/dev/kvm", O_RDWR); r[3] = ioctl(r[2], KVM_CREATE_VM, 0); r[4] = ioctl(r[3], KVM_CREATE_VCPU, 0x8); r[7] = ioctl(r[4], KVM_SET_CPUID, &c); return 0; } Reported-by: Dmitry Vyukov <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Radim Krčmář <[email protected]>
1 parent b21629d commit 83676e9

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

arch/x86/kvm/cpuid.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,22 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
181181
struct kvm_cpuid_entry __user *entries)
182182
{
183183
int r, i;
184-
struct kvm_cpuid_entry *cpuid_entries;
184+
struct kvm_cpuid_entry *cpuid_entries = NULL;
185185

186186
r = -E2BIG;
187187
if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
188188
goto out;
189189
r = -ENOMEM;
190-
cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent);
191-
if (!cpuid_entries)
192-
goto out;
193-
r = -EFAULT;
194-
if (copy_from_user(cpuid_entries, entries,
195-
cpuid->nent * sizeof(struct kvm_cpuid_entry)))
196-
goto out_free;
190+
if (cpuid->nent) {
191+
cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) *
192+
cpuid->nent);
193+
if (!cpuid_entries)
194+
goto out;
195+
r = -EFAULT;
196+
if (copy_from_user(cpuid_entries, entries,
197+
cpuid->nent * sizeof(struct kvm_cpuid_entry)))
198+
goto out;
199+
}
197200
for (i = 0; i < cpuid->nent; i++) {
198201
vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
199202
vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
@@ -212,9 +215,8 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
212215
kvm_x86_ops->cpuid_update(vcpu);
213216
r = kvm_update_cpuid(vcpu);
214217

215-
out_free:
216-
vfree(cpuid_entries);
217218
out:
219+
vfree(cpuid_entries);
218220
return r;
219221
}
220222

0 commit comments

Comments
 (0)