From 3ed90cbba30f7fd82be3b374cf7ba40e4e852b79 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 9 Dec 2012 19:12:04 +0000 Subject: [PATCH] [x86] KVM: x86: invalid opcode oops on SET_SREGS with OSXSAVE bit set (CVE-2012-4461) svn path=/dists/sid/linux/; revision=19591 --- debian/changelog | 2 + ...opcode-oops-on-SET_SREGS-with-OSXSAV.patch | 71 +++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 74 insertions(+) create mode 100644 debian/patches/bugfix/x86/KVM-x86-invalid-opcode-oops-on-SET_SREGS-with-OSXSAV.patch diff --git a/debian/changelog b/debian/changelog index b2ecc65f1..bae8c0359 100644 --- a/debian/changelog +++ b/debian/changelog @@ -93,6 +93,8 @@ linux (3.2.35-1) UNRELEASED; urgency=low * firmware: Remove redundant log messages from drivers * [x86] ACPI / video: ignore BIOS initial backlight value for HP Folio 13-2000 (Closes: #692361) + * [x86] KVM: x86: invalid opcode oops on SET_SREGS with OSXSAVE bit set + (CVE-2012-4461) [ Ian Campbell ] * [xen] add support for microcode updating. (Closes: #693053) diff --git a/debian/patches/bugfix/x86/KVM-x86-invalid-opcode-oops-on-SET_SREGS-with-OSXSAV.patch b/debian/patches/bugfix/x86/KVM-x86-invalid-opcode-oops-on-SET_SREGS-with-OSXSAV.patch new file mode 100644 index 000000000..b40317da5 --- /dev/null +++ b/debian/patches/bugfix/x86/KVM-x86-invalid-opcode-oops-on-SET_SREGS-with-OSXSAV.patch @@ -0,0 +1,71 @@ +From 6d1068b3a98519247d8ba4ec85cd40ac136dbdf9 Mon Sep 17 00:00:00 2001 +From: Petr Matousek +Date: Tue, 6 Nov 2012 19:24:07 +0100 +Subject: [PATCH] KVM: x86: invalid opcode oops on SET_SREGS with OSXSAVE bit + set (CVE-2012-4461) + +On hosts without the XSAVE support unprivileged local user can trigger +oops similar to the one below by setting X86_CR4_OSXSAVE bit in guest +cr4 register using KVM_SET_SREGS ioctl and later issuing KVM_RUN +ioctl. + +invalid opcode: 0000 [#2] SMP +Modules linked in: tun ip6table_filter ip6_tables ebtable_nat ebtables +... +Pid: 24935, comm: zoog_kvm_monito Tainted: G D 3.2.0-3-686-pae +EIP: 0060:[] EFLAGS: 00210246 CPU: 0 +EIP is at kvm_arch_vcpu_ioctl_run+0x92a/0xd13 [kvm] +EAX: 00000001 EBX: 000f387e ECX: 00000000 EDX: 00000000 +ESI: 00000000 EDI: 00000000 EBP: ef5a0060 ESP: d7c63e70 + DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 +Process zoog_kvm_monito (pid: 24935, ti=d7c62000 task=ed84a0c0 +task.ti=d7c62000) +Stack: + 00000001 f70a1200 f8b940a9 ef5a0060 00000000 00200202 f8769009 00000000 + ef5a0060 000f387e eda5c020 8722f9c8 00015bae 00000000 ed84a0c0 ed84a0c0 + c12bf02d 0000ae80 ef7f8740 fffffffb f359b740 ef5a0060 f8b85dc1 0000ae80 +Call Trace: + [] ? kvm_arch_vcpu_ioctl_set_sregs+0x2fe/0x308 [kvm] +... + [] ? syscall_call+0x7/0xb +Code: 89 e8 e8 14 ee ff ff ba 00 00 04 00 89 e8 e8 98 48 ff ff 85 c0 74 +1e 83 7d 48 00 75 18 8b 85 08 07 00 00 31 c9 8b 95 0c 07 00 00 <0f> 01 +d1 c7 45 48 01 00 00 00 c7 45 1c 01 00 00 00 0f ae f0 89 +EIP: [] kvm_arch_vcpu_ioctl_run+0x92a/0xd13 [kvm] SS:ESP +0068:d7c63e70 + +QEMU first retrieves the supported features via KVM_GET_SUPPORTED_CPUID +and then sets them later. So guest's X86_FEATURE_XSAVE should be masked +out on hosts without X86_FEATURE_XSAVE, making kvm_set_cr4 with +X86_CR4_OSXSAVE fail. Userspaces that allow specifying guest cpuid with +X86_FEATURE_XSAVE even on hosts that do not support it, might be +susceptible to this attack from inside the guest as well. + +Allow setting X86_CR4_OSXSAVE bit only if host has XSAVE support. + +Signed-off-by: Petr Matousek +Signed-off-by: Marcelo Tosatti +[bwh: Backported to 3.2: both functions are in arch/x86/kvm/x86.c] +--- +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -578,6 +578,9 @@ static bool guest_cpuid_has_xsave(struct + { + struct kvm_cpuid_entry2 *best; + ++ if (!static_cpu_has(X86_FEATURE_XSAVE)) ++ return 0; ++ + best = kvm_find_cpuid_entry(vcpu, 1, 0); + return best && (best->ecx & bit(X86_FEATURE_XSAVE)); + } +@@ -6154,6 +6157,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct + int pending_vec, max_bits, idx; + struct desc_ptr dt; + ++ if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) ++ return -EINVAL; ++ + dt.size = sregs->idt.limit; + dt.address = sregs->idt.base; + kvm_x86_ops->set_idt(vcpu, &dt); diff --git a/debian/patches/series b/debian/patches/series index 3a91253f2..a9422d966 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -422,3 +422,4 @@ bugfix/all/firmware_class-log-every-success-and-failure.patch bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch bugfix/x86/ACPI-video-ignore-BIOS-initial-backlight-value-for-H.patch +bugfix/x86/KVM-x86-invalid-opcode-oops-on-SET_SREGS-with-OSXSAV.patch