Index: head/emulators/xen-kernel/Makefile =================================================================== --- head/emulators/xen-kernel/Makefile +++ head/emulators/xen-kernel/Makefile @@ -2,12 +2,11 @@ PORTNAME= xen PKGNAMESUFFIX= -kernel -PORTVERSION= 4.5.1 -PORTREVISION= 1 +PORTVERSION= 4.5.2 CATEGORIES= emulators MASTER_SITES= http://bits.xensource.com/oss-xen/release/${PORTVERSION}/ -MAINTAINER= ports@FreeBSD.org +MAINTAINER= royger@FreeBSD.org COMMENT= Hypervisor using a microkernel design LICENSE= GPLv2 @@ -31,12 +30,7 @@ ${FILESDIR}/0005-x86-rework-paging_log_dirty_op-to-work-with-hvm-gues.patch:-p2 \ ${FILESDIR}/0006-xen-pvh-enable-mmu_update-hypercall.patch:-p2 \ ${FILESDIR}/0007-iommu-fix-usage-of-shared-EPT-IOMMU-page-tables-on-P.patch:-p2 \ - ${FILESDIR}/0008-xen-arm-mm-Do-not-dump-the-p2m-when-mapping-a-foreig.patch:-p2 \ - ${FILESDIR}/xsa148-4.5.patch:-p2 \ - ${FILESDIR}/xsa149.patch:-p2 \ - ${FILESDIR}/xsa150.patch:-p2 \ - ${FILESDIR}/xsa151.patch:-p2 \ - ${FILESDIR}/xsa152-4.5.patch:-p2 + ${FILESDIR}/xsa156-4.5.patch:-p2 .include Index: head/emulators/xen-kernel/distinfo =================================================================== --- head/emulators/xen-kernel/distinfo +++ head/emulators/xen-kernel/distinfo @@ -1,2 +1,2 @@ -SHA256 (xen-4.5.1.tar.gz) = 668c11d4fca67ac44329e369f810356eacd37b28d28fb96e66aac77f3c5e1371 -SIZE (xen-4.5.1.tar.gz) = 18410400 +SHA256 (xen-4.5.2.tar.gz) = 4c9e5dac4eea484974e9f76da2756c8e0973b4e884d28d37e955df9ebf00e7e8 +SIZE (xen-4.5.2.tar.gz) = 18416220 Index: head/emulators/xen-kernel/files/0008-xen-arm-mm-Do-not-dump-the-p2m-when-mapping-a-foreig.patch =================================================================== --- head/emulators/xen-kernel/files/0008-xen-arm-mm-Do-not-dump-the-p2m-when-mapping-a-foreig.patch +++ head/emulators/xen-kernel/files/0008-xen-arm-mm-Do-not-dump-the-p2m-when-mapping-a-foreig.patch @@ -1,39 +0,0 @@ -From 403805aca7a4a508cf193d63aa525b3a76bb09dd Mon Sep 17 00:00:00 2001 -From: Julien Grall -Date: Fri, 9 Oct 2015 13:00:35 +0200 -Subject: [PATCH 8/8] xen/arm: mm: Do not dump the p2m when mapping a foreign - gfn - -The physmap operation XENMAPSPACE_gfmn_foreign is dumping the p2m when -an error occured by calling dump_p2m_lookup. But this function is not -using ratelimited printk. - -Any domain able to map foreign gfmn would be able to flood the Xen -console. - -The information wasn't not useful so drop it. - -This is XSA-141. - -Signed-off-by: Julien Grall -Acked-by: Ian Campbell -(cherry picked from commit afc13fe5e21d18c09e44f8ae6f7f4484e9f1de7f) ---- - xen/arch/arm/mm.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c -index 7d4ba0c..7d95961 100644 ---- a/xen/arch/arm/mm.c -+++ b/xen/arch/arm/mm.c -@@ -1103,7 +1103,6 @@ int xenmem_add_to_physmap_one( - page = get_page_from_gfn(od, idx, &p2mt, P2M_ALLOC); - if ( !page ) - { -- dump_p2m_lookup(od, pfn_to_paddr(idx)); - rcu_unlock_domain(od); - return -EINVAL; - } --- -1.9.5 (Apple Git-50.3) - Index: head/emulators/xen-kernel/files/xsa148-4.5.patch =================================================================== --- head/emulators/xen-kernel/files/xsa148-4.5.patch +++ head/emulators/xen-kernel/files/xsa148-4.5.patch @@ -1,39 +0,0 @@ -x86: guard against undue super page PTE creation - -When optional super page support got added (commit bd1cd81d64 "x86: PV -support for hugepages"), two adjustments were missed: mod_l2_entry() -needs to consider the PSE and RW bits when deciding whether to use the -fast path, and the PSE bit must not be removed from L2_DISALLOW_MASK -unconditionally. - -This is XSA-148. - -Signed-off-by: Jan Beulich -Reviewed-by: Tim Deegan - ---- a/xen/arch/x86/mm.c -+++ b/xen/arch/x86/mm.c -@@ -162,7 +162,10 @@ static void put_superpage(unsigned long - static uint32_t base_disallow_mask; - /* Global bit is allowed to be set on L1 PTEs. Intended for user mappings. */ - #define L1_DISALLOW_MASK ((base_disallow_mask | _PAGE_GNTTAB) & ~_PAGE_GLOBAL) --#define L2_DISALLOW_MASK (base_disallow_mask & ~_PAGE_PSE) -+ -+#define L2_DISALLOW_MASK (unlikely(opt_allow_superpage) \ -+ ? base_disallow_mask & ~_PAGE_PSE \ -+ : base_disallow_mask) - - #define l3_disallow_mask(d) (!is_pv_32on64_domain(d) ? \ - base_disallow_mask : \ -@@ -1770,7 +1773,10 @@ static int mod_l2_entry(l2_pgentry_t *pl - } - - /* Fast path for identical mapping and presence. */ -- if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT) ) -+ if ( !l2e_has_changed(ol2e, nl2e, -+ unlikely(opt_allow_superpage) -+ ? _PAGE_PSE | _PAGE_RW | _PAGE_PRESENT -+ : _PAGE_PRESENT) ) - { - adjust_guest_l2e(nl2e, d); - if ( UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu, preserve_ad) ) Index: head/emulators/xen-kernel/files/xsa149.patch =================================================================== --- head/emulators/xen-kernel/files/xsa149.patch +++ head/emulators/xen-kernel/files/xsa149.patch @@ -1,20 +0,0 @@ -xen: free domain's vcpu array - -This was overlooked in fb442e2171 ("x86_64: allow more vCPU-s per -guest"). - -This is XSA-149. - -Signed-off-by: Jan Beulich -Reviewed-by: Ian Campbell - ---- a/xen/common/domain.c -+++ b/xen/common/domain.c -@@ -841,6 +841,7 @@ static void complete_domain_destroy(stru - - xsm_free_security_domain(d); - free_cpumask_var(d->domain_dirty_cpumask); -+ xfree(d->vcpu); - free_domain_struct(d); - - send_global_virq(VIRQ_DOM_EXC); Index: head/emulators/xen-kernel/files/xsa150.patch =================================================================== --- head/emulators/xen-kernel/files/xsa150.patch +++ head/emulators/xen-kernel/files/xsa150.patch @@ -1,201 +0,0 @@ -x86/PoD: Eager sweep for zeroed pages - -Based on the contents of a guests physical address space, -p2m_pod_emergency_sweep() could degrade into a linear memcmp() from 0 to -max_gfn, which runs non-preemptibly. - -As p2m_pod_emergency_sweep() runs behind the scenes in a number of contexts, -making it preemptible is not feasible. - -Instead, a different approach is taken. Recently-populated pages are eagerly -checked for reclaimation, which amortises the p2m_pod_emergency_sweep() -operation across each p2m_pod_demand_populate() operation. - -Note that in the case that a 2M superpage can't be reclaimed as a superpage, -it is shattered if 4K pages of zeros can be reclaimed. This is unfortunate -but matches the previous behaviour, and is required to avoid regressions -(domain crash from PoD exhaustion) with VMs configured close to the limit. - -This is CVE-2015-7970 / XSA-150. - -Signed-off-by: Andrew Cooper -Reviewed-by: Jan Beulich -Reviewed-by: George Dunlap - ---- a/xen/arch/x86/mm/p2m-pod.c -+++ b/xen/arch/x86/mm/p2m-pod.c -@@ -920,28 +920,6 @@ p2m_pod_zero_check(struct p2m_domain *p2 - } - - #define POD_SWEEP_LIMIT 1024 -- --/* When populating a new superpage, look at recently populated superpages -- * hoping that they've been zeroed. This will snap up zeroed pages as soon as -- * the guest OS is done with them. */ --static void --p2m_pod_check_last_super(struct p2m_domain *p2m, unsigned long gfn_aligned) --{ -- unsigned long check_gfn; -- -- ASSERT(p2m->pod.last_populated_index < POD_HISTORY_MAX); -- -- check_gfn = p2m->pod.last_populated[p2m->pod.last_populated_index]; -- -- p2m->pod.last_populated[p2m->pod.last_populated_index] = gfn_aligned; -- -- p2m->pod.last_populated_index = -- ( p2m->pod.last_populated_index + 1 ) % POD_HISTORY_MAX; -- -- p2m_pod_zero_check_superpage(p2m, check_gfn); --} -- -- - #define POD_SWEEP_STRIDE 16 - static void - p2m_pod_emergency_sweep(struct p2m_domain *p2m) -@@ -982,7 +960,7 @@ p2m_pod_emergency_sweep(struct p2m_domai - * NB that this is a zero-sum game; we're increasing our cache size - * by re-increasing our 'debt'. Since we hold the pod lock, - * (entry_count - count) must remain the same. */ -- if ( p2m->pod.count > 0 && i < limit ) -+ if ( i < limit && (p2m->pod.count > 0 || hypercall_preempt_check()) ) - break; - } - -@@ -994,6 +972,58 @@ p2m_pod_emergency_sweep(struct p2m_domai - - } - -+static void pod_eager_reclaim(struct p2m_domain *p2m) -+{ -+ struct pod_mrp_list *mrp = &p2m->pod.mrp; -+ unsigned int i = 0; -+ -+ /* -+ * Always check one page for reclaimation. -+ * -+ * If the PoD pool is empty, keep checking some space is found, or all -+ * entries have been exhaused. -+ */ -+ do -+ { -+ unsigned int idx = (mrp->idx + i++) % ARRAY_SIZE(mrp->list); -+ unsigned long gfn = mrp->list[idx]; -+ -+ if ( gfn != INVALID_GFN ) -+ { -+ if ( gfn & POD_LAST_SUPERPAGE ) -+ { -+ gfn &= ~POD_LAST_SUPERPAGE; -+ -+ if ( p2m_pod_zero_check_superpage(p2m, gfn) == 0 ) -+ { -+ unsigned int x; -+ -+ for ( x = 0; x < SUPERPAGE_PAGES; ++x, ++gfn ) -+ p2m_pod_zero_check(p2m, &gfn, 1); -+ } -+ } -+ else -+ p2m_pod_zero_check(p2m, &gfn, 1); -+ -+ mrp->list[idx] = INVALID_GFN; -+ } -+ -+ } while ( (p2m->pod.count == 0) && (i < ARRAY_SIZE(mrp->list)) ); -+} -+ -+static void pod_eager_record(struct p2m_domain *p2m, -+ unsigned long gfn, unsigned int order) -+{ -+ struct pod_mrp_list *mrp = &p2m->pod.mrp; -+ -+ ASSERT(mrp->list[mrp->idx] == INVALID_GFN); -+ ASSERT(gfn != INVALID_GFN); -+ -+ mrp->list[mrp->idx++] = -+ gfn | (order == PAGE_ORDER_2M ? POD_LAST_SUPERPAGE : 0); -+ mrp->idx %= ARRAY_SIZE(mrp->list); -+} -+ - int - p2m_pod_demand_populate(struct p2m_domain *p2m, unsigned long gfn, - unsigned int order, -@@ -1034,6 +1064,8 @@ p2m_pod_demand_populate(struct p2m_domai - return 0; - } - -+ pod_eager_reclaim(p2m); -+ - /* Only sweep if we're actually out of memory. Doing anything else - * causes unnecessary time and fragmentation of superpages in the p2m. */ - if ( p2m->pod.count == 0 ) -@@ -1070,6 +1102,8 @@ p2m_pod_demand_populate(struct p2m_domai - p2m->pod.entry_count -= (1 << order); - BUG_ON(p2m->pod.entry_count < 0); - -+ pod_eager_record(p2m, gfn_aligned, order); -+ - if ( tb_init_done ) - { - struct { -@@ -1085,12 +1119,6 @@ p2m_pod_demand_populate(struct p2m_domai - __trace_var(TRC_MEM_POD_POPULATE, 0, sizeof(t), &t); - } - -- /* Check the last guest demand-populate */ -- if ( p2m->pod.entry_count > p2m->pod.count -- && (order == PAGE_ORDER_2M) -- && (q & P2M_ALLOC) ) -- p2m_pod_check_last_super(p2m, gfn_aligned); -- - pod_unlock(p2m); - return 0; - out_of_memory: ---- a/xen/arch/x86/mm/p2m.c -+++ b/xen/arch/x86/mm/p2m.c -@@ -58,6 +58,7 @@ boolean_param("hap_2mb", opt_hap_2mb); - /* Init the datastructures for later use by the p2m code */ - static int p2m_initialise(struct domain *d, struct p2m_domain *p2m) - { -+ unsigned int i; - int ret = 0; - - mm_rwlock_init(&p2m->lock); -@@ -73,6 +74,9 @@ static int p2m_initialise(struct domain - - p2m->np2m_base = P2M_BASE_EADDR; - -+ for ( i = 0; i < ARRAY_SIZE(p2m->pod.mrp.list); ++i ) -+ p2m->pod.mrp.list[i] = INVALID_GFN; -+ - if ( hap_enabled(d) && cpu_has_vmx ) - ret = ept_p2m_init(p2m); - else ---- a/xen/include/asm-x86/p2m.h -+++ b/xen/include/asm-x86/p2m.h -@@ -292,10 +292,20 @@ struct p2m_domain { - entry_count; /* # of pages in p2m marked pod */ - unsigned long reclaim_single; /* Last gpfn of a scan */ - unsigned long max_guest; /* gpfn of max guest demand-populate */ --#define POD_HISTORY_MAX 128 -- /* gpfn of last guest superpage demand-populated */ -- unsigned long last_populated[POD_HISTORY_MAX]; -- unsigned int last_populated_index; -+ -+ /* -+ * Tracking of the most recently populated PoD pages, for eager -+ * reclamation. -+ */ -+ struct pod_mrp_list { -+#define NR_POD_MRP_ENTRIES 32 -+ -+/* Encode ORDER_2M superpage in top bit of GFN */ -+#define POD_LAST_SUPERPAGE (INVALID_GFN & ~(INVALID_GFN >> 1)) -+ -+ unsigned long list[NR_POD_MRP_ENTRIES]; -+ unsigned int idx; -+ } mrp; - mm_lock_t lock; /* Locking of private pod structs, * - * not relying on the p2m lock. */ - } pod; Index: head/emulators/xen-kernel/files/xsa151.patch =================================================================== --- head/emulators/xen-kernel/files/xsa151.patch +++ head/emulators/xen-kernel/files/xsa151.patch @@ -1,28 +0,0 @@ -xenoprof: free domain's vcpu array - -This was overlooked in fb442e2171 ("x86_64: allow more vCPU-s per -guest"). - -This is XSA-151. - -Signed-off-by: Jan Beulich -Reviewed-by: Ian Campbell - ---- a/xen/common/xenoprof.c -+++ b/xen/common/xenoprof.c -@@ -239,6 +239,7 @@ static int alloc_xenoprof_struct( - d->xenoprof->rawbuf = alloc_xenheap_pages(get_order_from_pages(npages), 0); - if ( d->xenoprof->rawbuf == NULL ) - { -+ xfree(d->xenoprof->vcpu); - xfree(d->xenoprof); - d->xenoprof = NULL; - return -ENOMEM; -@@ -286,6 +287,7 @@ void free_xenoprof_pages(struct domain * - free_xenheap_pages(x->rawbuf, order); - } - -+ xfree(x->vcpu); - xfree(x); - d->xenoprof = NULL; - } Index: head/emulators/xen-kernel/files/xsa152-4.5.patch =================================================================== --- head/emulators/xen-kernel/files/xsa152-4.5.patch +++ head/emulators/xen-kernel/files/xsa152-4.5.patch @@ -1,41 +0,0 @@ -x86: rate-limit logging in do_xen{oprof,pmu}_op() - -Some of the sub-ops are acessible to all guests, and hence should be -rate-limited. In the xenoprof case, just like for XSA-146, include them -only in debug builds. Since the vPMU code is rather new, allow them to -be always present, but downgrade them to (rate limited) guest messages. - -This is XSA-152. - -Signed-off-by: Jan Beulich - ---- a/xen/common/xenoprof.c -+++ b/xen/common/xenoprof.c -@@ -676,15 +676,13 @@ ret_t do_xenoprof_op(int op, XEN_GUEST_H - - if ( (op < 0) || (op > XENOPROF_last_op) ) - { -- printk("xenoprof: invalid operation %d for domain %d\n", -- op, current->domain->domain_id); -+ gdprintk(XENLOG_DEBUG, "invalid operation %d\n", op); - return -EINVAL; - } - - if ( !NONPRIV_OP(op) && (current->domain != xenoprof_primary_profiler) ) - { -- printk("xenoprof: dom %d denied privileged operation %d\n", -- current->domain->domain_id, op); -+ gdprintk(XENLOG_DEBUG, "denied privileged operation %d\n", op); - return -EPERM; - } - -@@ -907,8 +905,7 @@ ret_t do_xenoprof_op(int op, XEN_GUEST_H - spin_unlock(&xenoprof_lock); - - if ( ret < 0 ) -- printk("xenoprof: operation %d failed for dom %d (status : %d)\n", -- op, current->domain->domain_id, ret); -+ gdprintk(XENLOG_DEBUG, "operation %d failed: %d\n", op, ret); - - return ret; - } Index: head/emulators/xen-kernel/files/xsa156-4.5.patch =================================================================== --- head/emulators/xen-kernel/files/xsa156-4.5.patch +++ head/emulators/xen-kernel/files/xsa156-4.5.patch @@ -0,0 +1,127 @@ +x86/HVM: always intercept #AC and #DB + +Both being benign exceptions, and both being possible to get triggered +by exception delivery, this is required to prevent a guest from locking +up a CPU (resulting from no other VM exits occurring once getting into +such a loop). + +The specific scenarios: + +1) #AC may be raised during exception delivery if the handler is set to +be a ring-3 one by a 32-bit guest, and the stack is misaligned. + +2) #DB may be raised during exception delivery when a breakpoint got +placed on a data structure involved in delivering the exception. This +can result in an endless loop when a 64-bit guest uses a non-zero IST +for the vector 1 IDT entry, but even without use of IST the time it +takes until a contributory fault would get raised (results depending +on the handler) may be quite long. + +This is XSA-156. + +Reported-by: Benjamin Serebrin +Signed-off-by: Jan Beulich +Reviewed-by: Andrew Cooper +Tested-by: Andrew Cooper + +--- a/xen/arch/x86/hvm/svm/svm.c ++++ b/xen/arch/x86/hvm/svm/svm.c +@@ -1045,10 +1045,11 @@ static void noreturn svm_do_resume(struc + 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() ) +@@ -2435,8 +2436,9 @@ void svm_vmexit_handler(struct cpu_user_ + + case VMEXIT_EXCEPTION_DB: + if ( !v->domain->debugger_attached ) +- goto unexpected_exit_type; +- 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: +@@ -2484,6 +2486,11 @@ void svm_vmexit_handler(struct cpu_user_ + 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; +--- a/xen/arch/x86/hvm/vmx/vmx.c ++++ b/xen/arch/x86/hvm/vmx/vmx.c +@@ -1186,16 +1186,10 @@ static void vmx_update_host_cr3(struct v + + void vmx_update_debug_state(struct vcpu *v) + { +- unsigned long mask; +- +- 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_vmcs_enter(v); + vmx_update_exception_bitmap(v); +@@ -2801,9 +2795,10 @@ void vmx_vmexit_handler(struct cpu_user_ + __vmread(EXIT_QUALIFICATION, &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: + { +@@ -2868,6 +2863,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); ++ __vmread(VM_EXIT_INTR_ERROR_CODE, &ecode); ++ hvm_inject_hw_exception(vector, ecode); ++ break; + case TRAP_nmi: + if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) != + (X86_EVENTTYPE_NMI << 8) ) +--- a/xen/include/asm-x86/hvm/hvm.h ++++ b/xen/include/asm-x86/hvm/hvm.h +@@ -378,7 +378,10 @@ static inline int hvm_event_pending(stru + (X86_CR4_VMXE | X86_CR4_PAE | X86_CR4_MCE)) + + /* 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: Index: head/emulators/xen/Makefile =================================================================== --- head/emulators/xen/Makefile +++ head/emulators/xen/Makefile @@ -1,11 +1,10 @@ # $FreeBSD$ PORTNAME= xen -PORTVERSION= 4.5.1 -PORTREVISION= 1 +PORTVERSION= 4.5.2 CATEGORIES= emulators -MAINTAINER= ports@FreeBSD.org +MAINTAINER= royger@FreeBSD.org COMMENT= Xen Hyvervisor meta port LICENSE= GPLv2 Index: head/sysutils/xen-tools/Makefile =================================================================== --- head/sysutils/xen-tools/Makefile +++ head/sysutils/xen-tools/Makefile @@ -1,14 +1,13 @@ # $FreeBSD$ PORTNAME= xen -PORTVERSION= 4.5.1 -PORTREVISION= 2 +PORTVERSION= 4.5.2 CATEGORIES= sysutils emulators MASTER_SITES= http://bits.xensource.com/oss-xen/release/${PORTVERSION}/ \ http://code.coreboot.org/p/seabios/downloads/get/:seabios PKGNAMESUFFIX= -tools -MAINTAINER= ports@FreeBSD.org +MAINTAINER= royger@FreeBSD.org COMMENT= Xen management tool, based on LibXenlight LICENSE= GPLv2 LGPL3 @@ -48,10 +47,7 @@ --disable-curl \ --cxx=c++ -EXTRA_PATCHES= ${FILESDIR}/xsa137.patch:-p1 \ - ${FILESDIR}/xsa142-4.5.patch:-p1 \ - ${FILESDIR}/xsa153-libxl.patch:-p1 \ - ${FILESDIR}/0002-libxc-fix-xc_dom_load_elf_symtab.patch:-p1 +EXTRA_PATCHES= ${FILESDIR}/0002-libxc-fix-xc_dom_load_elf_symtab.patch:-p1 CONFIGURE_ARGS+= --with-extra-qemuu-configure-args="${QEMU_ARGS}" SHEBANG_FILES= tools/misc/xencov_split \ @@ -78,10 +74,6 @@ ${WRKSRC}/tools/libxl/libxl_dm.c \ ${WRKSRC}/tools/qemu-xen-traditional/i386-dm/helper2.c \ ${WRKSRC}/docs/man/* - @for p in ${FILESDIR}/*qemuu*.patch; do \ - ${ECHO_CMD} "====> Applying $${p##*/}" ; \ - ${PATCH} -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen ; \ - done post-install: ${MKDIR} ${STAGEDIR}/var/run/xen Index: head/sysutils/xen-tools/distinfo =================================================================== --- head/sysutils/xen-tools/distinfo +++ head/sysutils/xen-tools/distinfo @@ -1,4 +1,4 @@ -SHA256 (xen-4.5.1.tar.gz) = 668c11d4fca67ac44329e369f810356eacd37b28d28fb96e66aac77f3c5e1371 -SIZE (xen-4.5.1.tar.gz) = 18410400 +SHA256 (xen-4.5.2.tar.gz) = 4c9e5dac4eea484974e9f76da2756c8e0973b4e884d28d37e955df9ebf00e7e8 +SIZE (xen-4.5.2.tar.gz) = 18416220 SHA256 (seabios-1.8.1.tar.gz) = 283bd848f5ce9d4bc52add973a856347e02c9ce89a9e6bc92c99359b87c9871d SIZE (seabios-1.8.1.tar.gz) = 537712 Index: head/sysutils/xen-tools/files/xsa137.patch =================================================================== --- head/sysutils/xen-tools/files/xsa137.patch +++ head/sysutils/xen-tools/files/xsa137.patch @@ -1,231 +0,0 @@ -From 593fe52faa1b85567a7ec20c69d8cfbc7368ae5b Mon Sep 17 00:00:00 2001 -From: Ian Jackson -Date: Mon, 15 Jun 2015 14:50:42 +0100 -Subject: [PATCH] xl: Sane handling of extra config file arguments - -Various xl sub-commands take additional parameters containing = as -additional config fragments. - -The handling of these config fragments has a number of bugs: - - 1. Use of a static 1024-byte buffer. (If truncation would occur, - with semi-trusted input, a security risk arises due to quotes - being lost.) - - 2. Mishandling of the return value from snprintf, so that if - truncation occurs, the to-write pointer is updated with the - wanted-to-write length, resulting in stack corruption. (This is - XSA-137.) - - 3. Clone-and-hack of the code for constructing the appended - config file. - -These are fixed here, by introducing a new function -`string_realloc_append' and using it everywhere. The `extra_info' -buffers are replaced by pointers, which start off NULL and are -explicitly freed on all return paths. - -The separate variable which will become dom_info.extra_config is -abolished (which involves moving the clearing of dom_info). - -Additional bugs I observe, not fixed here: - - 4. The functions which now call string_realloc_append use ad-hoc - error returns, with multiple calls to `return'. This currently - necessitates multiple new calls to `free'. - - 5. Many of the paths in xl call exit(-rc) where rc is a libxl status - code. This is a ridiculous exit status `convention'. - - 6. The loops for handling extra config data are clone-and-hacks. - - 7. Once the extra config buffer is accumulated, it must be combined - with the appropriate main config file. The code to do this - combining is clone-and-hacked too. - -Signed-off-by: Ian Jackson -Tested-by: Ian Jackson -Acked-by: Ian Campbell ---- -v2: Use SSIZE_MAX, not INT_MAX. - Check *accumulate for NULL, not accumulate. - Move memset of dom_info. ---- - tools/libxl/xl_cmdimpl.c | 64 +++++++++++++++++++++++++++++----------------- - 1 file changed, 40 insertions(+), 24 deletions(-) - -diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c -index c858068..c01a851 100644 ---- a/tools/libxl/xl_cmdimpl.c -+++ b/tools/libxl/xl_cmdimpl.c -@@ -151,7 +151,7 @@ struct domain_create { - int console_autoconnect; - int checkpointed_stream; - const char *config_file; -- const char *extra_config; /* extra config string */ -+ char *extra_config; /* extra config string */ - const char *restore_file; - int migrate_fd; /* -1 means none */ - char **migration_domname_r; /* from malloc */ -@@ -4805,11 +4805,25 @@ int main_vm_list(int argc, char **argv) - return 0; - } - -+static void string_realloc_append(char **accumulate, const char *more) -+{ -+ /* Appends more to accumulate. Accumulate is either NULL, or -+ * points (always) to a malloc'd nul-terminated string. */ -+ -+ size_t oldlen = *accumulate ? strlen(*accumulate) : 0; -+ size_t morelen = strlen(more) + 1/*nul*/; -+ if (oldlen > SSIZE_MAX || morelen > SSIZE_MAX - oldlen) { -+ fprintf(stderr,"Additional config data far too large\n"); -+ exit(-ERROR_FAIL); -+ } -+ -+ *accumulate = xrealloc(*accumulate, oldlen + morelen); -+ memcpy(*accumulate + oldlen, more, morelen); -+} -+ - int main_create(int argc, char **argv) - { - const char *filename = NULL; -- char *p; -- char extra_config[1024]; - struct domain_create dom_info; - int paused = 0, debug = 0, daemonize = 1, console_autoconnect = 0, - quiet = 0, monitor = 1, vnc = 0, vncautopass = 0; -@@ -4824,6 +4838,8 @@ int main_create(int argc, char **argv) - {0, 0, 0, 0} - }; - -+ dom_info.extra_config = NULL; -+ - if (argv[1] && argv[1][0] != '-' && !strchr(argv[1], '=')) { - filename = argv[1]; - argc--; argv++; -@@ -4863,20 +4879,21 @@ int main_create(int argc, char **argv) - break; - } - -- extra_config[0] = '\0'; -- for (p = extra_config; optind < argc; optind++) { -+ memset(&dom_info, 0, sizeof(dom_info)); -+ -+ for (; optind < argc; optind++) { - if (strchr(argv[optind], '=') != NULL) { -- p += snprintf(p, sizeof(extra_config) - (p - extra_config), -- "%s\n", argv[optind]); -+ string_realloc_append(&dom_info.extra_config, argv[optind]); -+ string_realloc_append(&dom_info.extra_config, "\n"); - } else if (!filename) { - filename = argv[optind]; - } else { - help("create"); -+ free(dom_info.extra_config); - return 2; - } - } - -- memset(&dom_info, 0, sizeof(dom_info)); - dom_info.debug = debug; - dom_info.daemonize = daemonize; - dom_info.monitor = monitor; -@@ -4884,16 +4901,18 @@ int main_create(int argc, char **argv) - dom_info.dryrun = dryrun_only; - dom_info.quiet = quiet; - dom_info.config_file = filename; -- dom_info.extra_config = extra_config; - dom_info.migrate_fd = -1; - dom_info.vnc = vnc; - dom_info.vncautopass = vncautopass; - dom_info.console_autoconnect = console_autoconnect; - - rc = create_domain(&dom_info); -- if (rc < 0) -+ if (rc < 0) { -+ free(dom_info.extra_config); - return -rc; -+ } - -+ free(dom_info.extra_config); - return 0; - } - -@@ -4901,8 +4920,7 @@ int main_config_update(int argc, char **argv) - { - uint32_t domid; - const char *filename = NULL; -- char *p; -- char extra_config[1024]; -+ char *extra_config = NULL; - void *config_data = 0; - int config_len = 0; - libxl_domain_config d_config; -@@ -4940,15 +4958,15 @@ int main_config_update(int argc, char **argv) - break; - } - -- extra_config[0] = '\0'; -- for (p = extra_config; optind < argc; optind++) { -+ for (; optind < argc; optind++) { - if (strchr(argv[optind], '=') != NULL) { -- p += snprintf(p, sizeof(extra_config) - (p - extra_config), -- "%s\n", argv[optind]); -+ string_realloc_append(&extra_config, argv[optind]); -+ string_realloc_append(&extra_config, "\n"); - } else if (!filename) { - filename = argv[optind]; - } else { - help("create"); -+ free(extra_config); - return 2; - } - } -@@ -4957,7 +4975,8 @@ int main_config_update(int argc, char **argv) - rc = libxl_read_file_contents(ctx, filename, - &config_data, &config_len); - if (rc) { fprintf(stderr, "Failed to read config file: %s: %s\n", -- filename, strerror(errno)); return ERROR_FAIL; } -+ filename, strerror(errno)); -+ free(extra_config); return ERROR_FAIL; } - if (strlen(extra_config)) { - if (config_len > INT_MAX - (strlen(extra_config) + 2 + 1)) { - fprintf(stderr, "Failed to attach extra configration\n"); -@@ -4998,7 +5017,7 @@ int main_config_update(int argc, char **argv) - libxl_domain_config_dispose(&d_config); - - free(config_data); -- -+ free(extra_config); - return 0; - } - -@@ -7255,7 +7274,7 @@ int main_cpupoolcreate(int argc, char **argv) - { - const char *filename = NULL, *config_src=NULL; - const char *p; -- char extra_config[1024]; -+ char *extra_config = NULL; - int opt; - static struct option opts[] = { - {"defconfig", 1, 0, 'f'}, -@@ -7289,13 +7308,10 @@ int main_cpupoolcreate(int argc, char **argv) - break; - } - -- memset(extra_config, 0, sizeof(extra_config)); - while (optind < argc) { - if ((p = strchr(argv[optind], '='))) { -- if (strlen(extra_config) + 1 + strlen(argv[optind]) < sizeof(extra_config)) { -- strcat(extra_config, "\n"); -- strcat(extra_config, argv[optind]); -- } -+ string_realloc_append(&extra_config, "\n"); -+ string_realloc_append(&extra_config, argv[optind]); - } else if (!filename) { - filename = argv[optind]; - } else { --- -1.7.10.4 - Index: head/sysutils/xen-tools/files/xsa138-qemuu-1.patch =================================================================== --- head/sysutils/xen-tools/files/xsa138-qemuu-1.patch +++ head/sysutils/xen-tools/files/xsa138-qemuu-1.patch @@ -1,76 +0,0 @@ -From a9de14175548c04e0f8be7fae219246509ba46a9 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 3 Jun 2015 14:13:31 +0200 -Subject: [PATCH 1/3] ide: Check array bounds before writing to io_buffer - (CVE-2015-5154) - -If the end_transfer_func of a command is called because enough data has -been read or written for the current PIO transfer, and it fails to -correctly call the command completion functions, the DRQ bit in the -status register and s->end_transfer_func may remain set. This allows the -guest to access further bytes in s->io_buffer beyond s->data_end, and -eventually overflowing the io_buffer. - -One case where this currently happens is emulation of the ATAPI command -START STOP UNIT. - -This patch fixes the problem by adding explicit array bounds checks -before accessing the buffer instead of relying on end_transfer_func to -function correctly. - -Cc: qemu-stable@nongnu.org -Signed-off-by: Kevin Wolf ---- - hw/ide/core.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/hw/ide/core.c b/hw/ide/core.c -index 122e955..44fcc23 100644 ---- a/hw/ide/core.c -+++ b/hw/ide/core.c -@@ -2021,6 +2021,10 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val) - } - - p = s->data_ptr; -+ if (p + 2 > s->data_end) { -+ return; -+ } -+ - *(uint16_t *)p = le16_to_cpu(val); - p += 2; - s->data_ptr = p; -@@ -2042,6 +2046,10 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr) - } - - p = s->data_ptr; -+ if (p + 2 > s->data_end) { -+ return 0; -+ } -+ - ret = cpu_to_le16(*(uint16_t *)p); - p += 2; - s->data_ptr = p; -@@ -2063,6 +2071,10 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val) - } - - p = s->data_ptr; -+ if (p + 4 > s->data_end) { -+ return; -+ } -+ - *(uint32_t *)p = le32_to_cpu(val); - p += 4; - s->data_ptr = p; -@@ -2084,6 +2096,10 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr) - } - - p = s->data_ptr; -+ if (p + 4 > s->data_end) { -+ return 0; -+ } -+ - ret = cpu_to_le32(*(uint32_t *)p); - p += 4; - s->data_ptr = p; --- -1.8.3.1 Index: head/sysutils/xen-tools/files/xsa138-qemuu-2.patch =================================================================== --- head/sysutils/xen-tools/files/xsa138-qemuu-2.patch +++ head/sysutils/xen-tools/files/xsa138-qemuu-2.patch @@ -1,28 +0,0 @@ -From aa851d30acfbb9580098ac1dc82885530cb8b3c1 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 3 Jun 2015 14:17:46 +0200 -Subject: [PATCH 2/3] ide/atapi: Fix START STOP UNIT command completion - -The command must be completed on all code paths. START STOP UNIT with -pwrcnd set should succeed without doing anything. - -Signed-off-by: Kevin Wolf ---- - hw/ide/atapi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c -index 950e311..79dd167 100644 ---- a/hw/ide/atapi.c -+++ b/hw/ide/atapi.c -@@ -983,6 +983,7 @@ static void cmd_start_stop_unit(IDEState *s, uint8_t* buf) - - if (pwrcnd) { - /* eject/load only happens for power condition == 0 */ -+ ide_atapi_cmd_ok(s); - return; - } - --- -1.8.3.1 - Index: head/sysutils/xen-tools/files/xsa138-qemuu-3.patch =================================================================== --- head/sysutils/xen-tools/files/xsa138-qemuu-3.patch +++ head/sysutils/xen-tools/files/xsa138-qemuu-3.patch @@ -1,71 +0,0 @@ -From 1d3c2268f8708126a34064c2e0c1000b40e6f3e5 Mon Sep 17 00:00:00 2001 -From: Kevin Wolf -Date: Wed, 3 Jun 2015 14:41:27 +0200 -Subject: [PATCH 3/3] ide: Clear DRQ after handling all expected accesses - -This is additional hardening against an end_transfer_func that fails to -clear the DRQ status bit. The bit must be unset as soon as the PIO -transfer has completed, so it's better to do this in a central place -instead of duplicating the code in all commands (and forgetting it in -some). - -Signed-off-by: Kevin Wolf ---- - hw/ide/core.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/hw/ide/core.c b/hw/ide/core.c -index 44fcc23..50449ca 100644 ---- a/hw/ide/core.c -+++ b/hw/ide/core.c -@@ -2028,8 +2028,10 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val) - *(uint16_t *)p = le16_to_cpu(val); - p += 2; - s->data_ptr = p; -- if (p >= s->data_end) -+ if (p >= s->data_end) { -+ s->status &= ~DRQ_STAT; - s->end_transfer_func(s); -+ } - } - - uint32_t ide_data_readw(void *opaque, uint32_t addr) -@@ -2053,8 +2055,10 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr) - ret = cpu_to_le16(*(uint16_t *)p); - p += 2; - s->data_ptr = p; -- if (p >= s->data_end) -+ if (p >= s->data_end) { -+ s->status &= ~DRQ_STAT; - s->end_transfer_func(s); -+ } - return ret; - } - -@@ -2078,8 +2082,10 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val) - *(uint32_t *)p = le32_to_cpu(val); - p += 4; - s->data_ptr = p; -- if (p >= s->data_end) -+ if (p >= s->data_end) { -+ s->status &= ~DRQ_STAT; - s->end_transfer_func(s); -+ } - } - - uint32_t ide_data_readl(void *opaque, uint32_t addr) -@@ -2103,8 +2109,10 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr) - ret = cpu_to_le32(*(uint32_t *)p); - p += 4; - s->data_ptr = p; -- if (p >= s->data_end) -+ if (p >= s->data_end) { -+ s->status &= ~DRQ_STAT; - s->end_transfer_func(s); -+ } - return ret; - } - --- -1.8.3.1 - Index: head/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch =================================================================== --- head/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch +++ head/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch @@ -1,38 +0,0 @@ -pci_piix3_xen_ide_unplug should completely unhook the unplugged -IDEDevice from the corresponding BlockBackend, otherwise the next call -to release_drive will try to detach the drive again. - -Suggested-by: Kevin Wolf -Signed-off-by: Stefano Stabellini ---- - hw/ide/piix.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/hw/ide/piix.c b/hw/ide/piix.c -index 40757eb..0524dce 100644 ---- a/hw/ide/piix.c -+++ b/hw/ide/piix.c -@@ -172,6 +172,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) - PCIIDEState *pci_ide; - DriveInfo *di; - int i = 0; -+ IDEDevice *idedev; - - pci_ide = PCI_IDE(dev); - -@@ -184,6 +185,12 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) - } - bdrv_close(di->bdrv); - pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; -+ if (!(i % 2)) { -+ idedev = pci_ide->bus[di->bus].master; -+ } else { -+ idedev = pci_ide->bus[di->bus].slave; -+ } -+ idedev->conf.bs = NULL; - drive_put_ref(di); - } - } --- -2.1.4 - Index: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch =================================================================== --- head/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch @@ -1,82 +0,0 @@ -From 5e0c290415b9d57077a86e70c8e6a058868334d3 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 15 Jul 2015 18:16:58 +0100 -Subject: [PATCH 1/7] rtl8139: avoid nested ifs in IP header parsing - -Transmit offload needs to parse packet headers. If header fields have -unexpected values the offload processing is skipped. - -The code currently uses nested ifs because there is relatively little -input validation. The next patches will add missing input validation -and a goto label is more appropriate to avoid deep if statement nesting. - -Signed-off-by: Stefan Hajnoczi ---- - hw/net/rtl8139.c | 41 ++++++++++++++++++++++------------------- - 1 file changed, 22 insertions(+), 19 deletions(-) - -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index 5f0197c..91ba33b 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -2174,28 +2174,30 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - size_t eth_payload_len = 0; - - int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12)); -- if (proto == ETH_P_IP) -+ if (proto != ETH_P_IP) - { -- DPRINTF("+++ C+ mode has IP packet\n"); -- -- /* not aligned */ -- eth_payload_data = saved_buffer + ETH_HLEN; -- eth_payload_len = saved_size - ETH_HLEN; -- -- ip = (ip_header*)eth_payload_data; -- -- if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { -- DPRINTF("+++ C+ mode packet has bad IP version %d " -- "expected %d\n", IP_HEADER_VERSION(ip), -- IP_HEADER_VERSION_4); -- ip = NULL; -- } else { -- hlen = IP_HEADER_LENGTH(ip); -- ip_protocol = ip->ip_p; -- ip_data_len = be16_to_cpu(ip->ip_len) - hlen; -- } -+ goto skip_offload; - } - -+ DPRINTF("+++ C+ mode has IP packet\n"); -+ -+ /* not aligned */ -+ eth_payload_data = saved_buffer + ETH_HLEN; -+ eth_payload_len = saved_size - ETH_HLEN; -+ -+ ip = (ip_header*)eth_payload_data; -+ -+ if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { -+ DPRINTF("+++ C+ mode packet has bad IP version %d " -+ "expected %d\n", IP_HEADER_VERSION(ip), -+ IP_HEADER_VERSION_4); -+ goto skip_offload; -+ } -+ -+ hlen = IP_HEADER_LENGTH(ip); -+ ip_protocol = ip->ip_p; -+ ip_data_len = be16_to_cpu(ip->ip_len) - hlen; -+ - if (ip) - { - if (txdw0 & CP_TX_IPCS) -@@ -2391,6 +2393,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - } - } - -+skip_offload: - /* update tally counter */ - ++s->tally_counters.TxOk; - --- -2.1.4 - Index: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch =================================================================== --- head/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch @@ -1,373 +0,0 @@ -From 2d7d80e8dc160904fa7276cc05da26c062a50066 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 15 Jul 2015 18:16:59 +0100 -Subject: [PATCH 2/7] rtl8139: drop tautologous if (ip) {...} statement - -The previous patch stopped using the ip pointer as an indicator that the -IP header is present. When we reach the if (ip) {...} statement we know -ip is always non-NULL. - -Remove the if statement to reduce nesting. - -Signed-off-by: Stefan Hajnoczi ---- - hw/net/rtl8139.c | 305 +++++++++++++++++++++++++++---------------------------- - 1 file changed, 151 insertions(+), 154 deletions(-) - -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index 91ba33b..2f12d42 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -2198,198 +2198,195 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - ip_protocol = ip->ip_p; - ip_data_len = be16_to_cpu(ip->ip_len) - hlen; - -- if (ip) -+ if (txdw0 & CP_TX_IPCS) - { -- if (txdw0 & CP_TX_IPCS) -- { -- DPRINTF("+++ C+ mode need IP checksum\n"); -+ DPRINTF("+++ C+ mode need IP checksum\n"); - -- if (hleneth_payload_len) {/* min header length */ -- /* bad packet header len */ -- /* or packet too short */ -- } -- else -- { -- ip->ip_sum = 0; -- ip->ip_sum = ip_checksum(ip, hlen); -- DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", -- hlen, ip->ip_sum); -- } -+ if (hleneth_payload_len) {/* min header length */ -+ /* bad packet header len */ -+ /* or packet too short */ - } -- -- if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) -+ else - { -- int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; -+ ip->ip_sum = 0; -+ ip->ip_sum = ip_checksum(ip, hlen); -+ DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", -+ hlen, ip->ip_sum); -+ } -+ } - -- DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " -- "frame data %d specified MSS=%d\n", ETH_MTU, -- ip_data_len, saved_size - ETH_HLEN, large_send_mss); -+ if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) -+ { -+ int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; - -- int tcp_send_offset = 0; -- int send_count = 0; -+ DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " -+ "frame data %d specified MSS=%d\n", ETH_MTU, -+ ip_data_len, saved_size - ETH_HLEN, large_send_mss); - -- /* maximum IP header length is 60 bytes */ -- uint8_t saved_ip_header[60]; -+ int tcp_send_offset = 0; -+ int send_count = 0; - -- /* save IP header template; data area is used in tcp checksum calculation */ -- memcpy(saved_ip_header, eth_payload_data, hlen); -+ /* maximum IP header length is 60 bytes */ -+ uint8_t saved_ip_header[60]; - -- /* a placeholder for checksum calculation routine in tcp case */ -- uint8_t *data_to_checksum = eth_payload_data + hlen - 12; -- // size_t data_to_checksum_len = eth_payload_len - hlen + 12; -+ /* save IP header template; data area is used in tcp checksum calculation */ -+ memcpy(saved_ip_header, eth_payload_data, hlen); - -- /* pointer to TCP header */ -- tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); -+ /* a placeholder for checksum calculation routine in tcp case */ -+ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; -+ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; - -- int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); -+ /* pointer to TCP header */ -+ tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); - -- /* ETH_MTU = ip header len + tcp header len + payload */ -- int tcp_data_len = ip_data_len - tcp_hlen; -- int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; -+ int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); - -- DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " -- "data len %d TCP chunk size %d\n", ip_data_len, -- tcp_hlen, tcp_data_len, tcp_chunk_size); -+ /* ETH_MTU = ip header len + tcp header len + payload */ -+ int tcp_data_len = ip_data_len - tcp_hlen; -+ int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; - -- /* note the cycle below overwrites IP header data, -- but restores it from saved_ip_header before sending packet */ -+ DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " -+ "data len %d TCP chunk size %d\n", ip_data_len, -+ tcp_hlen, tcp_data_len, tcp_chunk_size); - -- int is_last_frame = 0; -+ /* note the cycle below overwrites IP header data, -+ but restores it from saved_ip_header before sending packet */ - -- for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) -- { -- uint16_t chunk_size = tcp_chunk_size; -- -- /* check if this is the last frame */ -- if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) -- { -- is_last_frame = 1; -- chunk_size = tcp_data_len - tcp_send_offset; -- } -- -- DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", -- be32_to_cpu(p_tcp_hdr->th_seq)); -- -- /* add 4 TCP pseudoheader fields */ -- /* copy IP source and destination fields */ -- memcpy(data_to_checksum, saved_ip_header + 12, 8); -- -- DPRINTF("+++ C+ mode TSO calculating TCP checksum for " -- "packet with %d bytes data\n", tcp_hlen + -- chunk_size); -- -- if (tcp_send_offset) -- { -- memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); -- } -- -- /* keep PUSH and FIN flags only for the last frame */ -- if (!is_last_frame) -- { -- TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); -- } -- -- /* recalculate TCP checksum */ -- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; -- p_tcpip_hdr->zeros = 0; -- p_tcpip_hdr->ip_proto = IP_PROTO_TCP; -- p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); -- -- p_tcp_hdr->th_sum = 0; -- -- int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); -- DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", -- tcp_checksum); -- -- p_tcp_hdr->th_sum = tcp_checksum; -- -- /* restore IP header */ -- memcpy(eth_payload_data, saved_ip_header, hlen); -- -- /* set IP data length and recalculate IP checksum */ -- ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); -- -- /* increment IP id for subsequent frames */ -- ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); -- -- ip->ip_sum = 0; -- ip->ip_sum = ip_checksum(eth_payload_data, hlen); -- DPRINTF("+++ C+ mode TSO IP header len=%d " -- "checksum=%04x\n", hlen, ip->ip_sum); -- -- int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; -- DPRINTF("+++ C+ mode TSO transferring packet size " -- "%d\n", tso_send_size); -- rtl8139_transfer_frame(s, saved_buffer, tso_send_size, -- 0, (uint8_t *) dot1q_buffer); -- -- /* add transferred count to TCP sequence number */ -- p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); -- ++send_count; -- } -+ int is_last_frame = 0; - -- /* Stop sending this frame */ -- saved_size = 0; -- } -- else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) -+ for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) - { -- DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); -+ uint16_t chunk_size = tcp_chunk_size; - -- /* maximum IP header length is 60 bytes */ -- uint8_t saved_ip_header[60]; -- memcpy(saved_ip_header, eth_payload_data, hlen); -+ /* check if this is the last frame */ -+ if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) -+ { -+ is_last_frame = 1; -+ chunk_size = tcp_data_len - tcp_send_offset; -+ } - -- uint8_t *data_to_checksum = eth_payload_data + hlen - 12; -- // size_t data_to_checksum_len = eth_payload_len - hlen + 12; -+ DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", -+ be32_to_cpu(p_tcp_hdr->th_seq)); - - /* add 4 TCP pseudoheader fields */ - /* copy IP source and destination fields */ - memcpy(data_to_checksum, saved_ip_header + 12, 8); - -- if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) -+ DPRINTF("+++ C+ mode TSO calculating TCP checksum for " -+ "packet with %d bytes data\n", tcp_hlen + -+ chunk_size); -+ -+ if (tcp_send_offset) - { -- DPRINTF("+++ C+ mode calculating TCP checksum for " -- "packet with %d bytes data\n", ip_data_len); -+ memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); -+ } - -- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; -- p_tcpip_hdr->zeros = 0; -- p_tcpip_hdr->ip_proto = IP_PROTO_TCP; -- p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); -+ /* keep PUSH and FIN flags only for the last frame */ -+ if (!is_last_frame) -+ { -+ TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); -+ } - -- tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); -+ /* recalculate TCP checksum */ -+ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; -+ p_tcpip_hdr->zeros = 0; -+ p_tcpip_hdr->ip_proto = IP_PROTO_TCP; -+ p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); - -- p_tcp_hdr->th_sum = 0; -+ p_tcp_hdr->th_sum = 0; - -- int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); -- DPRINTF("+++ C+ mode TCP checksum %04x\n", -- tcp_checksum); -+ int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); -+ DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", -+ tcp_checksum); - -- p_tcp_hdr->th_sum = tcp_checksum; -- } -- else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) -- { -- DPRINTF("+++ C+ mode calculating UDP checksum for " -- "packet with %d bytes data\n", ip_data_len); -+ p_tcp_hdr->th_sum = tcp_checksum; - -- ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; -- p_udpip_hdr->zeros = 0; -- p_udpip_hdr->ip_proto = IP_PROTO_UDP; -- p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); -+ /* restore IP header */ -+ memcpy(eth_payload_data, saved_ip_header, hlen); - -- udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); -+ /* set IP data length and recalculate IP checksum */ -+ ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); - -- p_udp_hdr->uh_sum = 0; -+ /* increment IP id for subsequent frames */ -+ ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); - -- int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); -- DPRINTF("+++ C+ mode UDP checksum %04x\n", -- udp_checksum); -+ ip->ip_sum = 0; -+ ip->ip_sum = ip_checksum(eth_payload_data, hlen); -+ DPRINTF("+++ C+ mode TSO IP header len=%d " -+ "checksum=%04x\n", hlen, ip->ip_sum); - -- p_udp_hdr->uh_sum = udp_checksum; -- } -+ int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; -+ DPRINTF("+++ C+ mode TSO transferring packet size " -+ "%d\n", tso_send_size); -+ rtl8139_transfer_frame(s, saved_buffer, tso_send_size, -+ 0, (uint8_t *) dot1q_buffer); - -- /* restore IP header */ -- memcpy(eth_payload_data, saved_ip_header, hlen); -+ /* add transferred count to TCP sequence number */ -+ p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); -+ ++send_count; - } -+ -+ /* Stop sending this frame */ -+ saved_size = 0; -+ } -+ else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) -+ { -+ DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); -+ -+ /* maximum IP header length is 60 bytes */ -+ uint8_t saved_ip_header[60]; -+ memcpy(saved_ip_header, eth_payload_data, hlen); -+ -+ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; -+ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; -+ -+ /* add 4 TCP pseudoheader fields */ -+ /* copy IP source and destination fields */ -+ memcpy(data_to_checksum, saved_ip_header + 12, 8); -+ -+ if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) -+ { -+ DPRINTF("+++ C+ mode calculating TCP checksum for " -+ "packet with %d bytes data\n", ip_data_len); -+ -+ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; -+ p_tcpip_hdr->zeros = 0; -+ p_tcpip_hdr->ip_proto = IP_PROTO_TCP; -+ p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); -+ -+ tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); -+ -+ p_tcp_hdr->th_sum = 0; -+ -+ int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); -+ DPRINTF("+++ C+ mode TCP checksum %04x\n", -+ tcp_checksum); -+ -+ p_tcp_hdr->th_sum = tcp_checksum; -+ } -+ else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) -+ { -+ DPRINTF("+++ C+ mode calculating UDP checksum for " -+ "packet with %d bytes data\n", ip_data_len); -+ -+ ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; -+ p_udpip_hdr->zeros = 0; -+ p_udpip_hdr->ip_proto = IP_PROTO_UDP; -+ p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); -+ -+ udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); -+ -+ p_udp_hdr->uh_sum = 0; -+ -+ int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); -+ DPRINTF("+++ C+ mode UDP checksum %04x\n", -+ udp_checksum); -+ -+ p_udp_hdr->uh_sum = udp_checksum; -+ } -+ -+ /* restore IP header */ -+ memcpy(eth_payload_data, saved_ip_header, hlen); - } - } - --- -2.1.4 - Index: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch =================================================================== --- head/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch @@ -1,39 +0,0 @@ -From 043d28507ef7c5fdc34866f5e3b27a72bd0cd072 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 15 Jul 2015 18:17:00 +0100 -Subject: [PATCH 3/7] rtl8139: skip offload on short Ethernet/IP header - -Transmit offload features access Ethernet and IP headers the packet. If -the packet is too short we must not attempt to access header fields: - - int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12)); - ... - eth_payload_data = saved_buffer + ETH_HLEN; - ... - ip = (ip_header*)eth_payload_data; - if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { - -Signed-off-by: Stefan Hajnoczi ---- - hw/net/rtl8139.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index 2f12d42..d377b6b 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -2164,6 +2164,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - { - DPRINTF("+++ C+ mode offloaded task checksum\n"); - -+ /* Large enough for Ethernet and IP headers? */ -+ if (saved_size < ETH_HLEN + sizeof(ip_header)) { -+ goto skip_offload; -+ } -+ - /* ip packet header */ - ip_header *ip = NULL; - int hlen = 0; --- -2.1.4 - Index: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch =================================================================== --- head/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch @@ -1,53 +0,0 @@ -From 5a75d242fe019d05b46ef9bc330a6892525c84a7 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 15 Jul 2015 18:17:01 +0100 -Subject: [PATCH 4/7] rtl8139: check IP Header Length field - -The IP Header Length field was only checked in the IP checksum case, but -is used in other cases too. - -Signed-off-by: Stefan Hajnoczi ---- - hw/net/rtl8139.c | 19 ++++++++----------- - 1 file changed, 8 insertions(+), 11 deletions(-) - -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index d377b6b..cd5ac05 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -2200,6 +2200,10 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - } - - hlen = IP_HEADER_LENGTH(ip); -+ if (hlen < sizeof(ip_header) || hlen > eth_payload_len) { -+ goto skip_offload; -+ } -+ - ip_protocol = ip->ip_p; - ip_data_len = be16_to_cpu(ip->ip_len) - hlen; - -@@ -2207,17 +2211,10 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - { - DPRINTF("+++ C+ mode need IP checksum\n"); - -- if (hleneth_payload_len) {/* min header length */ -- /* bad packet header len */ -- /* or packet too short */ -- } -- else -- { -- ip->ip_sum = 0; -- ip->ip_sum = ip_checksum(ip, hlen); -- DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", -- hlen, ip->ip_sum); -- } -+ ip->ip_sum = 0; -+ ip->ip_sum = ip_checksum(ip, hlen); -+ DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", -+ hlen, ip->ip_sum); - } - - if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) --- -2.1.4 - Index: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch =================================================================== --- head/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch @@ -1,34 +0,0 @@ -From 6c79ea275d72bc1fd88bdcf1e7d231b2c9c865de Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 15 Jul 2015 18:17:02 +0100 -Subject: [PATCH 5/7] rtl8139: check IP Total Length field - -The IP Total Length field includes the IP header and data. Make sure it -is valid and does not exceed the Ethernet payload size. - -Signed-off-by: Stefan Hajnoczi ---- - hw/net/rtl8139.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index cd5ac05..ed2b23b 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -2205,7 +2205,12 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - } - - ip_protocol = ip->ip_p; -- ip_data_len = be16_to_cpu(ip->ip_len) - hlen; -+ -+ ip_data_len = be16_to_cpu(ip->ip_len); -+ if (ip_data_len < hlen || ip_data_len > eth_payload_len) { -+ goto skip_offload; -+ } -+ ip_data_len -= hlen; - - if (txdw0 & CP_TX_IPCS) - { --- -2.1.4 - Index: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch =================================================================== --- head/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch @@ -1,35 +0,0 @@ -From 30aa7be430e7c982e9163f3bcc745d3aa57b6aa4 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 15 Jul 2015 18:17:03 +0100 -Subject: [PATCH 6/7] rtl8139: skip offload on short TCP header - -TCP Large Segment Offload accesses the TCP header in the packet. If the -packet is too short we must not attempt to access header fields: - - tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); - int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); - -Signed-off-by: Stefan Hajnoczi ---- - hw/net/rtl8139.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index ed2b23b..c8f0df9 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -2224,6 +2224,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - - if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) - { -+ /* Large enough for the TCP header? */ -+ if (ip_data_len < sizeof(tcp_header)) { -+ goto skip_offload; -+ } -+ - int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; - - DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " --- -2.1.4 - Index: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch =================================================================== --- head/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch @@ -1,32 +0,0 @@ -From 9a084807bf6ca7c16d997a236d304111894a6539 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Wed, 15 Jul 2015 18:17:04 +0100 -Subject: [PATCH 7/7] rtl8139: check TCP Data Offset field - -The TCP Data Offset field contains the length of the header. Make sure -it is valid and does not exceed the IP data length. - -Signed-off-by: Stefan Hajnoczi ---- - hw/net/rtl8139.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index c8f0df9..2df4a51 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -2253,6 +2253,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) - - int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); - -+ /* Invalid TCP data offset? */ -+ if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) { -+ goto skip_offload; -+ } -+ - /* ETH_MTU = ip header len + tcp header len + payload */ - int tcp_data_len = ip_data_len - tcp_hlen; - int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; --- -2.1.4 - Index: head/sysutils/xen-tools/files/xsa142-4.5.patch =================================================================== --- head/sysutils/xen-tools/files/xsa142-4.5.patch +++ head/sysutils/xen-tools/files/xsa142-4.5.patch @@ -1,53 +0,0 @@ -From 07ca00703f76ad392eda5ee52cce1197cf49c30a Mon Sep 17 00:00:00 2001 -From: Stefano Stabellini -Subject: [PATCH v2.1 for-4.5] libxl: handle read-only drives with qemu-xen - -The current libxl code doesn't deal with read-only drives at all. - -Upstream QEMU and qemu-xen only support read-only cdrom drives: make -sure to specify "readonly=on" for cdrom drives and return error in case -the user requested a non-cdrom read-only drive. - -This is XSA-142, discovered by Lin Liu -(https://bugzilla.redhat.com/show_bug.cgi?id=1257893). - -Signed-off-by: Stefano Stabellini - -Backport to Xen 4.5 and earlier, apropos of report and review from -Michael Young. - -Signed-off-by: Ian Jackson ---- - tools/libxl/libxl_dm.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - -diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c -index b4ce523..d74fb14 100644 ---- a/tools/libxl/libxl_dm.c -+++ b/tools/libxl/libxl_dm.c -@@ -797,13 +797,18 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc, - if (disks[i].is_cdrom) { - if (disks[i].format == LIBXL_DISK_FORMAT_EMPTY) - drive = libxl__sprintf -- (gc, "if=ide,index=%d,media=cdrom,cache=writeback,id=ide-%i", -- disk, dev_number); -+ (gc, "if=ide,index=%d,readonly=%s,media=cdrom,cache=writeback,id=ide-%i", -+ disk, disks[i].readwrite ? "off" : "on", dev_number); - else - drive = libxl__sprintf -- (gc, "file=%s,if=ide,index=%d,media=cdrom,format=%s,cache=writeback,id=ide-%i", -- disks[i].pdev_path, disk, format, dev_number); -+ (gc, "file=%s,if=ide,index=%d,readonly=%s,media=cdrom,format=%s,cache=writeback,id=ide-%i", -+ disks[i].pdev_path, disk, disks[i].readwrite ? "off" : "on", format, dev_number); - } else { -+ if (!disks[i].readwrite) { -+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "qemu-xen doesn't support read-only disk drivers"); -+ return NULL; -+ } -+ - if (disks[i].format == LIBXL_DISK_FORMAT_EMPTY) { - LIBXL__LOG(ctx, LIBXL__LOG_WARNING, "cannot support" - " empty disk format for %s", disks[i].vdev); --- -1.7.10.4 - Index: head/sysutils/xen-tools/files/xsa153-libxl.patch =================================================================== --- head/sysutils/xen-tools/files/xsa153-libxl.patch +++ head/sysutils/xen-tools/files/xsa153-libxl.patch @@ -1,86 +0,0 @@ -From 27593ec62bdad8621df910931349d964a6dbaa8c Mon Sep 17 00:00:00 2001 -From: Ian Jackson -Date: Wed, 21 Oct 2015 16:18:30 +0100 -Subject: [PATCH XSA-153 v3] libxl: adjust PoD target by memory fudge, too - -PoD guests need to balloon at least as far as required by PoD, or risk -crashing. Currently they don't necessarily know what the right value -is, because our memory accounting is (at the very least) confusing. - -Apply the memory limit fudge factor to the in-hypervisor PoD memory -target, too. This will increase the size of the guest's PoD cache by -the fudge factor LIBXL_MAXMEM_CONSTANT (currently 1Mby). This ensures -that even with a slightly-off balloon driver, the guest will be -stable even under memory pressure. - -There are two call sites of xc_domain_set_pod_target that need fixing: - -The one in libxl_set_memory_target is straightforward. - -The one in xc_hvm_build_x86.c:setup_guest is more awkward. Simply -setting the PoD target differently does not work because the various -amounts of memory during domain construction no longer match up. -Instead, we adjust the guest memory target in xenstore (but only for -PoD guests). - -This introduces a 1Mby discrepancy between the balloon target of a PoD -guest at boot, and the target set by an apparently-equivalent `xl -mem-set' (or similar) later. This approach is low-risk for a security -fix but we need to fix this up properly in xen.git#staging and -probably also in stable trees. - -This is XSA-153. - -Signed-off-by: Ian Jackson ---- - tools/libxl/libxl.c | 2 +- - tools/libxl/libxl_dom.c | 9 ++++++++- - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c -index d38d0c7..1366177 100644 ---- a/tools/libxl/libxl.c -+++ b/tools/libxl/libxl.c -@@ -4815,7 +4815,7 @@ retry_transaction: - } - - rc = xc_domain_set_pod_target(ctx->xch, domid, -- new_target_memkb / 4, NULL, NULL, NULL); -+ (new_target_memkb + LIBXL_MAXMEM_CONSTANT) / 4, NULL, NULL, NULL); - if (rc != 0) { - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, - "xc_domain_set_pod_target domid=%d, memkb=%d " -diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c -index b514377..8019f4e 100644 ---- a/tools/libxl/libxl_dom.c -+++ b/tools/libxl/libxl_dom.c -@@ -486,6 +486,7 @@ int libxl__build_post(libxl__gc *gc, uint32_t domid, - xs_transaction_t t; - char **ents; - int i, rc; -+ int64_t mem_target_fudge; - - if (info->num_vnuma_nodes && !info->num_vcpu_soft_affinity) { - rc = set_vnuma_affinity(gc, domid, info); -@@ -518,11 +519,17 @@ int libxl__build_post(libxl__gc *gc, uint32_t domid, - } - } - -+ mem_target_fudge = -+ (info->type == LIBXL_DOMAIN_TYPE_HVM && -+ info->max_memkb > info->target_memkb) -+ ? LIBXL_MAXMEM_CONSTANT : 0; -+ - ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); - ents[0] = "memory/static-max"; - ents[1] = GCSPRINTF("%"PRId64, info->max_memkb); - ents[2] = "memory/target"; -- ents[3] = GCSPRINTF("%"PRId64, info->target_memkb - info->video_memkb); -+ ents[3] = GCSPRINTF("%"PRId64, info->target_memkb - info->video_memkb -+ - mem_target_fudge); - ents[4] = "memory/videoram"; - ents[5] = GCSPRINTF("%"PRId64, info->video_memkb); - ents[6] = "domid"; --- -1.7.10.4 -