diff -Nru xen-4.5.0/debian/changelog xen-4.5.0/debian/changelog --- xen-4.5.0/debian/changelog 2015-03-04 11:36:43.000000000 +0000 +++ xen-4.5.0/debian/changelog 2015-04-08 08:14:00.000000000 +0000 @@ -1,3 +1,17 @@ +xen (4.5.0-1ubuntu4) vivid; urgency=low + + * Applying Xen Security Advisories: + * CVE-2014-3969 / XSA-98 (update) + - xen: arm: correct arm64 version of gva_to_ma_par + * CVE-2015-2752 / XSA-125 + - Limit XEN_DOMCTL_memory_mapping hypercall to only process up + to 64 GFNs (or less) + * CVE-2015-2751 / XSA-127 + - domctl: don't allow a toolstack domain to call domain_pause() on + itself + + -- Stefan Bader Wed, 08 Apr 2015 10:10:27 +0200 + xen (4.5.0-1ubuntu3) vivid; urgency=low * Applying Xen Security Advisories: diff -Nru xen-4.5.0/debian/patches/series xen-4.5.0/debian/patches/series --- xen-4.5.0/debian/patches/series 2015-03-04 11:28:55.000000000 +0000 +++ xen-4.5.0/debian/patches/series 2015-04-08 08:09:29.000000000 +0000 @@ -34,3 +34,6 @@ xsa121.patch xsa122.patch xsa123.patch +xsa98-update.patch +xsa125.patch +xsa127-4.x.patch diff -Nru xen-4.5.0/debian/patches/xsa125.patch xen-4.5.0/debian/patches/xsa125.patch --- xen-4.5.0/debian/patches/xsa125.patch 1970-01-01 00:00:00.000000000 +0000 +++ xen-4.5.0/debian/patches/xsa125.patch 2015-04-08 08:08:42.000000000 +0000 @@ -0,0 +1,151 @@ +From 98670acc98cad5aee0e0714694a64d3b96675c36 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Wed, 19 Nov 2014 12:57:11 -0500 +Subject: [PATCH] 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. + +Suggested-by: Jan Beulich +Acked-by: Jan Beulich +Signed-off-by: Konrad Rzeszutek Wilk +Acked-by: Ian Campbell +--- +[v50: Simplify loop] +[v51: If max_batch_sz 1 (or less) we would return zero. Fix that] +[v52: Handle nr_mfns being zero] +[v53: Fix up return value] +--- + tools/libxc/xc_domain.c | 46 +++++++++++++++++++++++++++++++++++++++++---- + xen/common/domctl.c | 5 +++++ + xen/include/public/domctl.h | 1 + + 3 files changed, 48 insertions(+), 4 deletions(-) + +Index: xen-4.5.0/tools/libxc/xc_domain.c +=================================================================== +--- xen-4.5.0.orig/tools/libxc/xc_domain.c 2015-04-08 10:08:37.688318091 +0200 ++++ xen-4.5.0/tools/libxc/xc_domain.c 2015-04-08 10:08:37.680318091 +0200 +@@ -1992,6 +1992,8 @@ int xc_domain_memory_mapping( + { + DECLARE_DOMCTL; + xc_dominfo_t info; ++ int ret = 0, err; ++ unsigned long done = 0, nr, max_batch_sz; + + if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 || + info.domid != domid ) +@@ -2002,14 +2004,50 @@ int xc_domain_memory_mapping( + if ( !xc_core_arch_auto_translated_physmap(&info) ) + return 0; + ++ 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; ++ ++ 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 do_domctl(xch, &domctl); ++ return ret; + } + + int xc_domain_ioport_mapping( +Index: xen-4.5.0/xen/common/domctl.c +=================================================================== +--- xen-4.5.0.orig/xen/common/domctl.c 2015-04-08 10:08:37.688318091 +0200 ++++ xen-4.5.0/xen/common/domctl.c 2015-04-08 10:08:37.684318091 +0200 +@@ -1036,6 +1036,11 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe + (gfn + nr_mfns - 1) < gfn ) /* wrap? */ + break; + ++ ret = -E2BIG; ++ /* Must break hypercall up as this could take a while. */ ++ if ( nr_mfns > 64 ) ++ break; ++ + ret = -EPERM; + if ( !iomem_access_permitted(current->domain, mfn, mfn_end) || + !iomem_access_permitted(d, mfn, mfn_end) ) +Index: xen-4.5.0/xen/include/public/domctl.h +=================================================================== +--- xen-4.5.0.orig/xen/include/public/domctl.h 2015-04-08 10:08:37.688318091 +0200 ++++ xen-4.5.0/xen/include/public/domctl.h 2015-04-08 10:08:37.684318091 +0200 +@@ -543,6 +543,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_ + + + /* 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 diff -Nru xen-4.5.0/debian/patches/xsa127-4.x.patch xen-4.5.0/debian/patches/xsa127-4.x.patch --- xen-4.5.0/debian/patches/xsa127-4.x.patch 1970-01-01 00:00:00.000000000 +0000 +++ xen-4.5.0/debian/patches/xsa127-4.x.patch 2015-04-08 08:09:29.000000000 +0000 @@ -0,0 +1,50 @@ +domctl: don't allow a toolstack domain to call domain_pause() on itself + +These DOMCTL subops were accidentally declared safe for disaggregation +in the wake of XSA-77. + +This is XSA-127. + +Signed-off-by: Andrew Cooper +Reviewed-by: Jan Beulich +Acked-by: Ian Campbell + +--- a/xen/arch/x86/domctl.c ++++ b/xen/arch/x86/domctl.c +@@ -888,6 +888,10 @@ long arch_do_domctl( + { + xen_guest_tsc_info_t info; + ++ ret = -EINVAL; ++ if ( d == current->domain ) /* no domain_pause() */ ++ break; ++ + domain_pause(d); + tsc_get_info(d, &info.tsc_mode, + &info.elapsed_nsec, +@@ -903,6 +907,10 @@ long arch_do_domctl( + + case XEN_DOMCTL_settscinfo: + { ++ ret = -EINVAL; ++ if ( d == current->domain ) /* no domain_pause() */ ++ break; ++ + domain_pause(d); + tsc_set_info(d, domctl->u.tsc_info.info.tsc_mode, + domctl->u.tsc_info.info.elapsed_nsec, +--- a/xen/common/domctl.c ++++ b/xen/common/domctl.c +@@ -522,8 +522,10 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe + + case XEN_DOMCTL_resumedomain: + { +- domain_resume(d); +- ret = 0; ++ if ( d == current->domain ) /* no domain_pause() */ ++ ret = -EINVAL; ++ else ++ domain_resume(d); + } + break; + diff -Nru xen-4.5.0/debian/patches/xsa98-update.patch xen-4.5.0/debian/patches/xsa98-update.patch --- xen-4.5.0/debian/patches/xsa98-update.patch 1970-01-01 00:00:00.000000000 +0000 +++ xen-4.5.0/debian/patches/xsa98-update.patch 2015-04-08 08:08:16.000000000 +0000 @@ -0,0 +1,26 @@ +xen: arm: correct arm64 version of gva_to_ma_par + +The implementation was backwards and checked that the guest could +read when asked about write and vice versa. + +This is an update to the fix for XSA-98. + +Reported-by: Tamas K Lengyel +Signed-off-by: Ian Campbell + +Index: xen-4.5.0/xen/include/asm-arm/arm64/page.h +=================================================================== +--- xen-4.5.0.orig/xen/include/asm-arm/arm64/page.h 2015-04-08 10:08:13.188318746 +0200 ++++ xen-4.5.0/xen/include/asm-arm/arm64/page.h 2015-04-08 10:08:13.184318746 +0200 +@@ -89,9 +89,9 @@ static inline uint64_t gva_to_ma_par(vad + uint64_t par, tmp = READ_SYSREG64(PAR_EL1); + + if ( (flags & GV2M_WRITE) == GV2M_WRITE ) +- asm volatile ("at s12e1r, %0;" : : "r" (va)); +- else + asm volatile ("at s12e1w, %0;" : : "r" (va)); ++ else ++ asm volatile ("at s12e1r, %0;" : : "r" (va)); + isb(); + par = READ_SYSREG64(PAR_EL1); + WRITE_SYSREG64(tmp, PAR_EL1);