Thu Oct 29 20:40:53 2015 UTC ()
Add patches from Xen security advisory, fixing:
CVE-2015-7835 aka XSA-148
CVE-2015-7869 aka XSA-149 + XSA-151
CVE-2015-7970 aka XSA-150
CVE-2015-7971 aka XSA-152
Bump PKGREVISION


(bouyer)
diff -r1.9 -r1.10 pkgsrc/sysutils/xenkernel45/Makefile
diff -r0 -r1.1 pkgsrc/sysutils/xenkernel45/patches/patch-CVE-2015-7835
diff -r0 -r1.1 pkgsrc/sysutils/xenkernel45/patches/patch-CVE-2015-7969
diff -r0 -r1.1 pkgsrc/sysutils/xenkernel45/patches/patch-CVE-2015-7970
diff -r0 -r1.1 pkgsrc/sysutils/xenkernel45/patches/patch-CVE-2015-7971

cvs diff -r1.9 -r1.10 pkgsrc/sysutils/xenkernel45/Attic/Makefile (expand / switch to unified diff)

--- pkgsrc/sysutils/xenkernel45/Attic/Makefile 2015/06/23 17:45:33 1.9
+++ pkgsrc/sysutils/xenkernel45/Attic/Makefile 2015/10/29 20:40:53 1.10
@@ -1,18 +1,19 @@ @@ -1,18 +1,19 @@
1# $NetBSD: Makefile,v 1.9 2015/06/23 17:45:33 bouyer Exp $ 1# $NetBSD: Makefile,v 1.10 2015/10/29 20:40:53 bouyer Exp $
2 2
3VERSION= 4.5.1 3VERSION= 4.5.1
4DISTNAME= xen-${VERSION} 4DISTNAME= xen-${VERSION}
5PKGNAME= xenkernel45-${VERSION} 5PKGNAME= xenkernel45-${VERSION}
 6PKGREVISION= 1
6CATEGORIES= sysutils 7CATEGORIES= sysutils
7MASTER_SITES= http://bits.xensource.com/oss-xen/release/${VERSION}/ 8MASTER_SITES= http://bits.xensource.com/oss-xen/release/${VERSION}/
8 9
9MAINTAINER= pkgsrc-users@NetBSD.org 10MAINTAINER= pkgsrc-users@NetBSD.org
10HOMEPAGE= http://xenproject.org/ 11HOMEPAGE= http://xenproject.org/
11COMMENT= Xen 4.5.x Kernel 12COMMENT= Xen 4.5.x Kernel
12 13
13LICENSE= gnu-gpl-v2 14LICENSE= gnu-gpl-v2
14 15
15ONLY_FOR_PLATFORM= Linux-2.6*-i386 Linux-2.6*-x86_64 16ONLY_FOR_PLATFORM= Linux-2.6*-i386 Linux-2.6*-x86_64
16ONLY_FOR_PLATFORM+= NetBSD-[5-9].*-x86_64 NetBSD-[5-9].*-i386 17ONLY_FOR_PLATFORM+= NetBSD-[5-9].*-x86_64 NetBSD-[5-9].*-i386
17 18
18NO_CONFIGURE= yes 19NO_CONFIGURE= yes

File Added: pkgsrc/sysutils/xenkernel45/patches/Attic/patch-CVE-2015-7835
$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) )

File Added: pkgsrc/sysutils/xenkernel45/patches/Attic/patch-CVE-2015-7969
$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;
 }

File Added: pkgsrc/sysutils/xenkernel45/patches/Attic/patch-CVE-2015-7970
$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;

File Added: pkgsrc/sysutils/xenkernel45/patches/Attic/patch-CVE-2015-7971
$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;
 }