Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
xen.5575
58343f29-x86-emul-correct-the-IDT-entry-calcula...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 58343f29-x86-emul-correct-the-IDT-entry-calculation-in-inject_swint.patch of Package xen.5575
Subject: x86/emul: correct the IDT entry calculation in inject_swint() From: Andrew Cooper andrew.cooper3@citrix.com Tue Nov 22 14:29:26 2016 +0100 Date: Tue Nov 22 14:29:26 2016 +0100: Git: 34fbae790c98966903d7f97c6f46622ea842ab55 The logic, as introduced in c/s 36ebf14ebe "x86/emulate: support for emulating software event injection" is buggy. The size of an IDT entry depends on long mode being active, not the width of the code segment currently in use. In particular, this means that a compatibility code segment which hits emulation for software event injection will end up using an incorrect offset in the IDT for DPL/Presence checking. In practice, this only occurs on old AMD hardware lacking NRip support; all newer AMD hardware, and all Intel hardware bypass this path in the emulator. While here, fix a minor issue with reading the IDT entry. The return value from ops->read() wasn't checked, but in reality the only failure case is if a pagefault occurs. This is not a realistic problem as the kernel will almost certainly crash with a double fault if this setup actually occured. This is CVE-2016-9377 / part of XSA-196. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> master commit: 255e8fe95f22ded5186fd75244ffcfb9d5dbc855 master date: 2016-11-22 13:50:49 +0100 Index: xen-4.5.5-testing/xen/arch/x86/x86_emulate/x86_emulate.c =================================================================== --- xen-4.5.5-testing.orig/xen/arch/x86/x86_emulate/x86_emulate.c +++ xen-4.5.5-testing/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1452,10 +1452,16 @@ static int inject_swint(enum x86_swint_t { if ( !in_realmode(ctxt, ops) ) { - unsigned int idte_size = (ctxt->addr_size == 64) ? 16 : 8; - unsigned int idte_offset = vector * idte_size; + unsigned int idte_size, idte_offset; struct segment_register idtr; uint32_t idte_ctl; + int lm = in_longmode(ctxt, ops); + + if ( lm < 0 ) + return X86EMUL_UNHANDLEABLE; + + idte_size = lm ? 16 : 8; + idte_offset = vector * idte_size; /* icebp sets the External Event bit despite being an instruction. */ error_code = (vector << 3) | ECODE_IDT | @@ -1483,8 +1489,9 @@ static int inject_swint(enum x86_swint_t * Should strictly speaking read all 8/16 bytes of an entry, * but we currently only care about the dpl and present bits. */ - ops->read(x86_seg_none, idtr.base + idte_offset + 4, - &idte_ctl, sizeof(idte_ctl), ctxt); + if ( (rc = ops->read(x86_seg_none, idtr.base + idte_offset + 4, + &idte_ctl, sizeof(idte_ctl), ctxt)) ) + goto done; /* Is this entry present? */ if ( !(idte_ctl & (1u << 15)) )
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor