Hello community, here is the log from the commit of package xen for openSUSE:Factory checked in at 2016-03-02 14:20:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/xen (Old) and /work/SRC/openSUSE:Factory/.xen.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "xen" Changes: -------- --- /work/SRC/openSUSE:Factory/xen/xen.changes 2016-02-25 22:02:13.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.xen.new/xen.changes 2016-03-02 14:21:07.000000000 +0100 @@ -1,0 +2,26 @@ +Wed Feb 24 08:05:02 MST 2016 - carnold@suse.com + +- bsc#968004 - VUL-0: CVE-2016-2538: xen: usb: integer overflow in + remote NDIS control message handling + CVE-2016-2538-qemuu-usb-integer-overflow-in-remote-NDIS-message-handling.patch + +------------------------------------------------------------------- +Thu Feb 18 10:39:00 MST 2016 - carnold@suse.com + +- bsc#954872 - L3: script block-dmmd not working as expected - + libxl: error: libxl_dm.c + block-dmmd +- Update libxl to recognize dmmd and npiv prefix in disk spec + xen.libxl.dmmd.patch + +------------------------------------------------------------------- +Wed Feb 17 08:30:35 MST 2016 - carnold@suse.com + +- bsc#967101 - VUL-0: CVE-2016-2391: xen: usb: multiple eof_timers + in ohci module leads to null pointer dereference + CVE-2016-2391-qemuu-usb-null-pointer-dereference-in-ohci-module.patch +- bsc#967090 - VUL-0: CVE-2016-2392: xen: usb: null pointer + dereference in remote NDIS control message handling + CVE-2016-2392-qemuu-usb-null-pointer-dereference-in-NDIS-message-handling.patch + +------------------------------------------------------------------- @@ -36,0 +63,11 @@ + +------------------------------------------------------------------- +Fri Feb 5 13:07:53 MST 2016 - carnold@suse.com + +- bsc#965315 - VUL-0: CVE-2016-2270: xen: x86: inconsistent + cachability flags on guest mappings (XSA-154) + xsa154.patch + xsa154-fix.patch +- bsc#965317 - VUL-0: CVE-2016-2271: xen: VMX: guest user mode may + crash guest with non-canonical RIP (XSA-170) + xsa170.patch New: ---- CVE-2016-2391-qemuu-usb-null-pointer-dereference-in-ohci-module.patch CVE-2016-2392-qemuu-usb-null-pointer-dereference-in-NDIS-message-handling.patch CVE-2016-2538-qemuu-usb-integer-overflow-in-remote-NDIS-message-handling.patch xen.libxl.dmmd.patch xsa154-fix.patch xsa154.patch xsa170.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ xen.spec ++++++ --- /var/tmp/diff_new_pack.DdfhB8/_old 2016-03-02 14:21:10.000000000 +0100 +++ /var/tmp/diff_new_pack.DdfhB8/_new 2016-03-02 14:21:10.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package xen # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -15,7 +15,6 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # - # needssslcertforbuild Name: xen @@ -207,11 +206,14 @@ Patch2: 5628fc67-libxl-No-emulated-disk-driver-for-xvdX-disk.patch Patch3: 5644b756-x86-HVM-don-t-inject-DB-with-error-code.patch Patch4: 5649bcbe-libxl-relax-readonly-check-introduced-by-XSA-142-fix.patch +Patch15401: xsa154.patch +Patch15402: xsa154-fix.patch Patch15501: xsa155-xen-0001-xen-Add-RING_COPY_REQUEST.patch Patch15502: xsa155-xen-0002-blktap2-Use-RING_COPY_REQUEST.patch Patch15503: xsa155-xen-0003-libvchan-Read-prod-cons-only-once.patch Patch162: xsa162-qemuu.patch Patch164: xsa164.patch +Patch170: xsa170.patch # Upstream qemu Patch250: VNC-Support-for-ExtendedKeyEvent-client-message.patch Patch251: 0001-net-move-the-tap-buffer-into-TAPState.patch @@ -254,6 +256,9 @@ Patch289: CVE-2015-5278-qemut-Infinite-loop-in-ne2000_receive-function.patch Patch290: CVE-2015-6855-qemuu-ide-divide-by-zero-issue.patch Patch291: CVE-2015-8619-qemuu-stack-based-OOB-write-in-hmp_sendkey-routine.patch +Patch292: CVE-2016-2392-qemuu-usb-null-pointer-dereference-in-NDIS-message-handling.patch +Patch293: CVE-2016-2391-qemuu-usb-null-pointer-dereference-in-ohci-module.patch +Patch294: CVE-2016-2538-qemuu-usb-integer-overflow-in-remote-NDIS-message-handling.patch # Our platform specific patches Patch321: xen-destdir.patch Patch322: vif-bridge-no-iptables.patch @@ -309,6 +314,7 @@ Patch472: tigervnc-long-press.patch Patch473: xendomains-libvirtd-conflict.patch Patch474: CVE-2014-0222-blktap-qcow1-validate-l2-table-size.patch +Patch475: xen.libxl.dmmd.patch # Hypervisor and PV driver Patches Patch501: x86-ioapic-ack-default.patch Patch502: x86-cpufreq-report.patch @@ -528,11 +534,14 @@ %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch15401 -p1 +%patch15402 -p1 %patch15501 -p1 %patch15502 -p1 %patch15503 -p1 %patch162 -p1 %patch164 -p1 +%patch170 -p1 # Upstream qemu patches %patch250 -p1 %patch251 -p1 @@ -575,6 +584,9 @@ %patch289 -p1 %patch290 -p1 %patch291 -p1 +%patch292 -p1 +%patch293 -p1 +%patch294 -p1 # Our platform specific patches %patch321 -p1 %patch322 -p1 @@ -630,6 +642,7 @@ %patch472 -p1 %patch473 -p1 %patch474 -p1 +%patch475 -p1 # Hypervisor and PV driver Patches %patch501 -p1 %patch502 -p1 ++++++ CVE-2016-2391-qemuu-usb-null-pointer-dereference-in-ohci-module.patch ++++++ References: bsc#967101 CVE-2016-2391
From d1b07becc481e09225cfe905ec357807ae07f095 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann
Date: Tue, 16 Feb 2016 15:15:04 +0100 Subject: [PATCH] ohci timer fix
Signed-off-by: Gerd Hoffmann
--- hw/usb/hcd-ohci.c | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) Index: xen-4.6.1-testing/tools/qemu-xen-dir-remote/hw/usb/hcd-ohci.c =================================================================== --- xen-4.6.1-testing.orig/tools/qemu-xen-dir-remote/hw/usb/hcd-ohci.c +++ xen-4.6.1-testing/tools/qemu-xen-dir-remote/hw/usb/hcd-ohci.c @@ -1331,16 +1331,6 @@ static void ohci_frame_boundary(void *op */ static int ohci_bus_start(OHCIState *ohci) { - ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, - ohci_frame_boundary, - ohci); - - if (ohci->eof_timer == NULL) { - trace_usb_ohci_bus_eof_timer_failed(ohci->name); - ohci_die(ohci); - return 0; - } - trace_usb_ohci_start(ohci->name); ohci_sof(ohci); @@ -1352,11 +1342,7 @@ static int ohci_bus_start(OHCIState *ohc static void ohci_bus_stop(OHCIState *ohci) { trace_usb_ohci_stop(ohci->name); - if (ohci->eof_timer) { - timer_del(ohci->eof_timer); - timer_free(ohci->eof_timer); - } - ohci->eof_timer = NULL; + timer_del(ohci->eof_timer); } /* Sets a flag in a port status register but only set it if the port is @@ -1881,6 +1867,8 @@ static int usb_ohci_init(OHCIState *ohci ohci->async_td = 0; qemu_register_reset(ohci_reset, ohci); + ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + ohci_frame_boundary, ohci); return 0; } @@ -1997,23 +1985,13 @@ static bool ohci_eof_timer_needed(void * { OHCIState *ohci = opaque; - return ohci->eof_timer != NULL; -} - -static int ohci_eof_timer_pre_load(void *opaque) -{ - OHCIState *ohci = opaque; - - ohci_bus_start(ohci); - - return 0; + return timer_pending(ohci->eof_timer); } static const VMStateDescription vmstate_ohci_eof_timer = { .name = "ohci-core/eof-timer", .version_id = 1, .minimum_version_id = 1, - .pre_load = ohci_eof_timer_pre_load, .fields = (VMStateField[]) { VMSTATE_TIMER(eof_timer, OHCIState), VMSTATE_END_OF_LIST() ++++++ CVE-2016-2392-qemuu-usb-null-pointer-dereference-in-NDIS-message-handling.patch ++++++ References: bsc#967090 CVE-2016-2392 When processing remote NDIS control message packets, the USB Net device emulator checks to see if the USB configuration descriptor object is of RNDIS type(2). But it does not check if it is null, which leads to a null dereference error. Add check to avoid it. Reported-by: Qinghao Tang Signed-off-by: Prasad J Pandit --- hw/usb/dev-network.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) Index: xen-4.6.1-testing/tools/qemu-xen-dir-remote/hw/usb/dev-network.c =================================================================== --- xen-4.6.1-testing.orig/tools/qemu-xen-dir-remote/hw/usb/dev-network.c +++ xen-4.6.1-testing/tools/qemu-xen-dir-remote/hw/usb/dev-network.c @@ -650,7 +650,8 @@ typedef struct USBNetState { static int is_rndis(USBNetState *s) { - return s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE; + return s->dev.config ? + s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE : 0; } static int ndis_query(USBNetState *s, uint32_t oid, ++++++ CVE-2016-2538-qemuu-usb-integer-overflow-in-remote-NDIS-message-handling.patch ++++++ References: bsc#968004 CVE-2016-2538 Subject: usb: check RNDIS buffer offsets & length From: Prasad J Pandit pjp@fedoraproject.org Wed Feb 17 00:23:41 2016 +0530 Date: Tue Feb 23 10:38:01 2016 +0100: Git: fe3c546c5ff2a6210f9a4d8561cc64051ca8603e When processing remote NDIS control message packets, the USB Net device emulator uses a fixed length(4096) data buffer. The incoming informationBufferOffset & Length combination could overflow and cross that range. Check control message buffer offsets and length to avoid it. Reported-by: Qinghao Tang`= <boolean>`
Index: xen-4.6.1-testing/xen/arch/x86/hvm/mtrr.c
===================================================================
--- xen-4.6.1-testing.orig/xen/arch/x86/hvm/mtrr.c
+++ xen-4.6.1-testing/xen/arch/x86/hvm/mtrr.c
@@ -807,8 +807,17 @@ int epte_get_entry_emt(struct domain *d,
if ( v->domain != d )
v = d->vcpu ? d->vcpu[0] : NULL;
- if ( !mfn_valid(mfn_x(mfn)) )
+ if ( !mfn_valid(mfn_x(mfn)) ||
+ rangeset_contains_range(mmio_ro_ranges, mfn_x(mfn),
+ mfn_x(mfn) + (1UL << order) - 1) )
+ {
+ *ipat = 1;
return MTRR_TYPE_UNCACHABLE;
+ }
+
+ if ( rangeset_overlaps_range(mmio_ro_ranges, mfn_x(mfn),
+ mfn_x(mfn) + (1UL << order) - 1) )
+ return -1;
switch ( hvm_get_mem_pinned_cacheattr(d, gfn, order, &type) )
{
Index: xen-4.6.1-testing/xen/arch/x86/mm/p2m-pt.c
===================================================================
--- xen-4.6.1-testing.orig/xen/arch/x86/mm/p2m-pt.c
+++ xen-4.6.1-testing/xen/arch/x86/mm/p2m-pt.c
@@ -107,6 +107,8 @@ static unsigned long p2m_type_to_flags(p
case p2m_mmio_direct:
if ( !rangeset_contains_singleton(mmio_ro_ranges, mfn_x(mfn)) )
flags |= _PAGE_RW;
+ else
+ flags |= _PAGE_PWT;
return flags | P2M_BASE_FLAGS | _PAGE_PCD;
}
}
Index: xen-4.6.1-testing/xen/arch/x86/mm/shadow/multi.c
===================================================================
--- xen-4.6.1-testing.orig/xen/arch/x86/mm/shadow/multi.c
+++ xen-4.6.1-testing/xen/arch/x86/mm/shadow/multi.c
@@ -519,6 +519,7 @@ _sh_propagate(struct vcpu *v,
gfn_t target_gfn = guest_l1e_get_gfn(guest_entry);
u32 pass_thru_flags;
u32 gflags, sflags;
+ bool_t mmio_mfn;
/* We don't shadow PAE l3s */
ASSERT(GUEST_PAGING_LEVELS > 3 || level != 3);
@@ -559,7 +560,10 @@ _sh_propagate(struct vcpu *v,
// mfn means that we can not usefully shadow anything, and so we
// return early.
//
- if ( !mfn_valid(target_mfn)
+ mmio_mfn = !mfn_valid(target_mfn)
+ || (level == 1
+ && page_get_owner(mfn_to_page(target_mfn)) == dom_io);
+ if ( mmio_mfn
&& !(level == 1 && (!shadow_mode_refcounts(d)
|| p2mt == p2m_mmio_direct)) )
{
@@ -577,7 +581,7 @@ _sh_propagate(struct vcpu *v,
_PAGE_RW | _PAGE_PRESENT);
if ( guest_supports_nx(v) )
pass_thru_flags |= _PAGE_NX_BIT;
- if ( !shadow_mode_refcounts(d) && !mfn_valid(target_mfn) )
+ if ( level == 1 && !shadow_mode_refcounts(d) && mmio_mfn )
pass_thru_flags |= _PAGE_PAT | _PAGE_PCD | _PAGE_PWT;
sflags = gflags & pass_thru_flags;
@@ -676,10 +680,14 @@ _sh_propagate(struct vcpu *v,
}
/* Read-only memory */
- if ( p2m_is_readonly(p2mt) ||
- (p2mt == p2m_mmio_direct &&
- rangeset_contains_singleton(mmio_ro_ranges, mfn_x(target_mfn))) )
+ if ( p2m_is_readonly(p2mt) )
sflags &= ~_PAGE_RW;
+ else if ( p2mt == p2m_mmio_direct &&
+ rangeset_contains_singleton(mmio_ro_ranges, mfn_x(target_mfn)) )
+ {
+ sflags &= ~(_PAGE_RW | _PAGE_PAT);
+ sflags |= _PAGE_PCD | _PAGE_PWT;
+ }
// protect guest page tables
//
@@ -1185,22 +1193,28 @@ static int shadow_set_l1e(struct domain
&& !sh_l1e_is_magic(new_sl1e) )
{
/* About to install a new reference */
- if ( shadow_mode_refcounts(d) ) {
+ if ( shadow_mode_refcounts(d) )
+ {
+#define PAGE_FLIPPABLE (_PAGE_RW | _PAGE_PWT | _PAGE_PCD | _PAGE_PAT)
+ int rc;
+
TRACE_SHADOW_PATH_FLAG(TRCE_SFLAG_SHADOW_L1_GET_REF);
- switch ( shadow_get_page_from_l1e(new_sl1e, d, new_type) )
+ switch ( rc = shadow_get_page_from_l1e(new_sl1e, d, new_type) )
{
default:
/* Doesn't look like a pagetable. */
flags |= SHADOW_SET_ERROR;
new_sl1e = shadow_l1e_empty();
break;
- case 1:
- shadow_l1e_remove_flags(new_sl1e, _PAGE_RW);
+ case PAGE_FLIPPABLE & -PAGE_FLIPPABLE ... PAGE_FLIPPABLE:
+ ASSERT(!(rc & ~PAGE_FLIPPABLE));
+ new_sl1e = shadow_l1e_flip_flags(new_sl1e, rc);
/* fall through */
case 0:
shadow_vram_get_l1e(new_sl1e, sl1e, sl1mfn, d);
break;
}
+#undef PAGE_FLIPPABLE
}
}
Index: xen-4.6.1-testing/xen/arch/x86/mm/shadow/types.h
===================================================================
--- xen-4.6.1-testing.orig/xen/arch/x86/mm/shadow/types.h
+++ xen-4.6.1-testing/xen/arch/x86/mm/shadow/types.h
@@ -99,6 +99,9 @@ static inline u32 shadow_l4e_get_flags(s
static inline shadow_l1e_t
shadow_l1e_remove_flags(shadow_l1e_t sl1e, u32 flags)
{ l1e_remove_flags(sl1e, flags); return sl1e; }
+static inline shadow_l1e_t
+shadow_l1e_flip_flags(shadow_l1e_t sl1e, u32 flags)
+{ l1e_flip_flags(sl1e, flags); return sl1e; }
static inline shadow_l1e_t shadow_l1e_empty(void)
{ return l1e_empty(); }
Index: xen-4.6.1-testing/xen/include/asm-x86/page.h
===================================================================
--- xen-4.6.1-testing.orig/xen/include/asm-x86/page.h
+++ xen-4.6.1-testing/xen/include/asm-x86/page.h
@@ -157,6 +157,9 @@ static inline l4_pgentry_t l4e_from_padd
#define l3e_remove_flags(x, flags) ((x).l3 &= ~put_pte_flags(flags))
#define l4e_remove_flags(x, flags) ((x).l4 &= ~put_pte_flags(flags))
+/* Flip flags in an existing L1 PTE. */
+#define l1e_flip_flags(x, flags) ((x).l1 ^= put_pte_flags(flags))
+
/* Check if a pte's page mapping or significant access flags have changed. */
#define l1e_has_changed(x,y,flags) \
( !!(((x).l1 ^ (y).l1) & ((PADDR_MASK&PAGE_MASK)|put_pte_flags(flags))) )
Index: xen-4.6.1-testing/xen/arch/x86/mm.c
===================================================================
--- xen-4.6.1-testing.orig/xen/arch/x86/mm.c
+++ xen-4.6.1-testing/xen/arch/x86/mm.c
@@ -178,6 +178,18 @@ static uint32_t base_disallow_mask;
is_pv_domain(d)) ? \
L1_DISALLOW_MASK : (L1_DISALLOW_MASK & ~PAGE_CACHE_ATTRS))
+static s8 __read_mostly opt_mmio_relax;
+static void __init parse_mmio_relax(const char *s)
+{
+ if ( !*s )
+ opt_mmio_relax = 1;
+ else
+ opt_mmio_relax = parse_bool(s);
+ if ( opt_mmio_relax < 0 && strcmp(s, "all") )
+ opt_mmio_relax = 0;
+}
+custom_param("mmio-relax", parse_mmio_relax);
+
static void __init init_frametable_chunk(void *start, void *end)
{
unsigned long s = (unsigned long)start;
@@ -799,10 +811,7 @@ get_page_from_l1e(
if ( !mfn_valid(mfn) ||
(real_pg_owner = page_get_owner_and_reference(page)) == dom_io )
{
-#ifndef NDEBUG
- const unsigned long *ro_map;
- unsigned int seg, bdf;
-#endif
+ int flip = 0;
/* Only needed the reference to confirm dom_io ownership. */
if ( mfn_valid(mfn) )
@@ -836,24 +845,55 @@ get_page_from_l1e(
return -EINVAL;
}
- if ( !(l1f & _PAGE_RW) ||
- !rangeset_contains_singleton(mmio_ro_ranges, mfn) )
- return 0;
+ if ( !rangeset_contains_singleton(mmio_ro_ranges, mfn) )
+ {
+ /* MMIO pages must not be mapped cachable unless requested so. */
+ switch ( opt_mmio_relax )
+ {
+ case 0:
+ break;
+ case 1:
+ if ( is_hardware_domain(l1e_owner) )
+ case -1:
+ return 0;
+ default:
+ ASSERT_UNREACHABLE();
+ }
+ }
+ else if ( l1f & _PAGE_RW )
+ {
#ifndef NDEBUG
- if ( !pci_mmcfg_decode(mfn, &seg, &bdf) ||
- ((ro_map = pci_get_ro_map(seg)) != NULL &&
- test_bit(bdf, ro_map)) )
- printk(XENLOG_G_WARNING
- "d%d: Forcing read-only access to MFN %lx\n",
- l1e_owner->domain_id, mfn);
- else
- rangeset_report_ranges(mmio_ro_ranges, 0, ~0UL,
- print_mmio_emul_range,
- &(struct mmio_emul_range_ctxt){
- .d = l1e_owner,
- .mfn = mfn });
+ const unsigned long *ro_map;
+ unsigned int seg, bdf;
+
+ if ( !pci_mmcfg_decode(mfn, &seg, &bdf) ||
+ ((ro_map = pci_get_ro_map(seg)) != NULL &&
+ test_bit(bdf, ro_map)) )
+ printk(XENLOG_G_WARNING
+ "d%d: Forcing read-only access to MFN %lx\n",
+ l1e_owner->domain_id, mfn);
+ else
+ rangeset_report_ranges(mmio_ro_ranges, 0, ~0UL,
+ print_mmio_emul_range,
+ &(struct mmio_emul_range_ctxt){
+ .d = l1e_owner,
+ .mfn = mfn });
#endif
- return 1;
+ flip = _PAGE_RW;
+ }
+
+ switch ( l1f & PAGE_CACHE_ATTRS )
+ {
+ case 0: /* WB */
+ flip |= _PAGE_PWT | _PAGE_PCD;
+ break;
+ case _PAGE_PWT: /* WT */
+ case _PAGE_PWT | _PAGE_PAT: /* WP */
+ flip |= _PAGE_PCD | (l1f & _PAGE_PAT);
+ break;
+ }
+
+ return flip;
}
if ( unlikely( (real_pg_owner != pg_owner) &&
@@ -1243,8 +1283,9 @@ static int alloc_l1_table(struct page_in
goto fail;
case 0:
break;
- case 1:
- l1e_remove_flags(pl1e[i], _PAGE_RW);
+ case _PAGE_RW ... _PAGE_RW | PAGE_CACHE_ATTRS:
+ ASSERT(!(ret & ~(_PAGE_RW | PAGE_CACHE_ATTRS)));
+ l1e_flip_flags(pl1e[i], ret);
break;
}
@@ -1759,8 +1800,9 @@ static int mod_l1_entry(l1_pgentry_t *pl
return -EINVAL;
}
- /* Fast path for identical mapping, r/w and presence. */
- if ( !l1e_has_changed(ol1e, nl1e, _PAGE_RW | _PAGE_PRESENT) )
+ /* Fast path for identical mapping, r/w, presence, and cachability. */
+ if ( !l1e_has_changed(ol1e, nl1e,
+ PAGE_CACHE_ATTRS | _PAGE_RW | _PAGE_PRESENT) )
{
adjust_guest_l1e(nl1e, pt_dom);
if ( UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu,
@@ -1783,8 +1825,9 @@ static int mod_l1_entry(l1_pgentry_t *pl
return rc;
case 0:
break;
- case 1:
- l1e_remove_flags(nl1e, _PAGE_RW);
+ case _PAGE_RW ... _PAGE_RW | PAGE_CACHE_ATTRS:
+ ASSERT(!(rc & ~(_PAGE_RW | PAGE_CACHE_ATTRS)));
+ l1e_flip_flags(nl1e, rc);
rc = 0;
break;
}
@@ -5000,6 +5043,7 @@ static int ptwr_emulated_update(
l1_pgentry_t pte, ol1e, nl1e, *pl1e;
struct vcpu *v = current;
struct domain *d = v->domain;
+ int ret;
/* Only allow naturally-aligned stores within the original %cr2 page. */
if ( unlikely(((addr^ptwr_ctxt->cr2) & PAGE_MASK) || (addr & (bytes-1))) )
@@ -5047,7 +5091,7 @@ static int ptwr_emulated_update(
/* Check the new PTE. */
nl1e = l1e_from_intpte(val);
- switch ( get_page_from_l1e(nl1e, d, d) )
+ switch ( ret = get_page_from_l1e(nl1e, d, d) )
{
default:
if ( is_pv_32bit_domain(d) && (bytes == 4) && (unaligned_addr & 4) &&
@@ -5071,8 +5115,9 @@ static int ptwr_emulated_update(
break;
case 0:
break;
- case 1:
- l1e_remove_flags(nl1e, _PAGE_RW);
+ case _PAGE_RW ... _PAGE_RW | PAGE_CACHE_ATTRS:
+ ASSERT(!(ret & ~(_PAGE_RW | PAGE_CACHE_ATTRS)));
+ l1e_flip_flags(nl1e, ret);
break;
}
++++++ xsa170.patch ++++++
References: bsc#965317 CVE-2016-2271 XSA-170
x86/VMX: sanitize rIP before re-entering guest
... to prevent guest user mode arranging for a guest crash (due to
failed VM entry). (On the AMD system I checked, hardware is doing
exactly the canonicalization being added here.)
Note that fixing this in an architecturally correct way would be quite
a bit more involved: Making the x86 instruction emulator check all
branch targets for validity, plus dealing with invalid rIP resulting
from update_guest_eip() or incoming directly during a VM exit. The only
way to get the latter right would be by not having hardware do the
injection.
Note further that there are a two early returns from
vmx_vmexit_handler(): One (through vmx_failed_vmentry()) leads to
domain_crash() anyway, and the other covers real mode only and can
neither occur with a non-canonical rIP nor result in an altered rIP,
so we don't need to force those paths through the checking logic.
This is XSA-170.
Reported-by: 刘令