$NetBSD: patch-CVE-2015-5307,v 1.1 2016/01/07 17:53:58 bouyer Exp $ Patch for CVE-2015-5307 and CVE-2015-8104 aka XSA-156, based on http://xenbits.xenproject.org/xsa/xsa156-4.3.patch --- xen/arch/x86/hvm/svm/svm.c.orig 2014-09-02 08:22:57.000000000 +0200 +++ xen/arch/x86/hvm/svm/svm.c 2016-01-07 14:30:34.000000000 +0100 @@ -942,10 +942,11 @@ unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) ) { uint32_t intercepts = vmcb_get_exception_intercepts(vmcb); - uint32_t mask = (1U << TRAP_debug) | (1U << TRAP_int3); + v->arch.hvm_vcpu.debug_state_latch = debug_state; vmcb_set_exception_intercepts( - vmcb, debug_state ? (intercepts | mask) : (intercepts & ~mask)); + vmcb, debug_state ? (intercepts | (1U << TRAP_int3)) + : (intercepts & ~(1U << TRAP_int3))); } if ( v->arch.hvm_svm.launch_core != smp_processor_id() ) @@ -2232,8 +2233,9 @@ case VMEXIT_EXCEPTION_DB: if ( !v->domain->debugger_attached ) - goto exit_and_crash; - domain_pause_for_debugger(); + hvm_inject_hw_exception(TRAP_debug, HVM_DELIVER_NO_ERROR_CODE); + else + domain_pause_for_debugger(); break; case VMEXIT_EXCEPTION_BP: @@ -2281,6 +2283,11 @@ break; } + case VMEXIT_EXCEPTION_AC: + HVMTRACE_1D(TRAP, TRAP_alignment_check); + hvm_inject_hw_exception(TRAP_alignment_check, vmcb->exitinfo1); + break; + case VMEXIT_EXCEPTION_UD: svm_vmexit_ud_intercept(regs); break; --- xen/arch/x86/hvm/vmx/vmx.c.orig +++ xen/arch/x86/hvm/vmx/vmx.c @@ -1122,18 +1122,12 @@ static void vmx_update_host_cr3(struct v void vmx_update_debug_state(struct vcpu *v) { - unsigned long mask; - ASSERT(v == current); - mask = 1u << TRAP_int3; - if ( !cpu_has_monitor_trap_flag ) - mask |= 1u << TRAP_debug; - if ( v->arch.hvm_vcpu.debug_state_latch ) - v->arch.hvm_vmx.exception_bitmap |= mask; + v->arch.hvm_vmx.exception_bitmap |= 1U << TRAP_int3; else - v->arch.hvm_vmx.exception_bitmap &= ~mask; + v->arch.hvm_vmx.exception_bitmap &= ~(1U << TRAP_int3); vmx_update_exception_bitmap(v); } @@ -2616,9 +2610,10 @@ void vmx_vmexit_handler(struct cpu_user_ exit_qualification = __vmread(EXIT_QUALIFICATION); HVMTRACE_1D(TRAP_DEBUG, exit_qualification); write_debugreg(6, exit_qualification | 0xffff0ff0); - if ( !v->domain->debugger_attached || cpu_has_monitor_trap_flag ) - goto exit_and_crash; - domain_pause_for_debugger(); + if ( !v->domain->debugger_attached ) + hvm_inject_hw_exception(vector, HVM_DELIVER_NO_ERROR_CODE); + else + domain_pause_for_debugger(); break; case TRAP_int3: { @@ -2679,6 +2674,11 @@ void vmx_vmexit_handler(struct cpu_user_ hvm_inject_page_fault(regs->error_code, exit_qualification); break; + case TRAP_alignment_check: + HVMTRACE_1D(TRAP, vector); + hvm_inject_hw_exception(vector, + __vmread(VM_EXIT_INTR_ERROR_CODE)); + break; case TRAP_nmi: if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) != (X86_EVENTTYPE_NMI << 8) ) --- xen/include/asm-x86/hvm/hvm.h.orig +++ xen/include/asm-x86/hvm/hvm.h @@ -389,7 +389,10 @@ static inline bool_t hvm_vcpu_has_smep(v }) /* These exceptions must always be intercepted. */ -#define HVM_TRAP_MASK ((1U << TRAP_machine_check) | (1U << TRAP_invalid_op)) +#define HVM_TRAP_MASK ((1U << TRAP_debug) | \ + (1U << TRAP_invalid_op) | \ + (1U << TRAP_alignment_check) | \ + (1U << TRAP_machine_check)) /* * x86 event types. This enumeration is valid for: