diff options
Diffstat (limited to 'sysutils')
-rw-r--r-- | sysutils/xenkernel45/Makefile | 6 | ||||
-rw-r--r-- | sysutils/xenkernel45/distinfo | 14 | ||||
-rw-r--r-- | sysutils/xenkernel45/patches/patch-CVE-2015-7835 | 32 | ||||
-rw-r--r-- | sysutils/xenkernel45/patches/patch-CVE-2015-7969 | 35 | ||||
-rw-r--r-- | sysutils/xenkernel45/patches/patch-CVE-2015-7970 | 182 | ||||
-rw-r--r-- | sysutils/xenkernel45/patches/patch-CVE-2015-7971 | 35 | ||||
-rw-r--r-- | sysutils/xentools45/Makefile | 6 | ||||
-rw-r--r-- | sysutils/xentools45/distinfo | 15 | ||||
-rw-r--r-- | sysutils/xentools45/patches/patch-XSA135 | 139 | ||||
-rw-r--r-- | sysutils/xentools45/patches/patch-XSA137 | 175 | ||||
-rw-r--r-- | sysutils/xentools45/patches/patch-XSA138 | 175 | ||||
-rw-r--r-- | sysutils/xentools45/patches/patch-XSA139 | 28 | ||||
-rw-r--r-- | sysutils/xentools45/patches/patch-XSA140 | 433 |
13 files changed, 16 insertions, 1259 deletions
diff --git a/sysutils/xenkernel45/Makefile b/sysutils/xenkernel45/Makefile index 1270b76c98c..6e06c9e907b 100644 --- a/sysutils/xenkernel45/Makefile +++ b/sysutils/xenkernel45/Makefile @@ -1,9 +1,9 @@ -# $NetBSD: Makefile,v 1.12 2016/01/07 17:48:33 bouyer Exp $ +# $NetBSD: Makefile,v 1.13 2016/01/08 13:24:29 bouyer Exp $ -VERSION= 4.5.1 +VERSION= 4.5.2 DISTNAME= xen-${VERSION} PKGNAME= xenkernel45-${VERSION} -PKGREVISION= 2 +#PKGREVISION= 0 CATEGORIES= sysutils MASTER_SITES= http://bits.xensource.com/oss-xen/release/${VERSION}/ diff --git a/sysutils/xenkernel45/distinfo b/sysutils/xenkernel45/distinfo index c80c96e02bc..3bdd3a8c080 100644 --- a/sysutils/xenkernel45/distinfo +++ b/sysutils/xenkernel45/distinfo @@ -1,14 +1,10 @@ -$NetBSD: distinfo,v 1.12 2016/01/07 17:48:33 bouyer Exp $ +$NetBSD: distinfo,v 1.13 2016/01/08 13:24:29 bouyer Exp $ -SHA1 (xen-4.5.1.tar.gz) = f10328ce63625a5a7bfa3af5899c4432a467c051 -RMD160 (xen-4.5.1.tar.gz) = 4c449d799e041a52a94c00ee43a8c28fd4af1b96 -SHA512 (xen-4.5.1.tar.gz) = 9436243e26bc64bc836a179abdc3a6b1b6fa9d3f2170453092c18be71fa62e18cd4465a9154c0f28a7ac8d69d08361ba1defef240a51197f058c012c3855ba04 -Size (xen-4.5.1.tar.gz) = 18410400 bytes +SHA1 (xen-4.5.2.tar.gz) = c764589afc817aee4a5df5fa5dc2c7b8ab79508b +RMD160 (xen-4.5.2.tar.gz) = 953f81cd175b3cb9f591ce21d3c838ecb8e6a780 +SHA512 (xen-4.5.2.tar.gz) = e0ce01a5356c254bfde48fae0b0e005c42c1615a7ccf4c1ba7dcf90784777b53995e9a9ae4575e3f19ef341014b34cb8c06e39d68be359f7fd69830501a144dd +Size (xen-4.5.2.tar.gz) = 18416220 bytes SHA1 (patch-CVE-2015-5307) = f140ec14cbb9d5194e926d8f34777ebddf3d6836 -SHA1 (patch-CVE-2015-7835) = b62858a3c615e564e56e52d84e4c7961fb63122d -SHA1 (patch-CVE-2015-7969) = 4e3d5a6eeaaaa6b7ce656b24bf9ce40c174897f1 -SHA1 (patch-CVE-2015-7970) = 3e757e1f17b9c5861517c2a9ad88ec0f32b311e8 -SHA1 (patch-CVE-2015-7971) = 3bba0f79548ae55558a9d0aeadc9aac6d9c56252 SHA1 (patch-CVE-2015-8339) = 080bc4c04ee5ad832756b11a65b1598f12eae97e SHA1 (patch-CVE-2015-8555) = 493a9229c2d5f8bd3bedc79166939d4883466645 SHA1 (patch-Config.mk) = a2a104d023cea4e551a3ad40927d4884d6c610bf diff --git a/sysutils/xenkernel45/patches/patch-CVE-2015-7835 b/sysutils/xenkernel45/patches/patch-CVE-2015-7835 deleted file mode 100644 index 38dac501b30..00000000000 --- a/sysutils/xenkernel45/patches/patch-CVE-2015-7835 +++ /dev/null @@ -1,32 +0,0 @@ -$NetBSD: patch-CVE-2015-7835,v 1.1 2015/10/29 20:40:53 bouyer Exp $ - -Patch for CVE-2015-7835 aka XSA-148, from -http://xenbits.xenproject.org/xsa/xsa148-4.5.patch - - ---- xen/arch/x86/mm.c.orig -+++ 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) ) diff --git a/sysutils/xenkernel45/patches/patch-CVE-2015-7969 b/sysutils/xenkernel45/patches/patch-CVE-2015-7969 deleted file mode 100644 index dfe82e224d3..00000000000 --- a/sysutils/xenkernel45/patches/patch-CVE-2015-7969 +++ /dev/null @@ -1,35 +0,0 @@ -$NetBSD: patch-CVE-2015-7969,v 1.1 2015/10/29 20:40:53 bouyer Exp $ - -Patch for CVE-2015-7869 aka XSA-149 + XSA-151, from -http://xenbits.xenproject.org/xsa/xsa149.patch -http://xenbits.xenproject.org/xsa/xsa151.patch - ---- xen/common/domain.c.orig -+++ 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); - ---- xen/common/xenoprof.c.orig -+++ 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; - } diff --git a/sysutils/xenkernel45/patches/patch-CVE-2015-7970 b/sysutils/xenkernel45/patches/patch-CVE-2015-7970 deleted file mode 100644 index 79a37b0d58c..00000000000 --- a/sysutils/xenkernel45/patches/patch-CVE-2015-7970 +++ /dev/null @@ -1,182 +0,0 @@ -$NetBSD: patch-CVE-2015-7970,v 1.1 2015/10/29 20:40:53 bouyer Exp $ - -Patch for CVE-2015-7970 aka XSA-150, from -http://xenbits.xenproject.org/xsa/xsa150.patch - ---- xen/arch/x86/mm/p2m-pod.c.orig -+++ 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: ---- xen/arch/x86/mm/p2m.c.orig -+++ 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 ---- xen/include/asm-x86/p2m.h.orig -+++ 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; diff --git a/sysutils/xenkernel45/patches/patch-CVE-2015-7971 b/sysutils/xenkernel45/patches/patch-CVE-2015-7971 deleted file mode 100644 index 7724c92a3b3..00000000000 --- a/sysutils/xenkernel45/patches/patch-CVE-2015-7971 +++ /dev/null @@ -1,35 +0,0 @@ -$NetBSD: patch-CVE-2015-7971,v 1.1 2015/10/29 20:40:53 bouyer Exp $ - -Patch for CVE-2015-7971 aka XSA-152, based on -http://xenbits.xenproject.org/xsa/xsa152.patch - ---- xen/common/xenoprof.c.orig -+++ 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; - } diff --git a/sysutils/xentools45/Makefile b/sysutils/xentools45/Makefile index ea8a0bc3ed4..0d4d5ac777c 100644 --- a/sysutils/xentools45/Makefile +++ b/sysutils/xentools45/Makefile @@ -1,11 +1,11 @@ -# $NetBSD: Makefile,v 1.23 2016/01/07 17:48:34 bouyer Exp $ +# $NetBSD: Makefile,v 1.24 2016/01/08 13:24:29 bouyer Exp $ -VERSION= 4.5.1 +VERSION= 4.5.2 VERSION_IPXE= 9a93db3f0947484e30e753bbd61a10b17336e20e DISTNAME= xen-${VERSION} PKGNAME= xentools45-${VERSION} -PKGREVISION= 9 +#PKGREVISION= 0 CATEGORIES= sysutils MASTER_SITES= http://bits.xensource.com/oss-xen/release/${VERSION}/ diff --git a/sysutils/xentools45/distinfo b/sysutils/xentools45/distinfo index 589abbf50bf..c5c4c236b2d 100644 --- a/sysutils/xentools45/distinfo +++ b/sysutils/xentools45/distinfo @@ -1,13 +1,13 @@ -$NetBSD: distinfo,v 1.15 2016/01/07 17:48:34 bouyer Exp $ +$NetBSD: distinfo,v 1.16 2016/01/08 13:24:29 bouyer Exp $ SHA1 (ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz) = fecadf952821e830ce1a1d19655288eef8488f88 RMD160 (ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz) = 539bfa12db7054228250d6dd380bbf96c1a040f8 SHA512 (ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz) = c5cb1cdff40d2d71fd3e692a9d0efadf2aa17290daf5195391a1c81ddd9dfc913a8e44d5be2b12be85b2a5565ea31631c99c7053564f2fb2225c80ea0bb0e4a4 Size (ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz) = 2867999 bytes -SHA1 (xen-4.5.1.tar.gz) = f10328ce63625a5a7bfa3af5899c4432a467c051 -RMD160 (xen-4.5.1.tar.gz) = 4c449d799e041a52a94c00ee43a8c28fd4af1b96 -SHA512 (xen-4.5.1.tar.gz) = 9436243e26bc64bc836a179abdc3a6b1b6fa9d3f2170453092c18be71fa62e18cd4465a9154c0f28a7ac8d69d08361ba1defef240a51197f058c012c3855ba04 -Size (xen-4.5.1.tar.gz) = 18410400 bytes +SHA1 (xen-4.5.2.tar.gz) = c764589afc817aee4a5df5fa5dc2c7b8ab79508b +RMD160 (xen-4.5.2.tar.gz) = 953f81cd175b3cb9f591ce21d3c838ecb8e6a780 +SHA512 (xen-4.5.2.tar.gz) = e0ce01a5356c254bfde48fae0b0e005c42c1615a7ccf4c1ba7dcf90784777b53995e9a9ae4575e3f19ef341014b34cb8c06e39d68be359f7fd69830501a144dd +Size (xen-4.5.2.tar.gz) = 18416220 bytes SHA1 (patch-.._.._ipxe_src_core_settings.c) = 9e053e5e9936f49c46af0d59382a67d5f28cb39d SHA1 (patch-.._.._ipxe_src_interface_efi_efi_snp.c) = 7cd8a2d2dbeff55624b5d3461d22cd8331221762 SHA1 (patch-.._.._ipxe_src_net_fcels.c) = 7c13c87af5e38233f8b867503789f536394e7005 @@ -22,11 +22,6 @@ SHA1 (patch-CVE-2015-8550) = 27f9214b9df78e04ec30e8ca56970c5b1d5dc50d SHA1 (patch-CVE-2015-8554) = 908783cf619fc130d5a107ba2c4997fca0f0da88 SHA1 (patch-Makefile) = eb5d3211b26c5f10a24fcca658c83d5f60990d9f SHA1 (patch-Rules.mk) = e0dc4234c35dc2d78afad4a90b0af829a6a10b50 -SHA1 (patch-XSA135) = c27b9c495d7348864e9939f54574e3afc37a816a -SHA1 (patch-XSA137) = 3e65d46768eb3a09dd44c2d78e1760070718cb79 -SHA1 (patch-XSA138) = ef04f40621073b1e936dfeb3711c6e9ae2a896c2 -SHA1 (patch-XSA139) = 3b86a578c86f5a3ecb127dede4bccf51d6bc7687 -SHA1 (patch-XSA140) = 55ef4eb9c4d09ac327f9600ac7553e92b9cd0624 SHA1 (patch-blktap_drivers_Makefile) = 7cc53b2a0dea1694a969046ab8542271ca63f9e7 SHA1 (patch-configure) = d1a1b9c9e00dd79bb872190282006201510ce2c1 SHA1 (patch-console_daemon_utils.c) = 915078ce6155a367e3e597fa7ab551f6afac083f diff --git a/sysutils/xentools45/patches/patch-XSA135 b/sysutils/xentools45/patches/patch-XSA135 deleted file mode 100644 index d859e64ce14..00000000000 --- a/sysutils/xentools45/patches/patch-XSA135 +++ /dev/null @@ -1,139 +0,0 @@ -$NetBSD: patch-XSA135,v 1.1 2015/06/23 17:45:33 bouyer Exp $ - -pcnet: fix Negative array index read - -From: Gonglei <arei.gonglei@huawei.com> - -s->xmit_pos maybe assigned to a negative value (-1), -but in this branch variable s->xmit_pos as an index to -array s->buffer. Let's add a check for s->xmit_pos. - -upstream-commit-id: 7b50d00911ddd6d56a766ac5671e47304c20a21b - -Signed-off-by: Gonglei <arei.gonglei@huawei.com> -Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> -Reviewed-by: Jason Wang <jasowang@redhat.com> -Reviewed-by: Jason Wang <jasowang@redhat.com> -Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> - -diff --git a/hw/pcnet.c b/hw/pcnet.c -index 7cc0637..9f3e1cc 100644 ---- qemu-xen-traditional/hw/pcnet.c.orig -+++ qemu-xen-traditional/hw/pcnet.c -@@ -1250,7 +1250,7 @@ static void pcnet_transmit(PCNetState *s) - target_phys_addr_t xmit_cxda = 0; - int count = CSR_XMTRL(s)-1; - int add_crc = 0; -- -+ int bcnt; - s->xmit_pos = -1; - - if (!CSR_TXON(s)) { -@@ -1276,34 +1276,39 @@ static void pcnet_transmit(PCNetState *s) - if (BCR_SWSTYLE(s) != 1) - add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS); - } -+ -+ if (s->xmit_pos < 0) { -+ goto txdone; -+ } -+ -+ bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); -+ s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), -+ s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); -+ s->xmit_pos += bcnt; -+ - if (!GET_FIELD(tmd.status, TMDS, ENP)) { -- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); -- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), -- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); -- s->xmit_pos += bcnt; -- } else if (s->xmit_pos >= 0) { -- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); -- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), -- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); -- s->xmit_pos += bcnt; -+ goto txdone; -+ } - #ifdef PCNET_DEBUG -- printf("pcnet_transmit size=%d\n", s->xmit_pos); -+ printf("pcnet_transmit size=%d\n", s->xmit_pos); - #endif -- if (CSR_LOOP(s)) { -- if (BCR_SWSTYLE(s) == 1) -- add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); -- s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; -- pcnet_receive(s, s->buffer, s->xmit_pos); -- s->looptest = 0; -- } else -- if (s->vc) -- qemu_send_packet(s->vc, s->buffer, s->xmit_pos); -- -- s->csr[0] &= ~0x0008; /* clear TDMD */ -- s->csr[4] |= 0x0004; /* set TXSTRT */ -- s->xmit_pos = -1; -+ if (CSR_LOOP(s)) { -+ if (BCR_SWSTYLE(s) == 1) -+ add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); -+ s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; -+ pcnet_receive(s, s->buffer, s->xmit_pos); -+ s->looptest = 0; -+ } else { -+ if (s->vc) { -+ qemu_send_packet(s->vc, s->buffer, s->xmit_pos); -+ } - } - -+ s->csr[0] &= ~0x0008; /* clear TDMD */ -+ s->csr[4] |= 0x0004; /* set TXSTRT */ -+ s->xmit_pos = -1; -+ -+ txdone: - SET_FIELD(&tmd.status, TMDS, OWN, 0); - TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); - if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT))) -From 2630672ab22255de252f877709851c0557a1c647 Mon Sep 17 00:00:00 2001 -From: Petr Matousek <pmatouse@redhat.com> -Date: Sun, 24 May 2015 10:53:44 +0200 -Subject: [PATCH] pcnet: force the buffer access to be in bounds during tx - -4096 is the maximum length per TMD and it is also currently the size of -the relay buffer pcnet driver uses for sending the packet data to QEMU -for further processing. With packet spanning multiple TMDs it can -happen that the overall packet size will be bigger than sizeof(buffer), -which results in memory corruption. - -Fix this by only allowing to queue maximum sizeof(buffer) bytes. - -This is CVE-2015-3209. - -Signed-off-by: Petr Matousek <pmatouse@redhat.com> -Reported-by: Matt Tait <matttait@google.com> -Reviewed-by: Peter Maydell <peter.maydell@linaro.org> -Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> ---- - hw/pcnet.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/pcnet.c b/hw/pcnet.c -index bdfd38f..6d32e4c 100644 ---- qemu-xen-traditional/hw/pcnet.c.orig -+++ qemu-xen-traditional/hw/pcnet.c -@@ -1241,6 +1241,14 @@ static void pcnet_transmit(PCNetState *s) - } - - bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); -+ -+ /* if multi-tmd packet outsizes s->buffer then skip it silently. -+ Note: this is not what real hw does */ -+ if (s->xmit_pos + bcnt > sizeof(s->buffer)) { -+ s->xmit_pos = -1; -+ goto txdone; -+ } -+ - s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), - s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); - s->xmit_pos += bcnt; --- -2.1.0 - diff --git a/sysutils/xentools45/patches/patch-XSA137 b/sysutils/xentools45/patches/patch-XSA137 deleted file mode 100644 index d36320e12d9..00000000000 --- a/sysutils/xentools45/patches/patch-XSA137 +++ /dev/null @@ -1,175 +0,0 @@ -$NetBSD: patch-XSA137,v 1.1 2015/08/23 17:02:58 spz Exp $ - -patch for CVE-2015-3259 aka XSA-137 from: -http://xenbits.xen.org/xsa/xsa137.patch - ---- libxl/xl_cmdimpl.c.orig 2015-06-22 13:41:35.000000000 +0000 -+++ 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 */ -@@ -4570,11 +4570,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; -@@ -4589,6 +4603,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++; -@@ -4628,20 +4644,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; -@@ -4649,16 +4666,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; - } - -@@ -4666,8 +4685,7 @@ int main_config_update(int argc, char ** - { - 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; -@@ -4705,15 +4723,15 @@ int main_config_update(int argc, char ** - 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; - } - } -@@ -4722,7 +4740,8 @@ int main_config_update(int argc, char ** - 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"); -@@ -4763,7 +4782,7 @@ int main_config_update(int argc, char ** - libxl_domain_config_dispose(&d_config); - - free(config_data); -- -+ free(extra_config); - return 0; - } - -@@ -7020,7 +7039,7 @@ int main_cpupoolcreate(int argc, char ** - { - 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'}, -@@ -7054,13 +7073,10 @@ int main_cpupoolcreate(int argc, char ** - 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 { diff --git a/sysutils/xentools45/patches/patch-XSA138 b/sysutils/xentools45/patches/patch-XSA138 deleted file mode 100644 index 196066a7bd0..00000000000 --- a/sysutils/xentools45/patches/patch-XSA138 +++ /dev/null @@ -1,175 +0,0 @@ -$NetBSD: patch-XSA138,v 1.1 2015/08/23 17:02:58 spz Exp $ - -patch for CVE-2015-5154 from XSA-138 from -http://xenbits.xen.org/xsa/xsa138-qemut-1.patch -http://xenbits.xen.org/xsa/xsa138-qemut-2.patch -http://xenbits.xen.org/xsa/xsa138-qemuu-1.patch -http://xenbits.xen.org/xsa/xsa138-qemuu-2.patch -http://xenbits.xen.org/xsa/xsa138-qemuu-3.patch - ---- qemu-xen/hw/ide/core.c.orig 2015-06-10 11:43:51.000000000 +0000 -+++ qemu-xen/hw/ide/core.c -@@ -1901,11 +1901,17 @@ void ide_data_writew(void *opaque, uint3 - } - - p = s->data_ptr; -+ if (p + 2 > s->data_end) { -+ return; -+ } -+ - *(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) -@@ -1922,11 +1928,17 @@ uint32_t ide_data_readw(void *opaque, ui - } - - 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; -- if (p >= s->data_end) -+ if (p >= s->data_end) { -+ s->status &= ~DRQ_STAT; - s->end_transfer_func(s); -+ } - return ret; - } - -@@ -1943,11 +1955,17 @@ void ide_data_writel(void *opaque, uint3 - } - - p = s->data_ptr; -+ if (p + 4 > s->data_end) { -+ return; -+ } -+ - *(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) -@@ -1964,11 +1982,17 @@ uint32_t ide_data_readl(void *opaque, ui - } - - 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; -- if (p >= s->data_end) -+ if (p >= s->data_end) { -+ s->status &= ~DRQ_STAT; - s->end_transfer_func(s); -+ } - return ret; - } - ---- qemu-xen/hw/ide/atapi.c.orig 2015-06-10 11:43:51.000000000 +0000 -+++ qemu-xen/hw/ide/atapi.c -@@ -879,6 +879,7 @@ static void cmd_start_stop_unit(IDEState - - if (pwrcnd) { - /* eject/load only happens for power condition == 0 */ -+ ide_atapi_cmd_ok(s); - return; - } - ---- qemu-xen-traditional/hw/ide.c.orig 2015-08-23 15:08:13.000000000 +0000 -+++ qemu-xen-traditional/hw/ide.c -@@ -3006,11 +3006,17 @@ static void ide_data_writew(void *opaque - buffered_pio_write(s, addr, 2); - - p = s->data_ptr; -+ if (p + 2 > s->data_end) { -+ return; -+ } -+ - *(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); -+ } - } - - static uint32_t ide_data_readw(void *opaque, uint32_t addr) -@@ -3025,11 +3031,17 @@ static uint32_t ide_data_readw(void *opa - buffered_pio_read(s, addr, 2); - - 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; -- if (p >= s->data_end) -+ if (p >= s->data_end) { -+ s->status &= ~DRQ_STAT; - s->end_transfer_func(s); -+ } - return ret; - } - -@@ -3044,11 +3056,17 @@ static void ide_data_writel(void *opaque - buffered_pio_write(s, addr, 4); - - p = s->data_ptr; -+ if (p + 4 > s->data_end) { -+ return; -+ } -+ - *(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); -+ } - } - - static uint32_t ide_data_readl(void *opaque, uint32_t addr) -@@ -3063,11 +3081,17 @@ static uint32_t ide_data_readl(void *opa - buffered_pio_read(s, addr, 4); - - 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; -- if (p >= s->data_end) -+ if (p >= s->data_end) { -+ s->status &= ~DRQ_STAT; - s->end_transfer_func(s); -+ } - return ret; - } - diff --git a/sysutils/xentools45/patches/patch-XSA139 b/sysutils/xentools45/patches/patch-XSA139 deleted file mode 100644 index ffff15d5cdd..00000000000 --- a/sysutils/xentools45/patches/patch-XSA139 +++ /dev/null @@ -1,28 +0,0 @@ -$NetBSD: patch-XSA139,v 1.1 2015/08/23 17:02:58 spz Exp $ - -patch for CVE-2015-5166 aka XSA-139 from -http://xenbits.xen.org/xsa/xsa139-qemuu-4.5.patch - ---- qemu-xen/hw/ide/piix.c.orig 2015-06-10 11:43:51.000000000 +0000 -+++ qemu-xen/hw/ide/piix.c -@@ -172,6 +172,7 @@ int pci_piix3_xen_ide_unplug(DeviceState - 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 - } - 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); - } - } diff --git a/sysutils/xentools45/patches/patch-XSA140 b/sysutils/xentools45/patches/patch-XSA140 deleted file mode 100644 index 64199e48c3e..00000000000 --- a/sysutils/xentools45/patches/patch-XSA140 +++ /dev/null @@ -1,433 +0,0 @@ -$NetBSD: patch-XSA140,v 1.1 2015/08/23 17:02:58 spz Exp $ - -patch for CVE-2015-5165 aka XSA-140 from -http://xenbits.xen.org/xsa/xsa140-qemuu-unstable-1.patch -http://xenbits.xen.org/xsa/xsa140-qemuu-unstable-2.patch -http://xenbits.xen.org/xsa/xsa140-qemuu-unstable-3.patch -http://xenbits.xen.org/xsa/xsa140-qemuu-unstable-4.patch -http://xenbits.xen.org/xsa/xsa140-qemuu-unstable-5.patch -http://xenbits.xen.org/xsa/xsa140-qemuu-unstable-6.patch -http://xenbits.xen.org/xsa/xsa140-qemuu-unstable-7.patch - ---- qemu-xen/hw/net/rtl8139.c.orig 2015-06-10 11:43:51.000000000 +0000 -+++ qemu-xen/hw/net/rtl8139.c -@@ -2161,6 +2161,11 @@ static int rtl8139_cplus_transmit_one(RT - { - 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; -@@ -2171,223 +2176,235 @@ static int rtl8139_cplus_transmit_one(RT - 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"); -+ goto skip_offload; -+ } - -- /* 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; -- } -+ 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); -+ if (hlen < sizeof(ip_header) || hlen > eth_payload_len) { -+ goto skip_offload; - } - -- if (ip) -+ ip_protocol = ip->ip_p; -+ -+ 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) - { -- if (txdw0 & CP_TX_IPCS) -- { -- DPRINTF("+++ C+ mode need IP checksum\n"); -+ DPRINTF("+++ C+ mode need IP checksum\n"); - -- if (hlen<sizeof(ip_header) || hlen>eth_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) -+ { -+ /* Large enough for the TCP header? */ -+ if (ip_data_len < sizeof(tcp_header)) { -+ goto skip_offload; - } - -- if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) -- { -- int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; -+ int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; - -- 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); -+ 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); - -- int tcp_send_offset = 0; -- int send_count = 0; -+ int tcp_send_offset = 0; -+ int send_count = 0; - -- /* maximum IP header length is 60 bytes */ -- uint8_t saved_ip_header[60]; -+ /* maximum IP header length is 60 bytes */ -+ uint8_t saved_ip_header[60]; - -- /* save IP header template; data area is used in tcp checksum calculation */ -- memcpy(saved_ip_header, eth_payload_data, hlen); -+ /* save IP header template; data area is used in tcp checksum calculation */ -+ memcpy(saved_ip_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; -+ /* 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; - -- /* pointer to TCP header */ -- tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); -+ /* pointer to TCP header */ -+ tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); - -- int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); -+ int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); - -- /* 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; -+ /* Invalid TCP data offset? */ -+ if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) { -+ goto skip_offload; -+ } - -- 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; -+ int is_last_frame = 0; - -- /* 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; -- } -- -- /* 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) -+ { -+ 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) - { -- DPRINTF("+++ C+ mode calculating TCP checksum for " -- "packet with %d bytes data\n", ip_data_len); -+ TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); -+ } - -- 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); -+ /* 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); - -- tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); -+ p_tcp_hdr->th_sum = tcp_checksum; - -- p_tcp_hdr->th_sum = 0; -+ /* restore IP header */ -+ memcpy(eth_payload_data, saved_ip_header, hlen); - -- int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); -- DPRINTF("+++ C+ mode TCP checksum %04x\n", -- tcp_checksum); -+ /* set IP data length and recalculate IP checksum */ -+ ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); - -- 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); -+ /* 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_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); -+ 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; -+ } - -- udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); -+ /* 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"); - -- p_udp_hdr->uh_sum = 0; -+ /* maximum IP header length is 60 bytes */ -+ uint8_t saved_ip_header[60]; -+ memcpy(saved_ip_header, eth_payload_data, hlen); - -- int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); -- DPRINTF("+++ C+ mode UDP checksum %04x\n", -- udp_checksum); -+ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; -+ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; - -- p_udp_hdr->uh_sum = udp_checksum; -- } -+ /* add 4 TCP pseudoheader fields */ -+ /* copy IP source and destination fields */ -+ memcpy(data_to_checksum, saved_ip_header + 12, 8); - -- /* restore IP header */ -- memcpy(eth_payload_data, saved_ip_header, hlen); -+ 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); - } - } - -+skip_offload: - /* update tally counter */ - ++s->tally_counters.TxOk; - |