Sean Christopherson <seanjc@xxxxxxxxxx> writes: > Free the "struct kvm_cpuid_entry2" array on successful post-KVM_RUN > KVM_SET_CPUID{,2} to fix a memory leak, the callers of kvm_set_cpuid() > free the array only on failure. > > BUG: memory leak > unreferenced object 0xffff88810963a800 (size 2048): > comm "syz-executor025", pid 3610, jiffies 4294944928 (age 8.080s) > hex dump (first 32 bytes): > 00 00 00 00 00 00 00 00 00 00 00 00 0d 00 00 00 ................ > 47 65 6e 75 6e 74 65 6c 69 6e 65 49 00 00 00 00 GenuntelineI.... > backtrace: > [<ffffffff814948ee>] kmalloc_node include/linux/slab.h:604 [inline] > [<ffffffff814948ee>] kvmalloc_node+0x3e/0x100 mm/util.c:580 > [<ffffffff814950f2>] kvmalloc include/linux/slab.h:732 [inline] > [<ffffffff814950f2>] vmemdup_user+0x22/0x100 mm/util.c:199 > [<ffffffff8109f5ff>] kvm_vcpu_ioctl_set_cpuid2+0x8f/0xf0 arch/x86/kvm/cpuid.c:423 > [<ffffffff810711b9>] kvm_arch_vcpu_ioctl+0xb99/0x1e60 arch/x86/kvm/x86.c:5251 > [<ffffffff8103e92d>] kvm_vcpu_ioctl+0x4ad/0x950 arch/x86/kvm/../../../virt/kvm/kvm_main.c:4066 > [<ffffffff815afacc>] vfs_ioctl fs/ioctl.c:51 [inline] > [<ffffffff815afacc>] __do_sys_ioctl fs/ioctl.c:874 [inline] > [<ffffffff815afacc>] __se_sys_ioctl fs/ioctl.c:860 [inline] > [<ffffffff815afacc>] __x64_sys_ioctl+0xfc/0x140 fs/ioctl.c:860 > [<ffffffff844a3335>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] > [<ffffffff844a3335>] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 > [<ffffffff84600068>] entry_SYSCALL_64_after_hwframe+0x44/0xae > > Fixes: c6617c61e8fe ("KVM: x86: Partially allow KVM_SET_CPUID{,2} after KVM_RUN") > Cc: stable@xxxxxxxxxxxxxxx > Reported-by: syzbot+be576ad7655690586eec@xxxxxxxxxxxxxxxxxxxxxxxxx > Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> > --- > arch/x86/kvm/cpuid.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c > index 3902c28fb6cb..0a08db384fb9 100644 > --- a/arch/x86/kvm/cpuid.c > +++ b/arch/x86/kvm/cpuid.c > @@ -346,8 +346,14 @@ static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2, > * KVM_SET_CPUID{,2} again. To support this legacy behavior, check > * whether the supplied CPUID data is equal to what's already set. > */ > - if (vcpu->arch.last_vmentry_cpu != -1) > - return kvm_cpuid_check_equal(vcpu, e2, nent); > + if (vcpu->arch.last_vmentry_cpu != -1) { > + r = kvm_cpuid_check_equal(vcpu, e2, nent); > + if (r) > + return r; > + > + kvfree(e2); > + return 0; > + } > > r = kvm_check_cpuid(vcpu, e2, nent); > if (r) > > base-commit: e2e83a73d7ce66f62c7830a85619542ef59c90e4 Reviewed-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> Thanks! -- Vitaly