lkml.org 
[lkml]   [2017]   [Sep]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 024/233] KVM: x86: Fix load damaged SSEx MXCSR register
    3.16.48-rc1 review patch.  If anyone has any objections, please let me know.

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

    From: Wanpeng Li <wanpeng.li@hotmail.com>

    commit a575813bfe4bc15aba511a5e91e61d242bff8b9d upstream.

    Reported by syzkaller:

    BUG: unable to handle kernel paging request at ffffffffc07f6a2e
    IP: report_bug+0x94/0x120
    PGD 348e12067
    P4D 348e12067
    PUD 348e14067
    PMD 3cbd84067
    PTE 80000003f7e87161

    Oops: 0003 [#1] SMP
    CPU: 2 PID: 7091 Comm: kvm_load_guest_ Tainted: G OE 4.11.0+ #8
    task: ffff92fdfb525400 task.stack: ffffbda6c3d04000
    RIP: 0010:report_bug+0x94/0x120
    RSP: 0018:ffffbda6c3d07b20 EFLAGS: 00010202
    do_trap+0x156/0x170
    do_error_trap+0xa3/0x170
    ? kvm_load_guest_fpu.part.175+0x12a/0x170 [kvm]
    ? mark_held_locks+0x79/0xa0
    ? retint_kernel+0x10/0x10
    ? trace_hardirqs_off_thunk+0x1a/0x1c
    do_invalid_op+0x20/0x30
    invalid_op+0x1e/0x30
    RIP: 0010:kvm_load_guest_fpu.part.175+0x12a/0x170 [kvm]
    ? kvm_load_guest_fpu.part.175+0x1c/0x170 [kvm]
    kvm_arch_vcpu_ioctl_run+0xed6/0x1b70 [kvm]
    kvm_vcpu_ioctl+0x384/0x780 [kvm]
    ? kvm_vcpu_ioctl+0x384/0x780 [kvm]
    ? sched_clock+0x13/0x20
    ? __do_page_fault+0x2a0/0x550
    do_vfs_ioctl+0xa4/0x700
    ? up_read+0x1f/0x40
    ? __do_page_fault+0x2a0/0x550
    SyS_ioctl+0x79/0x90
    entry_SYSCALL_64_fastpath+0x23/0xc2

    SDM mentioned that "The MXCSR has several reserved bits, and attempting to write
    a 1 to any of these bits will cause a general-protection exception(#GP) to be
    generated". The syzkaller forks' testcase overrides xsave area w/ random values
    and steps on the reserved bits of MXCSR register. The damaged MXCSR register
    values of guest will be restored to SSEx MXCSR register before vmentry. This
    patch fixes it by catching userspace override MXCSR register reserved bits w/
    random values and bails out immediately.

    Reported-by: Andrey Konovalov <andreyknvl@google.com>
    Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Radim Krčmář <rkrcmar@redhat.com>
    Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
    Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
    [bwh: Backported to 3.16: adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    arch/x86/kernel/i387.c | 1 +
    arch/x86/kvm/x86.c | 9 +++++++--
    2 files changed, 8 insertions(+), 2 deletions(-)

    --- a/arch/x86/kernel/i387.c
    +++ b/arch/x86/kernel/i387.c
    @@ -115,6 +115,7 @@ void unlazy_fpu(struct task_struct *tsk)
    EXPORT_SYMBOL(unlazy_fpu);

    unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
    +EXPORT_SYMBOL_GPL(mxcsr_feature_mask);
    unsigned int xstate_size;
    EXPORT_SYMBOL_GPL(xstate_size);
    static struct i387_fxsave_struct fx_scratch;
    --- a/arch/x86/kvm/x86.c
    +++ b/arch/x86/kvm/x86.c
    @@ -3110,11 +3110,14 @@ static void kvm_vcpu_ioctl_x86_get_xsave
    }
    }

    +#define XSAVE_MXCSR_OFFSET 24
    +
    static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
    struct kvm_xsave *guest_xsave)
    {
    u64 xstate_bv =
    *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)];
    + u32 mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)];

    if (cpu_has_xsave) {
    /*
    @@ -3122,12 +3125,14 @@ static int kvm_vcpu_ioctl_x86_set_xsave(
    * CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility
    * with old userspace.
    */
    - if (xstate_bv & ~kvm_supported_xcr0())
    + if (xstate_bv & ~kvm_supported_xcr0() ||
    + mxcsr & ~mxcsr_feature_mask)
    return -EINVAL;
    memcpy(&vcpu->arch.guest_fpu.state->xsave,
    guest_xsave->region, vcpu->arch.guest_xstate_size);
    } else {
    - if (xstate_bv & ~XSTATE_FPSSE)
    + if (xstate_bv & ~XSTATE_FPSSE ||
    + mxcsr & ~mxcsr_feature_mask)
    return -EINVAL;
    memcpy(&vcpu->arch.guest_fpu.state->fxsave,
    guest_xsave->region, sizeof(struct i387_fxsave_struct));
    \
     
     \ /
      Last update: 2017-09-10 01:30    [W:2.249 / U:0.280 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site