lkml.org 
[lkml]   [2012]   [Nov]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 40/54] KVM: x86: invalid opcode oops on SET_SREGS with OSXSAVE bit set (CVE-2012-4461)
    Date
    3.6-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Petr Matousek <pmatouse@redhat.com>

    commit 6d1068b3a98519247d8ba4ec85cd40ac136dbdf9 upstream.

    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:[<f8b9550c>] 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:
    [<f8b940a9>] ? kvm_arch_vcpu_ioctl_set_sregs+0x2fe/0x308 [kvm]
    ...
    [<c12bfb44>] ? 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: [<f8b9550c>] 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 <pmatouse@redhat.com>
    Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/kvm/cpuid.h | 3 +++
    arch/x86/kvm/x86.c | 3 +++
    2 files changed, 6 insertions(+)

    --- a/arch/x86/kvm/cpuid.h
    +++ b/arch/x86/kvm/cpuid.h
    @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave
    {
    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));
    }
    --- a/arch/x86/kvm/x86.c
    +++ b/arch/x86/kvm/x86.c
    @@ -5762,6 +5762,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);



    \
     
     \ /
      Last update: 2012-12-01 04:21    [W:4.186 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site