Nadav Amit 854e8bb1aa KVM: x86: Check non-canonical addresses upon WRMSR
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: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-10-24 13:21:08 +02:00
..
2014-08-26 13:45:50 -04:00
2012-03-28 18:11:12 +01:00
2014-08-26 13:45:49 -04:00
2011-05-02 17:24:48 +02:00
2014-05-02 11:34:17 -07:00
2012-03-28 18:11:12 +01:00
2014-03-04 21:47:51 +01:00
2011-04-18 09:26:48 -07:00
2012-03-20 21:48:30 +08:00
2014-05-08 08:15:34 +02:00
2013-08-05 06:35:33 -07:00
2013-02-03 18:16:27 -05:00
2014-04-07 16:36:15 -07:00
2010-10-26 16:52:08 -07:00
2012-06-25 13:48:30 +02:00
2014-09-22 13:35:52 +02:00
2011-07-22 14:39:50 +09:30
2013-04-22 15:45:03 +09:30
2014-02-27 08:07:39 -08:00
2014-09-01 10:15:31 +02:00
2014-04-07 16:36:13 -07:00
2011-03-15 15:34:15 -07:00
2012-02-20 12:52:05 -08:00
2014-06-06 16:08:11 -07:00
2014-06-04 16:53:57 -07:00
2014-04-18 14:20:46 +02:00
2012-03-28 18:11:12 +01:00