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>
master commit: a9f3b3bad1
master date: 2016-09-08 14:16:26 +0200
This commit is contained in:
Andrew Cooper authored and Jan Beulich committed 2016-09-08 14:29:05 +02:00
1 parent bc9f72bb93
commit 433ebca120
1 file changed
+10 -1
+10 -1
View File
@@ -137,9 +137,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);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.