• N
    KVM: x86: Check non-canonical addresses upon WRMSR · 854e8bb1
    Nadav Amit 提交于
    Upon WRMSR, the CPU should inject #GP if a non-canonical value (address) is
    written to certain MSRs. The behavior is "almost" identical for AMD and Intel
    (ignoring MSRs that are not implemented in either architecture since they would
    anyhow #GP). However, IA32_SYSENTER_ESP and IA32_SYSENTER_EIP cause #GP if
    non-canonical address is written on Intel but not on AMD (which ignores the top
    32-bits).
    
    Accordingly, this patch injects a #GP on the MSRs which behave identically on
    Intel and AMD.  To eliminate the differences between the architecutres, the
    value which is written to IA32_SYSENTER_ESP and IA32_SYSENTER_EIP is turned to
    canonical value before writing instead of injecting a #GP.
    
    Some references from Intel and AMD manuals:
    
    According to Intel SDM description of WRMSR instruction #GP is expected on
    WRMSR "If the source register contains a non-canonical address and ECX
    specifies one of the following MSRs: IA32_DS_AREA, IA32_FS_BASE, IA32_GS_BASE,
    IA32_KERNEL_GS_BASE, IA32_LSTAR, IA32_SYSENTER_EIP, IA32_SYSENTER_ESP."
    
    According to AMD manual instruction manual:
    LSTAR/CSTAR (SYSCALL): "The WRMSR instruction loads the target RIP into the
    LSTAR and CSTAR registers.  If an RIP written by WRMSR is not in canonical
    form, a general-protection exception (#GP) occurs."
    IA32_GS_BASE and IA32_FS_BASE (WRFSBASE/WRGSBASE): "The address written to the
    base field must be in canonical form or a #GP fault will occur."
    IA32_KERNEL_GS_BASE (SWAPGS): "The address stored in the KernelGSbase MSR must
    be in canonical form."
    
    This patch fixes CVE-2014-3610.
    
    Cc: stable@vger.kernel.org
    Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
    Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
    854e8bb1
svm.c 113.2 KB