Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
xen.4698
58580060-x86-emul-correct-SYSCALL-eflags-handli...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 58580060-x86-emul-correct-SYSCALL-eflags-handling.patch of Package xen.4698
# Commit b9a8061bc28930b0c922a5d828447c52e4e873c2 # Date 2016-12-19 15:44:32 +0000 # Author Andrew Cooper <andrew.cooper3@citrix.com> # Committer Andrew Cooper <andrew.cooper3@citrix.com> x86/emul: Correct the handling of eflags with SYSCALL A singlestep #DB is determined by the resulting eflags value from the execution of SYSCALL, not the original eflags value. By using the original eflags value, we negate the guest kernels attempt to protect itself from a privilege escalation by masking TF. (re)introduce a singlestep boolean, defaulting to the original eflags state, but have the SYSCALL emulation recalculate it after masking has occurred. This is CVE-2016-10013 / XSA-204. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1441,6 +1441,7 @@ x86_emulate( union vex vex = {}; unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes; bool_t lock_prefix = 0; + bool_t tf = !!(ctxt->regs->eflags & EFLG_TF); int override_seg = -1, rc = X86EMUL_OKAY; struct operand src = { .reg = REG_POISON }; struct operand dst = { .reg = REG_POISON }; @@ -3778,9 +3779,8 @@ x86_emulate( break; } - /* Inject #DB if single-step tracing was enabled at instruction start. */ - if ( (ctxt->regs->eflags & EFLG_TF) && (rc == X86EMUL_OKAY) && - (ops->inject_hw_exception != NULL) ) + /* Should a singlestep #DB be raised? */ + if ( tf && (rc == X86EMUL_OKAY) && (ops->inject_hw_exception != NULL) ) rc = ops->inject_hw_exception(EXC_DB, -1, ctxt) ? : X86EMUL_EXCEPTION; /* Commit shadow register state. */ @@ -3965,6 +3965,23 @@ x86_emulate( (rc = ops->write_segment(x86_seg_ss, &ss, ctxt)) ) goto done; + /* + * SYSCALL (unlike most instructions) evaluates its singlestep action + * based on the resulting EFLG_TF, not the starting EFLG_TF. + * + * As the #DB is raised after the CPL change and before the OS can + * switch stack, it is a large risk for privilege escalation. + * + * 64bit kernels should mask EFLG_TF in MSR_FMASK to avoid any + * vulnerability. Running the #DB handler on an IST stack is also a + * mitigation. + * + * 32bit kernels have no ability to mask EFLG_TF at all. Their only + * mitigation is to use a task gate for handling #DB (or to not use + * enable EFER.SCE to start with). + */ + tf = !!(_regs.eflags & EFLG_TF); + break; }
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