Skip to contentSkip to conversation

qemu-kvm.git uq/master queue

GIT PULL New Gleb Natapov 1 participant 3 messages Jan 29, 2013 KVM

lore
Share & tools
lore
#0 lore raw

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(-)
#1 lore raw

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
index cbe6440..0b23f77 100755
@@ -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
#2 lore raw

PATCH 2/2 target-i386: kvm: prevent buffer overflow if -cpu foo, [x]level is too big

In reply to Gleb Natapov

From: 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
index 3acff40..4ecb728 100644
@@ -411,11 +411,12 @@ static void cpu_update_state(void *opaque, int running, RunState state)
     }
 }
 
+#define KVM_MAX_CPUID_ENTRIES  100
 int 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