Have attached patches for two security issues in the wheezy version.

CVE-2015-2752.diff
CVE-2015-8104+CVE-2015-5307.patch

Not tested in anyway, except they apply ok.

Am currently looking at CVE-2015-7969; I am beginning to think wheezy is
not vulnerable. Still need to double check this.

Out of time now, will continue looking at this later.
-- 
Brian May <b...@debian.org>
>From 16794c97e99228ca551ff09fa696d00f39ceee82 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.w...@oracle.com>
Date: Wed, 19 Nov 2014 12:57:11 -0500
Subject: Limit XEN_DOMCTL_memory_mapping hypercall to only process up to 64
 GFNs (or less)

Said hypercall for large BARs can take quite a while. As such
we can require that the hypercall MUST break up the request
in smaller values.

Another approach is to add preemption to it - whether we do the
preemption using hypercall_create_continuation or returning
EAGAIN to userspace (and have it re-invocate the call) - either
way the issue we cannot easily solve is that in 'map_mmio_regions'
if we encounter an error we MUST call 'unmap_mmio_regions' for the
whole BAR region.

Since the preemption would re-use input fields such as nr_mfns,
first_gfn, first_mfn - we would lose the original values -
and only undo what was done in the current round (i.e. ignoring
anything that was done prior to earlier preemptions).

Unless we re-used the return value as 'EAGAIN|nr_mfns_done<<10' but
that puts a limit (since the return value is a long) on the amount
of nr_mfns that can provided.

This patch sidesteps this problem by:
 - Setting an hard limit of nr_mfns having to be 64 or less.
 - Toolstack adjusts correspondingly to the nr_mfn limit.
 - If the there is an error when adding the toolstack will call the
   remove operation to remove the whole region.

The need to break this hypercall down is for large BARs can take
more than the guest (initial domain usually) time-slice. This has
the negative result in that the guest is locked out for a long
duration and is unable to act on any pending events.

We also augment the code to return zero if nr_mfns instead
of trying to the hypercall.

This is XSA-125 / CVE-2015-2752.

Suggested-by: Jan Beulich <jbeul...@suse.com>
Acked-by: Jan Beulich <jbeul...@suse.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.w...@oracle.com>
Acked-by: Ian Campbell <ian.campb...@citrix.com>
(cherry picked from commit 518ae14973a44228fd7158c3d70270df6ed90033)

Patch-Name: CVE-2015-2752.diff
---
 tools/libxc/xc_domain.c     | 55 ++++++++++++++++++++++++++++++++++++++++-----
 xen/arch/x86/domctl.c       |  5 +++++
 xen/include/public/domctl.h |  1 +
 3 files changed, 56 insertions(+), 5 deletions(-)

--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1322,6 +1322,13 @@
                                   PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq));
 }
 
+#ifndef min
+#define min(X, Y) ({                             \
+            const typeof (X) _x = (X);           \
+            const typeof (Y) _y = (Y);           \
+            (void) (&_x == &_y);                 \
+            (_x < _y) ? _x : _y; })
+#endif
 int xc_domain_memory_mapping(
     xc_interface *xch,
     uint32_t domid,
@@ -1331,17 +1338,55 @@
     uint32_t add_mapping)
 {
     DECLARE_DOMCTL;
+    int ret = 0, err;
+    unsigned long done = 0, nr, max_batch_sz;
+
+    if ( !nr_mfns )
+        return 0;
 
     domctl.cmd = XEN_DOMCTL_memory_mapping;
     domctl.domain = domid;
-    domctl.u.memory_mapping.first_gfn = first_gfn;
-    domctl.u.memory_mapping.first_mfn = first_mfn;
-    domctl.u.memory_mapping.nr_mfns = nr_mfns;
     domctl.u.memory_mapping.add_mapping = add_mapping;
+    max_batch_sz = nr_mfns;
+    do
+    {
+        nr = min(nr_mfns - done, max_batch_sz);
+        domctl.u.memory_mapping.nr_mfns = nr;
+        domctl.u.memory_mapping.first_gfn = first_gfn + done;
+        domctl.u.memory_mapping.first_mfn = first_mfn + done;
+        err = do_domctl(xch, &domctl);
+        if ( err && errno == E2BIG )
+        {
+            if ( max_batch_sz <= 1 )
+                break;
+            max_batch_sz >>= 1;
+            continue;
+        }
+        /* Save the first error... */
+        if ( !ret )
+            ret = err;
+        /* .. and ignore the rest of them when removing. */
+        if ( err && add_mapping != DPCI_REMOVE_MAPPING )
+            break;
 
-    return do_domctl(xch, &domctl);
-}
+        done += nr;
+    } while ( done < nr_mfns );
+
+    /*
+     * Undo what we have done unless unmapping, by unmapping the entire region.
+     * Errors here are ignored.
+     */
+    if ( ret && add_mapping != DPCI_REMOVE_MAPPING )
+        xc_domain_memory_mapping(xch, domid, first_gfn, first_mfn, nr_mfns,
+                                 DPCI_REMOVE_MAPPING);
 
+    /* We might get E2BIG so many times that we never advance. */
+    if ( !done && !ret )
+        ret = -1;
+
+    return ret;
+}
+#undef min
 int xc_domain_ioport_mapping(
     xc_interface *xch,
     uint32_t domid,
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -927,6 +927,11 @@
         if ( ret )
             goto bind_out;
 
+        ret = -E2BIG;
+        /* Must break hypercall up as this could take a while. */
+        if ( nr_mfns > 64 )
+            break;
+
         ret = -EPERM;
         if ( !IS_PRIV(current->domain) )
         {
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -505,6 +505,7 @@
 
 
 /* Bind machine I/O address range -> HVM address range. */
+/* If this returns -E2BIG lower nr_mfns value. */
 /* XEN_DOMCTL_memory_mapping */
 #define DPCI_ADD_MAPPING         1
 #define DPCI_REMOVE_MAPPING      0
x86/HVM: always intercept #AC and #DB

Both being benign exceptions, and both being possible to get triggered
by exception delivery, this is required to prevent a guest from locking
up a CPU (resulting from no other VM exits occurring once getting into
such a loop).

The specific scenarios:

1) #AC may be raised during exception delivery if the handler is set to
be a ring-3 one by a 32-bit guest, and the stack is misaligned.

2) #DB may be raised during exception delivery when a breakpoint got
placed on a data structure involved in delivering the exception. This
can result in an endless loop when a 64-bit guest uses a non-zero IST
for the vector 1 IDT entry, but even without use of IST the time it
takes until a contributory fault would get raised (results depending
on the handler) may be quite long.

This is XSA-156.

Reported-by: Benjamin Serebrin <sereb...@google.com>
Signed-off-by: Jan Beulich <jbeul...@suse.com>
Reviewed-by: Andrew Cooper <andrew.coop...@citrix.com>
Tested-by: Andrew Cooper <andrew.coop...@citrix.com>

--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -756,10 +756,11 @@
     if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) )
     {
         uint32_t intercepts = vmcb_get_exception_intercepts(vmcb);
-        uint32_t mask = (1U << TRAP_debug) | (1U << TRAP_int3);
+
         v->arch.hvm_vcpu.debug_state_latch = debug_state;
         vmcb_set_exception_intercepts(
-            vmcb, debug_state ? (intercepts | mask) : (intercepts & ~mask));
+            vmcb, debug_state ? (intercepts | (1U << TRAP_int3))
+                              : (intercepts & ~(1U << TRAP_int3)));
     }
 
     if ( v->arch.hvm_svm.launch_core != smp_processor_id() )
@@ -1632,8 +1633,9 @@
 
     case VMEXIT_EXCEPTION_DB:
         if ( !v->domain->debugger_attached )
-            goto exit_and_crash;
-        domain_pause_for_debugger();
+            hvm_inject_hw_exception(TRAP_debug, HVM_DELIVER_NO_ERROR_CODE);
+        else
+            domain_pause_for_debugger();
         break;
 
     case VMEXIT_EXCEPTION_BP:
@@ -1681,6 +1683,11 @@
         break;
     }
 
+    case VMEXIT_EXCEPTION_AC:
+        HVMTRACE_1D(TRAP, TRAP_alignment_check);
+        hvm_inject_hw_exception(TRAP_alignment_check, vmcb->exitinfo1);
+        break;
+
     case VMEXIT_EXCEPTION_UD:
         svm_vmexit_ud_intercept(regs);
         break;
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1059,18 +1059,12 @@
 
 void vmx_update_debug_state(struct vcpu *v)
 {
-    unsigned long mask;
-
     ASSERT(v == current);
 
-    mask = 1u << TRAP_int3;
-    if ( !cpu_has_monitor_trap_flag )
-        mask |= 1u << TRAP_debug;
-
     if ( v->arch.hvm_vcpu.debug_state_latch )
-        v->arch.hvm_vmx.exception_bitmap |= mask;
+        v->arch.hvm_vmx.exception_bitmap |= 1U << TRAP_int3;
     else
-        v->arch.hvm_vmx.exception_bitmap &= ~mask;
+        v->arch.hvm_vmx.exception_bitmap &= ~(1U << TRAP_int3);
     vmx_update_exception_bitmap(v);
 }
 
@@ -2266,9 +2260,10 @@
              */
             exit_qualification = __vmread(EXIT_QUALIFICATION);
             write_debugreg(6, exit_qualification | 0xffff0ff0);
-            if ( !v->domain->debugger_attached || cpu_has_monitor_trap_flag )
-                goto exit_and_crash;
-            domain_pause_for_debugger();
+            if ( !v->domain->debugger_attached )
+                hvm_inject_hw_exception(vector, HVM_DELIVER_NO_ERROR_CODE);
+            else
+                domain_pause_for_debugger();
             break;
         case TRAP_int3: 
         {
@@ -2322,6 +2317,11 @@
             v->arch.hvm_vcpu.guest_cr[2] = exit_qualification;
             vmx_inject_hw_exception(TRAP_page_fault, regs->error_code);
             break;
+        case TRAP_alignment_check:
+            HVMTRACE_1D(TRAP, vector);
+            __vmread(VM_EXIT_INTR_ERROR_CODE, &ecode);
+            hvm_inject_hw_exception(vector, ecode);
+            break;
         case TRAP_nmi:
             if ( (intr_info & INTR_INFO_INTR_TYPE_MASK) !=
                  (X86_EVENTTYPE_NMI << 8) )
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -307,7 +307,10 @@
         (xsave_enabled(_v) ? X86_CR4_OSXSAVE : 0))))
 
 /* These exceptions must always be intercepted. */
-#define HVM_TRAP_MASK ((1U << TRAP_machine_check) | (1U << TRAP_invalid_op))
+#define HVM_TRAP_MASK ((1U << TRAP_debug)           | \
+                       (1U << TRAP_invalid_op)      | \
+                       (1U << TRAP_alignment_check) | \
+                       (1U << TRAP_machine_check))
 
 /*
  * x86 event types. This enumeration is valid for:

Reply via email to