$NetBSD: patch-CVE-2013-4355_1,v 1.5 2014/10/01 17:18:22 drochner Exp $ http://lists.xenproject.org/archives/html/xen-devel/2013-09/msg03160.html also fixes http://lists.xenproject.org/archives/html/xen-devel/2013-11/msg03827.html (CVE-2013-4554) also fixes http://lists.xenproject.org/archives/html/xen-devel/2014-03/msg03177.html (CVE-2014-2599) also fixes http://lists.xenproject.org/archives/html/xen-devel/2014-04/msg03853.html (CVE-2014-3124) also fixes http://lists.xenproject.org/archives/html/xen-devel/2014-10/msg00065.html (CVE-2014-7188) --- xen/arch/x86/hvm/hvm.c.orig 2013-09-10 06:42:18.000000000 +0000 +++ xen/arch/x86/hvm/hvm.c 2014-10-01 16:40:48.000000000 +0000 @@ -1961,11 +1961,7 @@ void hvm_task_switch( rc = hvm_copy_from_guest_virt( &tss, prev_tr.base, sizeof(tss), PFEC_page_present); - if ( rc == HVMCOPY_bad_gva_to_gfn ) - goto out; - if ( rc == HVMCOPY_gfn_paged_out ) - goto out; - if ( rc == HVMCOPY_gfn_shared ) + if ( rc != HVMCOPY_okay ) goto out; eflags = regs->eflags; @@ -2010,13 +2006,11 @@ void hvm_task_switch( rc = hvm_copy_from_guest_virt( &tss, tr.base, sizeof(tss), PFEC_page_present); - if ( rc == HVMCOPY_bad_gva_to_gfn ) - goto out; - if ( rc == HVMCOPY_gfn_paged_out ) - goto out; - /* Note: this could be optimised, if the callee functions knew we want RO - * access */ - if ( rc == HVMCOPY_gfn_shared ) + /* + * Note: The HVMCOPY_gfn_shared case could be optimised, if the callee + * functions knew we want RO access. + */ + if ( rc != HVMCOPY_okay ) goto out; @@ -2409,7 +2403,7 @@ int hvm_msr_read_intercept(unsigned int *msr_content = vcpu_vlapic(v)->hw.apic_base_msr; break; - case MSR_IA32_APICBASE_MSR ... MSR_IA32_APICBASE_MSR + 0x3ff: + case MSR_IA32_APICBASE_MSR ... MSR_IA32_APICBASE_MSR + 0xff: if ( hvm_x2apic_msr_read(v, msr, msr_content) ) goto gp_fault; break; @@ -2529,7 +2523,7 @@ int hvm_msr_write_intercept(unsigned int vlapic_tdt_msr_set(vcpu_vlapic(v), msr_content); break; - case MSR_IA32_APICBASE_MSR ... MSR_IA32_APICBASE_MSR + 0x3ff: + case MSR_IA32_APICBASE_MSR ... MSR_IA32_APICBASE_MSR + 0xff: if ( hvm_x2apic_msr_write(v, msr, msr_content) ) goto gp_fault; break; @@ -2834,7 +2828,7 @@ int hvm_do_hypercall(struct cpu_user_reg case 4: case 2: hvm_get_segment_register(curr, x86_seg_ss, &sreg); - if ( unlikely(sreg.attr.fields.dpl == 3) ) + if ( unlikely(sreg.attr.fields.dpl) ) { default: regs->eax = -EPERM; @@ -3657,13 +3651,9 @@ long do_hvm_op(unsigned long op, XEN_GUE rc = -EINVAL; goto param_fail4; } - if ( p2m_is_grant(t) ) - { - gdprintk(XENLOG_WARNING, - "type for pfn 0x%lx changed to grant while " - "we were working?\n", pfn); + if ( !p2m_is_ram(t) && + (!p2m_is_hole(t) || a.hvmmem_type != HVMMEM_mmio_dm) ) goto param_fail4; - } else { nt = p2m_change_type(p2m, pfn, t, memtype[a.hvmmem_type]); @@ -3746,7 +3736,7 @@ long do_hvm_op(unsigned long op, XEN_GUE ((a.first_pfn + a.nr - 1) > domain_get_maximum_gpfn(d)) ) goto param_fail5; - for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ ) + for ( pfn = a.first_pfn; a.nr; ++pfn ) { p2m_type_t t; mfn_t mfn; @@ -3759,6 +3749,17 @@ long do_hvm_op(unsigned long op, XEN_GUE p2m_unlock(p2m); if ( !success ) goto param_fail5; + + /* Check for continuation if it's not the last interation. */ + if ( --a.nr && hypercall_preempt_check() ) + { + a.first_pfn = pfn + 1; + if ( copy_to_guest(arg, &a, 1) ) + rc = -EFAULT; + else + rc = -EAGAIN; + goto param_fail5; + } } rc = 0;