48 lines
1.7 KiB
Diff
48 lines
1.7 KiB
Diff
|
References: bsc#995792 CVE-2016-7094 XSA-187
|
||
|
|
||
|
# Commit a9f3b3bad17d91e2067fc00d51b0302349570d08
|
||
|
# Date 2016-09-08 14:16:26 +0200
|
||
|
# Author Andrew Cooper <andrew.cooper3@citrix.com>
|
||
|
# Committer Jan Beulich <jbeulich@suse.com>
|
||
|
x86/shadow: Avoid overflowing sh_ctxt->seg_reg[]
|
||
|
|
||
|
hvm_get_seg_reg() does not perform a range check on its input segment, calls
|
||
|
hvm_get_segment_register() and writes straight into sh_ctxt->seg_reg[].
|
||
|
|
||
|
x86_seg_none is outside the bounds of sh_ctxt->seg_reg[], and will hit a BUG()
|
||
|
in {vmx,svm}_get_segment_register().
|
||
|
|
||
|
HVM guests running with shadow paging can end up performing a virtual to
|
||
|
linear translation with x86_seg_none. This is used for addresses which are
|
||
|
already linear. However, none of this is a legitimate pagetable update, so
|
||
|
fail the emulation in such a case.
|
||
|
|
||
|
This is XSA-187 / CVE-2016-7094.
|
||
|
|
||
|
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||
|
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||
|
Reviewed-by: Tim Deegan <tim@xen.org>
|
||
|
|
||
|
--- a/xen/arch/x86/mm/shadow/common.c
|
||
|
+++ b/xen/arch/x86/mm/shadow/common.c
|
||
|
@@ -140,9 +140,18 @@ static int hvm_translate_linear_addr(
|
||
|
struct sh_emulate_ctxt *sh_ctxt,
|
||
|
unsigned long *paddr)
|
||
|
{
|
||
|
- struct segment_register *reg = hvm_get_seg_reg(seg, sh_ctxt);
|
||
|
+ struct segment_register *reg;
|
||
|
int okay;
|
||
|
|
||
|
+ /*
|
||
|
+ * Can arrive here with non-user segments. However, no such cirucmstance
|
||
|
+ * is part of a legitimate pagetable update, so fail the emulation.
|
||
|
+ */
|
||
|
+ if ( !is_x86_user_segment(seg) )
|
||
|
+ return X86EMUL_UNHANDLEABLE;
|
||
|
+
|
||
|
+ reg = hvm_get_seg_reg(seg, sh_ctxt);
|
||
|
+
|
||
|
okay = hvm_virtual_to_linear_addr(
|
||
|
seg, reg, offset, bytes, access_type, sh_ctxt->ctxt.addr_size, paddr);
|
||
|
|