qemu-kvm.git uq/master queue
The following changes since commit 1356b98d3e95a85071e6bf9a99e8799e1ae1bbee:
sysbus: Drop sysbus_from_qdev() cast macro (2013-01-21 13:52:24 -0600)
are available in the git repository at:
git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master
for you to fetch changes up to f8bb056564ed719b2fa5e05028bc70aeb0cc5c6c:
target-i386: kvm: prevent buffer overflow if -cpu foo, [x]level is too big (2013-01-29 08:57:56 +0200)
----------------------------------------------------------------
Igor Mammedov (1):
target-i386: kvm: prevent buffer overflow if -cpu foo, [x]level is too big
Marcelo Tosatti (1):
vmxcap: bit 9 of VMX_PROCBASED_CTLS2 is 'virtual interrupt delivery'
scripts/kvm/vmxcap | 1 + target-i386/kvm.c | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-)
PATCH 1/2 vmxcap: bit 9 of VMX_PROCBASED_CTLS2 is 'virtual interrupt delivery'
From: Marcelo Tosatti <[email protected]>
Bit 9 of MSR_IA32_VMX_PROCBASED_CTLS2 is
virtual interrupt delivery.
--- scripts/kvm/vmxcap | 1 + 1 file changed, 1 insertion(+)
scripts/kvm/vmxcap +1 -0
@@ -147,6 +147,7 @@ controls = [ 5: 'Enable VPID', 6: 'WBINVD exiting', 7: 'Unrestricted guest', + 9: 'Virtual interrupt delivery', 10: 'PAUSE-loop exiting', 11: 'RDRAND exiting', 12: 'Enable INVPCID',
Signature · 1 line
1.7.10.4
PATCH 2/2 target-i386: kvm: prevent buffer overflow if -cpu foo, [x]level is too big
In reply to Gleb NatapovFrom: Igor Mammedov <[email protected]>
Stack corruption may occur if too big 'level' or 'xlevel' values passed on command line with KVM enabled, due to limited size of cpuid_data in kvm_arch_init_vcpu().
reproduces with:
qemu -enable-kvm -cpu qemu64,level=4294967295
or
qemu -enable-kvm -cpu qemu64,xlevel=4294967295
Check if there is space in cpuid_data before passing it to cpu_x86_cpuid() or abort() if there is not space.
--- target-i386/kvm.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
target-i386/kvm.c +24 -1
@@ -411,11 +411,12 @@ static void cpu_update_state(void *opaque, int running, RunState state) } } +#define KVM_MAX_CPUID_ENTRIES 100int kvm_arch_init_vcpu (CPUState *cs) {struct {struct kvm_cpuid2 cpuid; -struct kvm_cpuid_entry2 entries[100 ]; +struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES ]; } QEMU_PACKED cpuid_data;X86CPU *cpu =X86_CPU (cs);CPUX86State *env = &cpu->env;
@@ -502,6 +503,10 @@ int kvm_arch_init_vcpu(CPUState *cs)cpu_x86_cpuid (env,0 ,0 , &limit, &unused, &unused, &unused);for (i =0 ; i <= limit; i++) { +if (cpuid_i ==KVM_MAX_CPUID_ENTRIES ) { +fprintf (stderr,"unsupported level value: 0x%x\n" , limit); +abort (); + } c = &cpuid_data.entries[cpuid_i++];switch (i) {
@@ -516,6 +521,11 @@ int kvm_arch_init_vcpu(CPUState *cs) times = c->eax &0xff ;for (j =1 ; j < times; ++j) { +if (cpuid_i ==KVM_MAX_CPUID_ENTRIES ) { +fprintf (stderr,"cpuid_data is full, no space for " +"cpuid(eax:2):eax & 0xf = 0x%x\n" , times); +abort (); + } c = &cpuid_data.entries[cpuid_i++]; c->function = i; c->flags =KVM_CPUID_FLAG_STATEFUL_FUNC ;
@@ -544,6 +554,11 @@ int kvm_arch_init_vcpu(CPUState *cs)if (i ==0xd && c->eax ==0 ) {continue ; } +if (cpuid_i ==KVM_MAX_CPUID_ENTRIES ) { +fprintf (stderr,"cpuid_data is full, no space for " +"cpuid(eax:0x%x,ecx:0x%x)\n" , i, j); +abort (); + } c = &cpuid_data.entries[cpuid_i++]; }break ;
@@ -557,6 +572,10 @@ int kvm_arch_init_vcpu(CPUState *cs)cpu_x86_cpuid (env,0x80000000 ,0 , &limit, &unused, &unused, &unused);for (i =0x80000000 ; i <= limit; i++) { +if (cpuid_i ==KVM_MAX_CPUID_ENTRIES ) { +fprintf (stderr,"unsupported xlevel value: 0x%x\n" , limit); +abort (); + } c = &cpuid_data.entries[cpuid_i++]; c->function = i;
@@ -569,6 +588,10 @@ int kvm_arch_init_vcpu(CPUState *cs)cpu_x86_cpuid (env,0xC0000000 ,0 , &limit, &unused, &unused, &unused);for (i =0xC0000000 ; i <= limit; i++) { +if (cpuid_i ==KVM_MAX_CPUID_ENTRIES ) { +fprintf (stderr,"unsupported xlevel2 value: 0x%x\n" , limit); +abort (); + } c = &cpuid_data.entries[cpuid_i++]; c->function = i;
Signature · 1 line
1.7.10.4