diff options
Diffstat (limited to 'main/xen/xsa186-0001-x86-emulate-Correct-boundary-interactions-of-emulate.patch')
-rw-r--r-- | main/xen/xsa186-0001-x86-emulate-Correct-boundary-interactions-of-emulate.patch | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/main/xen/xsa186-0001-x86-emulate-Correct-boundary-interactions-of-emulate.patch b/main/xen/xsa186-0001-x86-emulate-Correct-boundary-interactions-of-emulate.patch new file mode 100644 index 0000000000..b257497085 --- /dev/null +++ b/main/xen/xsa186-0001-x86-emulate-Correct-boundary-interactions-of-emulate.patch @@ -0,0 +1,73 @@ +From e938be013ba73ff08fa4f1d8670501aacefde7fb Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Fri, 22 Jul 2016 16:02:54 +0000 +Subject: [PATCH 1/2] x86/emulate: Correct boundary interactions of emulated + instructions + +This reverts most of c/s 0640ffb6 "x86emul: fix rIP handling". + +Experimentally, in long mode processors will execute an instruction stream +which crosses the 64bit -1 -> 0 virtual boundary, whether the instruction +boundary is aligned on the virtual boundary, or is misaligned. + +In compatibility mode, Intel processors will execute an instruction stream +which crosses the 32bit -1 -> 0 virtual boundary, while AMD processors raise a +segmentation fault. Xen's segmentation behaviour matches AMD. + +For 16bit code, hardware does not ever truncated %ip. %eip is always used and +behaves normally as a 32bit register, including in 16bit protected mode +segments, as well as in Real and Unreal mode. + +This is XSA-186 + +Reported-by: Brian Marcotte <marcotte@panix.com> +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +--- + xen/arch/x86/x86_emulate/x86_emulate.c | 22 ++++------------------ + 1 file changed, 4 insertions(+), 18 deletions(-) + +diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c +index d5a56cf..bf3529a 100644 +--- a/xen/arch/x86/x86_emulate/x86_emulate.c ++++ b/xen/arch/x86/x86_emulate/x86_emulate.c +@@ -1570,10 +1570,6 @@ x86_emulate( + #endif + } + +- /* Truncate rIP to def_ad_bytes (2 or 4) if necessary. */ +- if ( def_ad_bytes < sizeof(_regs.eip) ) +- _regs.eip &= (1UL << (def_ad_bytes * 8)) - 1; +- + /* Prefix bytes. */ + for ( ; ; ) + { +@@ -3906,21 +3902,11 @@ x86_emulate( + + /* Commit shadow register state. */ + _regs.eflags &= ~EFLG_RF; +- switch ( __builtin_expect(def_ad_bytes, sizeof(_regs.eip)) ) +- { +- uint16_t ip; + +- case 2: +- ip = _regs.eip; +- _regs.eip = ctxt->regs->eip; +- *(uint16_t *)&_regs.eip = ip; +- break; +-#ifdef __x86_64__ +- case 4: +- _regs.rip = _regs._eip; +- break; +-#endif +- } ++ /* Zero the upper 32 bits of %rip if not in long mode. */ ++ if ( def_ad_bytes < sizeof(_regs.eip) ) ++ _regs.eip = (uint32_t)_regs.eip; ++ + *ctxt->regs = _regs; + + done: +-- +2.1.4 + |