• Wanpeng Li's avatar
    KVM: cpuid: Fix read/write out-of-bounds vulnerability in cpuid emulation · f44699a8
    Wanpeng Li authored
    commit a3641631 upstream.
    
    If "i" is the last element in the vcpu->arch.cpuid_entries[] array, it
    potentially can be exploited the vulnerability. this will out-of-bounds
    read and write.  Luckily, the effect is small:
    
    	/* when no next entry is found, the current entry[i] is reselected */
    	for (j = i + 1; ; j = (j + 1) % nent) {
    		struct kvm_cpuid_entry2 *ej = &vcpu->arch.cpuid_entries[j];
    		if (ej->function == e->function) {
    
    It reads ej->maxphyaddr, which is user controlled.  However...
    
    			ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
    
    After cpuid_entries there is
    
    	int maxphyaddr;
    	struct x86_emulate_ctxt emulate_ctxt;  /* 16-byte aligned */
    
    So we have:
    
    - cpuid_entries at offset 1B50 (6992)
    - maxphyaddr at offset 27D0 (6992 + 3200 = 10192)
    - padding at 27D4...27DF
    - emulate_ctxt at 27E0
    
    And it writes in the padding.  Pfew, writing the ops field of emulate_ctxt
    would have been much worse.
    
    This patch fixes it by modding the index to avoid the out-of-bounds
    access. Worst case, i == j and ej->function == e->function,
    the loop can bail out.
    Reported-by: default avatarMoguofang <moguofang@huawei.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Radim Krčmář <rkrcmar@redhat.com>
    Cc: Guofang Mo <moguofang@huawei.com>
    Signed-off-by: default avatarWanpeng Li <wanpeng.li@hotmail.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    f44699a8
cpuid.c 20.1 KB