xen_4.1.6.1-1+deb7u2.dsc
Attached is the diff from xen_4.1.6.1-1+deb7u1.dsc to
xen_4.1.6.1-1+deb7u2.dsc from credativ that I plan to upload within the
next several days (unless I get feedback I should do it sooner or
later).
Downloaded from
https://people.debian.org/~zobel/xen-lts/xen_4.1.6.1-1+deb7u2.dsc
--
Brian May <brian@linuxpenguins.xyz>
https://linuxpenguins.xyz/brian/
diff -Nru xen-4.1.6.1/debian/changelog xen-4.1.6.1/debian/changelog
--- xen-4.1.6.1/debian/changelog 2016-05-17 08:31:20.000000000 +1000
+++ xen-4.1.6.1/debian/changelog 2016-06-01 21:32:03.000000000 +1000
@@ -1,3 +1,30 @@
+xen (4.1.6.1-1+deb7u2) wheezy-security; urgency=low
+
+ * Non-maintainer upload by the LTS Team.
+ * Various security fixes:
+ * ioreq handling possibly susceptible to multiple read issue
+ XSA-166
+ * fix DoS by writing to stdout or stderr.
+ CVE-2014-3672
+ * handle writes to the hardware FSW.ES bit when running on AMD64 processors
+ properly (Closes: #823620)
+ CVE-2016-3158
+ * handle writes to the hardware FSW.ES bit when running on AMD64 processors
+ properly (Closes: 823620)
+ CVE-2016-3159
+ * properly perform bounds checking on banked access to video memory in the
+ VGA module (Closes: #823830)
+ CVE-2016-3710
+ * fix integer overflow in the VGA module (Closes: #823830)
+ CVE-2016-3712
+ * fix integer overflow in the x86 shadow pagetable code (Closes: #823620)
+ CVE-2016-3960
+ * handle the Page Size (PS) page table entry bit at the L4 and L3 page
+ table levels properly
+ CVE-2016-4480
+
+ -- Martin Zobel-Helas <zobel@debian.org> Wed, 01 Jun 2016 13:15:36 +0200
+
xen (4.1.6.1-1+deb7u1) wheezy-security; urgency=high
[ Antoine Beaupré ]
diff -Nru xen-4.1.6.1/debian/patches/series xen-4.1.6.1/debian/patches/series
--- xen-4.1.6.1/debian/patches/series 2016-05-05 04:35:43.000000000 +1000
+++ xen-4.1.6.1/debian/patches/series 2016-06-01 21:15:21.000000000 +1000
@@ -148,3 +148,14 @@
CVE-2015-4106.8.patch
CVE-2015-7835-xsa148.patch
+
+xsa166-4.3.patch
+xsa172-4.3.patch
+xsa173-4.3.patch
+xsa176.patch
+xsa179-qemut-unstable-0001-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch
+xsa179-qemut-unstable-0002-vga-add-vbe_enabled-helper.patch
+xsa179-qemut-unstable-0003-vga-factor-out-vga-register-setup.patch
+xsa179-qemut-unstable-0004-vga-update-vga-register-setup-on-vbe-changes.patch
+xsa179-qemut-unstable-0005-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
+xsa180-qemut.patch
diff -Nru xen-4.1.6.1/debian/patches/xsa166-4.3.patch xen-4.1.6.1/debian/patches/xsa166-4.3.patch
--- xen-4.1.6.1/debian/patches/xsa166-4.3.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa166-4.3.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,50 @@
+x86/HVM: avoid reading ioreq state more than once
+
+Otherwise, especially when the compiler chooses to translate the
+switch() to a jump table, unpredictable behavior (and in the jump table
+case arbitrary code execution) can result.
+
+This is XSA-166.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Acked-by: Ian Campbell <ian.campbell@citrix.com>
+
+Index: xen-4.1.6.1/xen/arch/x86/hvm/hvm.c
+===================================================================
+--- xen-4.1.6.1.orig/xen/arch/x86/hvm/hvm.c 2016-05-31 11:05:09.000000000 +0000
++++ xen-4.1.6.1/xen/arch/x86/hvm/hvm.c 2016-05-31 11:05:54.000000000 +0000
+@@ -316,6 +316,7 @@
+ void hvm_do_resume(struct vcpu *v)
+ {
+ ioreq_t *p;
++ unsigned int state;
+
+ pt_restore_timer(v);
+
+@@ -323,9 +324,10 @@
+
+ /* NB. Optimised for common case (p->state == STATE_IOREQ_NONE). */
+ p = get_ioreq(v);
+- while ( p->state != STATE_IOREQ_NONE )
++ while ( (state = p->state) != STATE_IOREQ_NONE )
+ {
+- switch ( p->state )
++ rmb();
++ switch ( state )
+ {
+ case STATE_IORESP_READY: /* IORESP_READY -> NONE */
+ hvm_io_assist();
+@@ -333,11 +335,10 @@
+ case STATE_IOREQ_READY: /* IOREQ_{READY,INPROCESS} -> IORESP_READY */
+ case STATE_IOREQ_INPROCESS:
+ wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port,
+- (p->state != STATE_IOREQ_READY) &&
+- (p->state != STATE_IOREQ_INPROCESS));
++ p->state != state);
+ break;
+ default:
+- gdprintk(XENLOG_ERR, "Weird HVM iorequest state %d.\n", p->state);
++ gdprintk(XENLOG_ERR, "Weird HVM iorequest state %u\n", state);
+ domain_crash(v->domain);
+ return; /* bail */
+ }
diff -Nru xen-4.1.6.1/debian/patches/xsa172-4.3.patch xen-4.1.6.1/debian/patches/xsa172-4.3.patch
--- xen-4.1.6.1/debian/patches/xsa172-4.3.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa172-4.3.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,27 @@
+x86: fix information leak on AMD CPUs
+
+The fix for XSA-52 was wrong, and so was the change synchronizing that
+new behavior to the FXRSTOR logic: AMD's manuals explictly state that
+writes to the ES bit are ignored, and it instead gets calculated from
+the exception and mask bits (it gets set whenever there is an unmasked
+exception, and cleared otherwise). Hence we need to follow that model
+in our workaround.
+
+This is XSA-172 / CVE-2016-3158.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+Index: xen-4.1.6.1/xen/arch/x86/i387.c
+===================================================================
+--- xen-4.1.6.1.orig/xen/arch/x86/i387.c 2016-05-31 09:28:06.000000000 +0000
++++ xen-4.1.6.1/xen/arch/x86/i387.c 2016-05-31 09:52:08.000000000 +0000
+@@ -52,7 +52,7 @@
+ * data block as a safe address because it should be in L1.
+ */
+ if ( (ptr->xsave_hdr.xstate_bv & XSTATE_FP) &&
+- !(ptr->fpu_sse.fsw & 0x0080) &&
++ !(ptr->fpu_sse.fsw & ~ptr->fpu_sse.fcw & 0x003f) &&
+ boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+ asm volatile ( "fnclex\n\t" /* clear exceptions */
+ "ffree %%st(7)\n\t" /* clear stack tag */
diff -Nru xen-4.1.6.1/debian/patches/xsa173-4.3.patch xen-4.1.6.1/debian/patches/xsa173-4.3.patch
--- xen-4.1.6.1/debian/patches/xsa173-4.3.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa173-4.3.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,236 @@
+commit 95dd1b6e87b61222fc856724a5d828c9bdc30c80
+Author: Tim Deegan <tim@xen.org>
+Date: Wed Mar 16 17:07:18 2016 +0000
+
+ x86: limit GFNs to 32 bits for shadowed superpages.
+
+ Superpage shadows store the shadowed GFN in the backpointer field,
+ which for non-BIGMEM builds is 32 bits wide. Shadowing a superpage
+ mapping of a guest-physical address above 2^44 would lead to the GFN
+ being truncated there, and a crash when we come to remove the shadow
+ from the hash table.
+
+ Track the valid width of a GFN for each guest, including reporting it
+ through CPUID, and enforce it in the shadow pagetables. Set the
+ maximum witth to 32 for guests where this truncation could occur.
+
+ This is XSA-173.
+
+ Signed-off-by: Tim Deegan <tim@xen.org>
+ Signed-off-by: Jan Beulich <jbeulich@suse.com>
+
+Reported-by: Ling Liu <liuling-it@360.cn>
+Index: xen-4.1.6.1/xen/arch/x86/cpu/common.c
+===================================================================
+--- xen-4.1.6.1.orig/xen/arch/x86/cpu/common.c 2013-09-10 06:42:18.000000000 +0000
++++ xen-4.1.6.1/xen/arch/x86/cpu/common.c 2016-05-31 10:50:16.000000000 +0000
+@@ -44,6 +44,7 @@
+ struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
+
+ unsigned int paddr_bits __read_mostly = 36;
++unsigned int hap_paddr_bits __read_mostly = 36;
+
+ /*
+ * Default host IA32_CR_PAT value to cover all memory types.
+@@ -279,7 +280,7 @@
+
+ void __cpuinit generic_identify(struct cpuinfo_x86 * c)
+ {
+- u32 tfms, xlvl;
++ u32 tfms, xlvl, eax;
+
+ if (have_cpuid_p()) {
+ /* Get vendor name */
+@@ -321,8 +322,11 @@
+ }
+ if ( xlvl >= 0x80000004 )
+ get_model_name(c); /* Default name */
+- if ( xlvl >= 0x80000008 )
+- paddr_bits = cpuid_eax(0x80000008) & 0xff;
++ if ( xlvl >= 0x80000008 ) {
++ eax = cpuid_eax(0x80000008);
++ paddr_bits = eax & 0xff;
++ hap_paddr_bits = ((eax >> 16) & 0xff) ?: paddr_bits;
++ }
+ }
+
+ /* Intel-defined flags: level 0x00000007 */
+Index: xen-4.1.6.1/xen/arch/x86/mm/guest_walk.c
+===================================================================
+--- xen-4.1.6.1.orig/xen/arch/x86/mm/guest_walk.c 2013-09-10 06:42:18.000000000 +0000
++++ xen-4.1.6.1/xen/arch/x86/mm/guest_walk.c 2016-05-31 10:49:28.000000000 +0000
+@@ -92,6 +92,12 @@
+ p2m_type_t *p2mt,
+ uint32_t *rc)
+ {
++ if ( gfn_x(gfn) >> p2m->domain->arch.paging.gfn_bits )
++ {
++ *rc = _PAGE_INVALID_BIT;
++ return NULL;
++ }
++
+ /* Translate the gfn, unsharing if shared */
+ *mfn = gfn_to_mfn_unshare(p2m, gfn_x(gfn), p2mt, 0);
+ if ( p2m_is_paging(*p2mt) )
+@@ -250,20 +256,7 @@
+ #define GUEST_L2_GFN_ALIGN (1 << (GUEST_L2_PAGETABLE_SHIFT - \
+ GUEST_L1_PAGETABLE_SHIFT))
+ if ( gfn_x(start) & (GUEST_L2_GFN_ALIGN - 1) & ~0x1 )
+- {
+-#if GUEST_PAGING_LEVELS == 2
+- /*
+- * Note that _PAGE_INVALID_BITS is zero in this case, yielding a
+- * no-op here.
+- *
+- * Architecturally, the walk should fail if bit 21 is set (others
+- * aren't being checked at least in PSE36 mode), but we'll ignore
+- * this here in order to avoid specifying a non-natural, non-zero
+- * _PAGE_INVALID_BITS value just for that case.
+- */
+-#endif
+ rc |= _PAGE_INVALID_BITS;
+- }
+
+ /* Increment the pfn by the right number of 4k pages.
+ * Mask out PAT and invalid bits. */
+@@ -327,5 +320,11 @@
+ #endif
+ if ( l1p ) unmap_domain_page(l1p);
+
++ /* If this guest has a restricted physical address space then the
++ * target GFN must fit within it. */
++ if ( !(rc & _PAGE_PRESENT)
++ && gfn_x(guest_l1e_get_gfn(gw->l1e)) >> d->arch.paging.gfn_bits )
++ rc |= _PAGE_INVALID_BITS;
++
+ return rc;
+ }
+Index: xen-4.1.6.1/xen/arch/x86/mm/hap/hap.c
+===================================================================
+--- xen-4.1.6.1.orig/xen/arch/x86/mm/hap/hap.c 2016-05-31 09:28:06.000000000 +0000
++++ xen-4.1.6.1/xen/arch/x86/mm/hap/hap.c 2016-05-31 09:53:47.000000000 +0000
+@@ -545,6 +545,7 @@
+ void hap_domain_init(struct domain *d)
+ {
+ INIT_PAGE_LIST_HEAD(&d->arch.paging.hap.freelist);
++ d->arch.paging.gfn_bits = hap_paddr_bits - PAGE_SHIFT;
+ }
+
+ /* return 0 for success, -errno for failure */
+Index: xen-4.1.6.1/xen/arch/x86/mm/shadow/common.c
+===================================================================
+--- xen-4.1.6.1.orig/xen/arch/x86/mm/shadow/common.c 2016-05-31 09:28:06.000000000 +0000
++++ xen-4.1.6.1/xen/arch/x86/mm/shadow/common.c 2016-05-31 09:53:47.000000000 +0000
+@@ -48,6 +48,16 @@
+ INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.freelist);
+ INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.pinned_shadows);
+
++ d->arch.paging.gfn_bits = paddr_bits - PAGE_SHIFT;
++#ifndef CONFIG_BIGMEM
++ /*
++ * Shadowed superpages store GFNs in 32-bit page_info fields.
++ * Note that we cannot use guest_supports_superpages() here.
++ */
++ if ( is_hvm_domain(d) || opt_allow_superpage )
++ d->arch.paging.gfn_bits = 32;
++#endif
++
+ /* Use shadow pagetables for log-dirty support */
+ paging_log_dirty_init(d, shadow_enable_log_dirty,
+ shadow_disable_log_dirty, shadow_clean_dirty_bitmap);
+Index: xen-4.1.6.1/xen/arch/x86/mm/shadow/multi.c
+===================================================================
+--- xen-4.1.6.1.orig/xen/arch/x86/mm/shadow/multi.c 2016-05-31 09:28:06.000000000 +0000
++++ xen-4.1.6.1/xen/arch/x86/mm/shadow/multi.c 2016-05-31 09:53:47.000000000 +0000
+@@ -525,7 +525,8 @@
+ ASSERT(GUEST_PAGING_LEVELS > 3 || level != 3);
+
+ /* Check there's something for the shadows to map to */
+- if ( !p2m_is_valid(p2mt) && !p2m_is_grant(p2mt) )
++ if ( (!p2m_is_valid(p2mt) && !p2m_is_grant(p2mt))
++ || gfn_x(target_gfn) >> d->arch.paging.gfn_bits )
+ {
+ *sp = shadow_l1e_empty();
+ goto done;
+Index: xen-4.1.6.1/xen/include/asm-x86/domain.h
+===================================================================
+--- xen-4.1.6.1.orig/xen/include/asm-x86/domain.h 2016-05-31 09:28:06.000000000 +0000
++++ xen-4.1.6.1/xen/include/asm-x86/domain.h 2016-05-31 09:53:47.000000000 +0000
+@@ -193,6 +193,9 @@
+ /* log dirty support */
+ struct log_dirty_domain log_dirty;
+
++ /* Number of valid bits in a gfn. */
++ unsigned int gfn_bits;
++
+ /* preemption handling */
+ struct {
+ const struct domain *dom;
+Index: xen-4.1.6.1/xen/include/asm-x86/guest_pt.h
+===================================================================
+--- xen-4.1.6.1.orig/xen/include/asm-x86/guest_pt.h 2013-09-10 06:42:18.000000000 +0000
++++ xen-4.1.6.1/xen/include/asm-x86/guest_pt.h 2016-05-31 09:53:47.000000000 +0000
+@@ -204,15 +204,17 @@
+ }
+
+
+-/* Some bits are invalid in any pagetable entry. */
+-#if GUEST_PAGING_LEVELS == 2
+-#define _PAGE_INVALID_BITS (0)
+-#elif GUEST_PAGING_LEVELS == 3
++/*
++ * Some bits are invalid in any pagetable entry.
++ * Normal flags values get represented in 24-bit values (see
++ * get_pte_flags() and put_pte_flags()), so set bit 24 in
++ * addition to be able to flag out of range frame numbers.
++ */
++#if GUEST_PAGING_LEVELS == 3
+ #define _PAGE_INVALID_BITS \
+- get_pte_flags(((1ull<<63) - 1) & ~((1ull<<paddr_bits) - 1))
+-#else /* GUEST_PAGING_LEVELS == 4 */
+-#define _PAGE_INVALID_BITS \
+- get_pte_flags(((1ull<<52) - 1) & ~((1ull<<paddr_bits) - 1))
++ (_PAGE_INVALID_BIT | get_pte_flags(((1ull << 63) - 1) & ~(PAGE_SIZE - 1)))
++#else /* 2-level and 4-level */
++#define _PAGE_INVALID_BITS _PAGE_INVALID_BIT
+ #endif
+
+
+Index: xen-4.1.6.1/xen/include/asm-x86/processor.h
+===================================================================
+--- xen-4.1.6.1.orig/xen/include/asm-x86/processor.h 2013-09-10 06:42:18.000000000 +0000
++++ xen-4.1.6.1/xen/include/asm-x86/processor.h 2016-05-31 09:53:47.000000000 +0000
+@@ -203,6 +203,8 @@
+
+ /* Maximum width of physical addresses supported by the hardware */
+ extern unsigned int paddr_bits;
++/* Max physical address width supported within HAP guests */
++extern unsigned int hap_paddr_bits;
+
+ extern void identify_cpu(struct cpuinfo_x86 *);
+ extern void setup_clear_cpu_cap(unsigned int);
+Index: xen-4.1.6.1/xen/include/asm-x86/x86_64/page.h
+===================================================================
+--- xen-4.1.6.1.orig/xen/include/asm-x86/x86_64/page.h 2016-05-31 09:28:06.000000000 +0000
++++ xen-4.1.6.1/xen/include/asm-x86/x86_64/page.h 2016-05-31 09:53:47.000000000 +0000
+@@ -180,6 +180,7 @@
+
+ #define USER_MAPPINGS_ARE_GLOBAL
+ #ifdef USER_MAPPINGS_ARE_GLOBAL
++
+ /*
+ * Bit 12 of a 24-bit flag mask. This corresponds to bit 52 of a pte.
+ * This is needed to distinguish between user and kernel PTEs since _PAGE_USER
+@@ -193,6 +194,12 @@
+ #define _PAGE_GUEST_KERNEL 0
+ #endif
+
++/*
++ * Bit 24 of a 24-bit flag mask! This is not any bit of a real pte,
++ * and is only used for signalling in variables that contain flags.
++ */
++#define _PAGE_INVALID_BIT (1U<<24)
++
+ #endif /* __X86_64_PAGE_H__ */
+
+ /*
diff -Nru xen-4.1.6.1/debian/patches/xsa176.patch xen-4.1.6.1/debian/patches/xsa176.patch
--- xen-4.1.6.1/debian/patches/xsa176.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa176.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,29 @@
+x86/mm: fully honor PS bits in guest page table walks
+
+In L4 entries it is currently unconditionally reserved (and hence
+should, when set, always result in a reserved bit page fault), and is
+reserved on hardware not supporting 1Gb pages (and hence should, when
+set, similarly cause a reserved bit page fault on such hardware).
+
+This is CVE-2016-4480 / XSA-176.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+Index: xen-4.1.6.1/xen/arch/x86/mm/guest_walk.c
+===================================================================
+--- xen-4.1.6.1.orig/xen/arch/x86/mm/guest_walk.c 2016-05-31 09:57:37.000000000 +0000
++++ xen-4.1.6.1/xen/arch/x86/mm/guest_walk.c 2016-05-31 09:59:42.000000000 +0000
+@@ -172,6 +172,11 @@
+ rc |= _PAGE_PRESENT;
+ goto out;
+ }
++ if ( gflags & _PAGE_PSE )
++ {
++ rc |= _PAGE_PSE | _PAGE_INVALID_BIT;
++ goto out;
++ }
+ rc |= ((gflags & mflags) ^ mflags);
+
+ /* Map the l3 table */
diff -Nru xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0001-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0001-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch
--- xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0001-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0001-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,107 @@
+From bebb4f580901fb638016d9851a28dbb83d44b3a6 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 08:49:10 +0200
+Subject: [PATCH 1/5] vga: fix banked access bounds checking (CVE-2016-3710)
+
+vga allows banked access to video memory using the window at 0xa00000
+and it supports a different access modes with different address
+calculations.
+
+The VBE bochs extentions support banked access too, using the
+VBE_DISPI_INDEX_BANK register. The code tries to take the different
+address calculations into account and applies different limits to
+VBE_DISPI_INDEX_BANK depending on the current access mode.
+
+Which is probably effective in stopping misprogramming by accident.
+But from a security point of view completely useless as an attacker
+can easily change access modes after setting the bank register.
+
+Drop the bogus check, add range checks to vga_mem_{readb,writeb}
+instead.
+
+Fixes: CVE-2016-3710
+Reported-by: Qinghao Tang <luodalongde@gmail.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+[Backport to qemu-xen-tradition]
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+---
+ hw/vga.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+Index: xen-4.1.6.1/qemu/hw/vga.c
+===================================================================
+--- xen-4.1.6.1.orig/qemu/hw/vga.c 2013-07-17 10:59:40.000000000 +0000
++++ xen-4.1.6.1/qemu/hw/vga.c 2016-05-31 10:04:36.000000000 +0000
+@@ -34,6 +34,8 @@
+
+ #include "qemu-timer.h"
+
++#include <assert.h>
++
+ //#define DEBUG_VGA
+ //#define DEBUG_VGA_MEM
+ //#define DEBUG_VGA_REG
+@@ -606,11 +608,7 @@
+ }
+ break;
+ case VBE_DISPI_INDEX_BANK:
+- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
+- val &= (s->vbe_bank_mask >> 2);
+- } else {
+- val &= s->vbe_bank_mask;
+- }
++ val &= s->vbe_bank_mask;
+ s->vbe_regs[s->vbe_index] = val;
+ s->bank_offset = (val << 16);
+ break;
+@@ -751,13 +749,21 @@
+
+ if (s->sr[4] & 0x08) {
+ /* chain 4 mode : simplest access */
++ assert(addr < s->vram_size);
+ ret = s->vram_ptr[addr];
+ } else if (s->gr[5] & 0x10) {
+ /* odd/even mode (aka text mode mapping) */
+ plane = (s->gr[4] & 2) | (addr & 1);
+- ret = s->vram_ptr[((addr & ~1) << 1) | plane];
++ addr = ((addr & ~1) << 1) | plane;
++ if (addr >= s->vram_size) {
++ return 0xff;
++ }
++ ret = s->vram_ptr[addr];
+ } else {
+ /* standard VGA latched access */
++ if (addr * sizeof(uint32_t) >= s->vram_size) {
++ return 0xff;
++ }
+ s->latch = ((uint32_t *)s->vram_ptr)[addr];
+
+ if (!(s->gr[5] & 0x08)) {
+@@ -844,6 +850,7 @@
+ plane = addr & 3;
+ mask = (1 << plane);
+ if (s->sr[2] & mask) {
++ assert(addr < s->vram_size);
+ s->vram_ptr[addr] = val;
+ #ifdef DEBUG_VGA_MEM
+ printf("vga: chain4: [0x%x]\n", addr);
+@@ -857,6 +864,9 @@
+ mask = (1 << plane);
+ if (s->sr[2] & mask) {
+ addr = ((addr & ~1) << 1) | plane;
++ if (addr >= s->vram_size) {
++ return;
++ }
+ s->vram_ptr[addr] = val;
+ #ifdef DEBUG_VGA_MEM
+ printf("vga: odd/even: [0x%x]\n", addr);
+@@ -929,6 +939,9 @@
+ mask = s->sr[2];
+ s->plane_updated |= mask; /* only used to detect font change */
+ write_mask = mask16[mask];
++ if (addr * sizeof(uint32_t) >= s->vram_size) {
++ return;
++ }
+ ((uint32_t *)s->vram_ptr)[addr] =
+ (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
+ (val & write_mask);
diff -Nru xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0002-vga-add-vbe_enabled-helper.patch xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0002-vga-add-vbe_enabled-helper.patch
--- xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0002-vga-add-vbe_enabled-helper.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0002-vga-add-vbe_enabled-helper.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,57 @@
+From 34db09fb9967441408a1ff0579d553222cf17441 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 14:11:34 +0200
+Subject: [PATCH 2/5] vga: add vbe_enabled() helper
+
+Makes code a bit easier to read.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+[Backport to qemu-xen-tradition]
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+---
+ hw/vga.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+Index: xen-4.1.6.1/qemu/hw/vga.c
+===================================================================
+--- xen-4.1.6.1.orig/qemu/hw/vga.c 2016-05-31 10:04:36.000000000 +0000
++++ xen-4.1.6.1/qemu/hw/vga.c 2016-05-31 10:04:46.000000000 +0000
+@@ -160,6 +160,11 @@
+ static uint16_t expand2[256];
+ static uint8_t expand4to8[16];
+
++static inline bool vbe_enabled(VGAState *s)
++{
++ return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
++}
++
+ static void vga_bios_init(VGAState *s);
+ static void vga_screen_dump(void *opaque, const char *filename);
+
+@@ -1129,7 +1134,7 @@
+ {
+ uint32_t start_addr, line_offset, line_compare;
+ #ifdef CONFIG_BOCHS_VBE
+- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
++ if (vbe_enabled(s)) {
+ line_offset = s->vbe_line_offset;
+ start_addr = s->vbe_start_addr;
+ line_compare = 65535;
+@@ -1515,7 +1520,7 @@
+ {
+ int ret;
+ #ifdef CONFIG_BOCHS_VBE
+- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
++ if (vbe_enabled(s)) {
+ ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
+ } else
+ #endif
+@@ -1530,7 +1535,7 @@
+ int width, height;
+
+ #ifdef CONFIG_BOCHS_VBE
+- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
++ if (vbe_enabled(s)) {
+ width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
+ height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
+ } else
diff -Nru xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0003-vga-factor-out-vga-register-setup.patch xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0003-vga-factor-out-vga-register-setup.patch
--- xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0003-vga-factor-out-vga-register-setup.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0003-vga-factor-out-vga-register-setup.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,118 @@
+From df228023ce39e8b72bd5a198b8703319b8b9ca23 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 15:24:18 +0200
+Subject: [PATCH 3/5] vga: factor out vga register setup
+
+When enabling vbe mode qemu will setup a bunch of vga registers to make
+sure the vga emulation operates in correct mode for a linear
+framebuffer. Move that code to a separate function so we can call it
+from other places too.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+[Backport to qemu-xen-tradition]
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+---
+ hw/vga.c | 70 +++++++++++++++++++++++++++++++++++++---------------------------
+ 1 file changed, 41 insertions(+), 29 deletions(-)
+
+Index: xen-4.1.6.1/qemu/hw/vga.c
+===================================================================
+--- xen-4.1.6.1.orig/qemu/hw/vga.c 2016-05-31 10:04:46.000000000 +0000
++++ xen-4.1.6.1/qemu/hw/vga.c 2016-05-31 10:09:58.000000000 +0000
+@@ -527,6 +527,46 @@
+ }
+ }
+
++/* we initialize the VGA graphic mode */
++static void vbe_update_vgaregs(VGAState *s)
++{
++ int h, shift_control;
++
++ if (!vbe_enabled(s)) {
++ /* vbe is turned off -- nothing to do */
++ return;
++ }
++
++ /* graphic mode + memory map 1 */
++ s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05;
++ s->cr[0x17] |= 3; /* no CGA modes */
++ s->cr[0x13] = s->vbe_line_offset >> 3;
++ /* width */
++ s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
++ /* height (only meaningful if < 1024) */
++ h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
++ s->cr[0x12] = h;
++ s->cr[0x07] = (s->cr[0x07] & ~0x42) |
++ ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
++ /* line compare to 1023 */
++ s->cr[0x18] = 0xff;
++ s->cr[0x07] |= 0x10;
++ s->cr[0x09] |= 0x40;
++
++ if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
++ shift_control = 0;
++ s->sr[0x01] &= ~8; /* no double line */
++ } else {
++ shift_control = 2;
++ /* set chain 4 mode */
++ s->sr[4] |= 0x08;
++ /* activate all planes */
++ s->sr[2] |= 0x0f;
++ }
++ s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
++ s->cr[0x09] &= ~0x9f; /* no double scan */
++}
++
+ #ifdef CONFIG_BOCHS_VBE
+ static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
+ {
+@@ -620,7 +660,6 @@
+ case VBE_DISPI_INDEX_ENABLE:
+ if ((val & VBE_DISPI_ENABLED) &&
+ !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
+- int h, shift_control;
+
+ if (s->vram_gmfn != s->lfb_addr) {
+ set_vram_mapping(s, s->lfb_addr, s->lfb_end);
+@@ -639,40 +678,13 @@
+ s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
+ ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
+ s->vbe_start_addr = 0;
++ vbe_update_vgaregs(s);
+
+ /* clear the screen (should be done in BIOS) */
+ if (!(val & VBE_DISPI_NOCLEARMEM)) {
+ memset(s->vram_ptr, 0,
+ s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
+ }
+-
+- /* we initialize the VGA graphic mode (should be done
+- in BIOS) */
+- s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
+- s->cr[0x17] |= 3; /* no CGA modes */
+- s->cr[0x13] = s->vbe_line_offset >> 3;
+- /* width */
+- s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
+- /* height (only meaningful if < 1024) */
+- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
+- s->cr[0x12] = h;
+- s->cr[0x07] = (s->cr[0x07] & ~0x42) |
+- ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
+- /* line compare to 1023 */
+- s->cr[0x18] = 0xff;
+- s->cr[0x07] |= 0x10;
+- s->cr[0x09] |= 0x40;
+-
+- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
+- shift_control = 0;
+- s->sr[0x01] &= ~8; /* no double line */
+- } else {
+- shift_control = 2;
+- s->sr[4] |= 0x08; /* set chain 4 mode */
+- s->sr[2] |= 0x0f; /* activate all planes */
+- }
+- s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
+- s->cr[0x09] &= ~0x9f; /* no double scan */
+ } else {
+ /* XXX: the bios should do that */
+ s->bank_offset = 0;
diff -Nru xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0004-vga-update-vga-register-setup-on-vbe-changes.patch xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0004-vga-update-vga-register-setup-on-vbe-changes.patch
--- xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0004-vga-update-vga-register-setup-on-vbe-changes.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0004-vga-update-vga-register-setup-on-vbe-changes.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,27 @@
+From 5e840e6292825fcae90f6750a8f57bc989e28c5f Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 15:39:22 +0200
+Subject: [PATCH 4/5] vga: update vga register setup on vbe changes
+
+Call the new vbe_update_vgaregs() function on vbe configuration
+changes, to make sure vga registers are up-to-date.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+[Backport to qemu-xen-tradition]
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+---
+ hw/vga.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: xen-4.1.6.1/qemu/hw/vga.c
+===================================================================
+--- xen-4.1.6.1.orig/qemu/hw/vga.c 2016-05-31 10:09:58.000000000 +0000
++++ xen-4.1.6.1/qemu/hw/vga.c 2016-05-31 10:43:45.000000000 +0000
+@@ -724,6 +724,7 @@
+ else
+ s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
+ s->vbe_start_addr >>= 2;
++ vbe_update_vgaregs(s);
+ }
+ break;
+ default:
diff -Nru xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0005-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0005-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
--- xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0005-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa179-qemut-unstable-0005-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,80 @@
+From 0b0cf8110e97b0cbd0da73d11163e26978822757 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 14:48:06 +0200
+Subject: [PATCH 5/5] vga: make sure vga register setup for vbe stays intact
+ (CVE-2016-3712).
+
+Call vbe_update_vgaregs() when the guest touches GFX, SEQ or CRT
+registers, to make sure the vga registers will always have the
+values needed by vbe mode. This makes sure the sanity checks
+applied by vbe_fixup_regs() are effective.
+
+Without this guests can muck with shift_control, can turn on planar
+vga modes or text mode emulation while VBE is active, making qemu
+take code paths meant for CGA compatibility, but with the very
+large display widths and heigts settable using VBE registers.
+
+Which is good for one or another buffer overflow. Not that
+critical as they typically read overflows happening somewhere
+in the display code. So guests can DoS by crashing qemu with a
+segfault, but it is probably not possible to break out of the VM.
+
+Fixes: CVE-2016-3712
+Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
+Reported-by: P J P <ppandit@redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+[Backport to qemu-xen-tradition]
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+---
+ hw/vga.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+Index: xen-4.1.6.1/qemu/hw/vga.c
+===================================================================
+--- xen-4.1.6.1.orig/qemu/hw/vga.c 2016-05-31 10:43:45.000000000 +0000
++++ xen-4.1.6.1/qemu/hw/vga.c 2016-05-31 10:44:30.000000000 +0000
+@@ -160,6 +160,8 @@
+ static uint16_t expand2[256];
+ static uint8_t expand4to8[16];
+
++static void vbe_update_vgaregs(VGAState *s);
++
+ static inline bool vbe_enabled(VGAState *s)
+ {
+ return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
+@@ -449,6 +451,7 @@
+ printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
+ #endif
+ s->sr[s->sr_index] = val & sr_mask[s->sr_index];
++ vbe_update_vgaregs(s);
+ if (s->sr_index == 1) s->update_retrace_info(s);
+ break;
+ case 0x3c7:
+@@ -477,6 +480,7 @@
+ printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
+ #endif
+ s->gr[s->gr_index] = val & gr_mask[s->gr_index];
++ vbe_update_vgaregs(s);
+ break;
+ case 0x3b4:
+ case 0x3d4:
+@@ -490,8 +494,10 @@
+ /* handle CR0-7 protection */
+ if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
+ /* can always write bit 4 of CR7 */
+- if (s->cr_index == 7)
++ if (s->cr_index == 7) {
+ s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
++ vbe_update_vgaregs(s);
++ }
+ return;
+ }
+ switch(s->cr_index) {
+@@ -507,6 +513,7 @@
+ s->cr[s->cr_index] = val;
+ break;
+ }
++ vbe_update_vgaregs(s);
+
+ switch(s->cr_index) {
+ case 0x00:
diff -Nru xen-4.1.6.1/debian/patches/xsa180-qemut.patch xen-4.1.6.1/debian/patches/xsa180-qemut.patch
--- xen-4.1.6.1/debian/patches/xsa180-qemut.patch 1970-01-01 10:00:00.000000000 +1000
+++ xen-4.1.6.1/debian/patches/xsa180-qemut.patch 2016-06-01 21:15:21.000000000 +1000
@@ -0,0 +1,85 @@
+From 7490dab5c1a01b1623e9d87bdc653cb4f963dd8a Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Thu, 19 May 2016 19:38:35 +0100
+Subject: [PATCH] main loop: Big hammer to fix logfile disk DoS in Xen setups
+
+Each time round the main loop, we now fstat stderr. If it is too big,
+we dup2 /dev/null onto it. This is not a very pretty patch but it is
+very simple, easy to see that it's correct, and has a low risk of
+collateral damage.
+
+The limit is 1Mby by default but can be adjusted by setting a new
+environment variable.
+
+This fixes CVE-2014-3672.
+
+Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
+Tested-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
+---
+ vl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+Index: xen-4.1.6.1/qemu/vl.c
+===================================================================
+--- xen-4.1.6.1.orig/qemu/vl.c 2013-07-17 10:59:40.000000000 +0000
++++ xen-4.1.6.1/qemu/vl.c 2016-05-31 11:01:11.000000000 +0000
+@@ -3743,6 +3743,50 @@
+ }
+ #endif
+
++static void check_cve_2014_3672_xen(void)
++{
++ static unsigned long limit = ~0UL;
++ const int fd = 2;
++ struct stat stab;
++
++ if (limit == ~0UL) {
++ const char *s = getenv("XEN_QEMU_CONSOLE_LIMIT");
++ /* XEN_QEMU_CONSOLE_LIMIT=0 means no limit */
++ limit = s ? strtoul(s,0,0) : 1*1024*1024;
++ }
++ if (limit == 0)
++ return;
++
++ int r = fstat(fd, &stab);
++ if (r) {
++ perror("fstat stderr (for CVE-2014-3672 check)");
++ exit(-1);
++ }
++ if (!S_ISREG(stab.st_mode))
++ return;
++ if (stab.st_size <= limit)
++ return;
++
++ /* oh dear */
++ fprintf(stderr,"\r\n"
++ "Closing stderr due to CVE-2014-3672 limit. "
++ " Set XEN_QEMU_CONSOLE_LIMIT to number of bytes to override,"
++ " or 0 for no limit.\n");
++ fflush(stderr);
++
++ int nfd = open("/dev/null", O_WRONLY);
++ if (nfd < 0) {
++ perror("open /dev/null (for CVE-2014-3672 check)");
++ exit(-1);
++ }
++ r = dup2(nfd, fd);
++ if (r != fd) {
++ perror("dup2 /dev/null (for CVE-2014-3672 check)");
++ exit(-1);
++ }
++ close(nfd);
++}
++
+ void main_loop_wait(int timeout)
+ {
+ IOHandlerRecord *ioh;
+@@ -3754,6 +3798,8 @@
+
+ host_main_loop_wait(&timeout);
+
++ check_cve_2014_3672_xen();
++
+ /* poll any events */
+ /* XXX: separate device handlers from system ones */
+ nfds = -1;
Reply to: