[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: