Accepting request 362063 from Virtualization
Security and maintenance update OBS-URL: https://build.opensuse.org/request/show/362063 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/xen?expand=0&rev=218
This commit is contained in:
commit
2e153fae6c
@ -0,0 +1,80 @@
|
|||||||
|
References: bsc#967101 CVE-2016-2391
|
||||||
|
|
||||||
|
From d1b07becc481e09225cfe905ec357807ae07f095 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <address@hidden>
|
||||||
|
Date: Tue, 16 Feb 2016 15:15:04 +0100
|
||||||
|
Subject: [PATCH] ohci timer fix
|
||||||
|
|
||||||
|
Signed-off-by: Gerd Hoffmann <address@hidden>
|
||||||
|
---
|
||||||
|
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()
|
@ -0,0 +1,27 @@
|
|||||||
|
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 <address@hidden>
|
||||||
|
Signed-off-by: Prasad J Pandit <address@hidden>
|
||||||
|
---
|
||||||
|
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,
|
@ -0,0 +1,55 @@
|
|||||||
|
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 <luodalongde@gmail.com>
|
||||||
|
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||||
|
Message-id: 1455648821-17340-3-git-send-email-ppandit@redhat.com
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -912,8 +912,9 @@ static int rndis_query_response(USBNetSt
|
||||||
|
|
||||||
|
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
|
||||||
|
buflen = le32_to_cpu(buf->InformationBufferLength);
|
||||||
|
- if (bufoffs + buflen > length)
|
||||||
|
+ if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
|
||||||
|
return USB_RET_STALL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
infobuflen = ndis_query(s, le32_to_cpu(buf->OID),
|
||||||
|
bufoffs + (uint8_t *) buf, buflen, infobuf,
|
||||||
|
@@ -958,8 +959,9 @@ static int rndis_set_response(USBNetStat
|
||||||
|
|
||||||
|
bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
|
||||||
|
buflen = le32_to_cpu(buf->InformationBufferLength);
|
||||||
|
- if (bufoffs + buflen > length)
|
||||||
|
+ if (buflen > length || bufoffs >= length || bufoffs + buflen > length) {
|
||||||
|
return USB_RET_STALL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ret = ndis_set(s, le32_to_cpu(buf->OID),
|
||||||
|
bufoffs + (uint8_t *) buf, buflen);
|
||||||
|
@@ -1209,8 +1211,9 @@ static void usb_net_handle_dataout(USBNe
|
||||||
|
if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) {
|
||||||
|
uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
|
||||||
|
uint32_t size = le32_to_cpu(msg->DataLength);
|
||||||
|
- if (offs + size <= len)
|
||||||
|
+ if (offs < len && size < len && offs + size <= len) {
|
||||||
|
qemu_send_packet(qemu_get_queue(s->nic), s->out_buf + offs, size);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
s->out_ptr -= len;
|
||||||
|
memmove(s->out_buf, &s->out_buf[len], s->out_ptr);
|
90
block-dmmd
90
block-dmmd
@ -2,13 +2,22 @@
|
|||||||
|
|
||||||
# Usage: block-dmmd [add args | remove args]
|
# Usage: block-dmmd [add args | remove args]
|
||||||
#
|
#
|
||||||
# the xm config file should have something like:
|
# the dmmd device syntax (in xm commands/configs) is something like:
|
||||||
# dmmd:md;/dev/md0;md;/dev/md1;lvm;/dev/vg1/lv1
|
# dmmd:md;/dev/md0;md;/dev/md1;lvm;/dev/vg1/lv1
|
||||||
# or
|
# or
|
||||||
# dmmd:lvm;/dev/vg1/lv1;lvm;/dev/vg1/lv2;md;/dev/md0
|
# dmmd:lvm;/dev/vg1/lv1;lvm;/dev/vg1/lv2;md;/dev/md0
|
||||||
# note the last device will be used for VM
|
# device pairs (type;dev) are processed in order, with the last device
|
||||||
|
# assigned to the VM
|
||||||
|
#
|
||||||
|
# md devices can optionally:
|
||||||
|
# specify a config file through:
|
||||||
|
# md;/dev/md100(/var/xen/config/mdadm.conf)
|
||||||
|
# use an array name (mdadm -N option):
|
||||||
|
# dmmd:md;My-MD-name;lvm;/dev/vg1/lv1
|
||||||
|
#
|
||||||
# History:
|
# History:
|
||||||
|
# 2013-07-03, loic.devulder@mpsa.com:
|
||||||
|
# Partial rewrite of the script for supporting MD activation by name
|
||||||
# 2009-06-09, mh@novell.com:
|
# 2009-06-09, mh@novell.com:
|
||||||
# Emit debugging messages into a temporary file; if no longer needed,
|
# Emit debugging messages into a temporary file; if no longer needed,
|
||||||
# just comment the exec I/O redirection below
|
# just comment the exec I/O redirection below
|
||||||
@ -39,7 +48,7 @@ function run_mdadm()
|
|||||||
local msg
|
local msg
|
||||||
local rc
|
local rc
|
||||||
|
|
||||||
msg="`/sbin/mdadm $mdadm_cmd 2>&1`"
|
msg="$(/sbin/mdadm $mdadm_cmd 2>&1)"
|
||||||
rc=$?
|
rc=$?
|
||||||
case "$msg" in
|
case "$msg" in
|
||||||
*"has been started"* | *"already active"* )
|
*"has been started"* | *"already active"* )
|
||||||
@ -59,11 +68,12 @@ function run_mdadm()
|
|||||||
|
|
||||||
function activate_md()
|
function activate_md()
|
||||||
{
|
{
|
||||||
|
# Make it explicitly local
|
||||||
local par=$1
|
local par=$1
|
||||||
local already_active=0 cfg dev rc t
|
local cfg dev dev_path rc t mdadm_opts
|
||||||
|
|
||||||
if [ ${par} = ${par%%(*} ]; then
|
if [ ${par} = ${par%%(*} ]; then
|
||||||
# No configuration file specified:
|
# No configuration file specified
|
||||||
dev=$par
|
dev=$par
|
||||||
cfg=
|
cfg=
|
||||||
else
|
else
|
||||||
@ -71,23 +81,51 @@ function activate_md()
|
|||||||
t=${par#*(}
|
t=${par#*(}
|
||||||
cfg="-c ${t%%)*}"
|
cfg="-c ${t%%)*}"
|
||||||
fi
|
fi
|
||||||
if /sbin/mdadm -Q -D $dev; then
|
|
||||||
already_active=1
|
# Looking for device name or aliase
|
||||||
|
if [ ${dev:0:1} = / ]; then
|
||||||
|
dev_path=${dev%/*}
|
||||||
|
mdadm_opts=
|
||||||
|
else
|
||||||
|
dev_path=/dev/md
|
||||||
|
mdadm_opts="-s -N"
|
||||||
fi
|
fi
|
||||||
run_mdadm "-A $dev $cfg"
|
|
||||||
|
# Is md device already active?
|
||||||
|
# We need to use full path name, aliase is not possible...
|
||||||
|
if [ -e $dev_path/${dev##*/} ]; then
|
||||||
|
/sbin/mdadm -Q -D $dev_path/${dev##*/} 2>/dev/null | grep -iq state.*\:.*inactive || return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
run_mdadm "-A $mdadm_opts $dev $cfg"
|
||||||
rc=$?
|
rc=$?
|
||||||
if [ $already_active -eq 1 ] && [ $rc -eq 2 ]; then
|
[ $rc -eq 2 ] && return 0
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
return $rc
|
return $rc
|
||||||
}
|
}
|
||||||
|
|
||||||
function deactivate_md()
|
function deactivate_md()
|
||||||
{
|
{
|
||||||
local par=$1 # Make it explicitly local
|
local par=$1
|
||||||
|
local dev
|
||||||
|
|
||||||
|
if [ ${par} = ${par%%(*} ]; then
|
||||||
|
# No configuration file specified
|
||||||
|
dev=${par}
|
||||||
|
else
|
||||||
|
dev=${par%%(*}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Looking for device name or aliase
|
||||||
|
if [ ${dev:0:1} = / ]; then
|
||||||
|
dev_path=${dev%/*}
|
||||||
|
else
|
||||||
|
dev_path=/dev/md
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We need the device name only while deactivating
|
||||||
|
/sbin/mdadm -S ${dev_path}/${dev##*/} > /dev/null 2>&1
|
||||||
|
|
||||||
## We need the device name only while deactivating
|
|
||||||
/sbin/mdadm -S ${par%%(*}
|
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,9 +134,15 @@ function activate_lvm()
|
|||||||
local run_timeout=90
|
local run_timeout=90
|
||||||
local end_time
|
local end_time
|
||||||
|
|
||||||
|
# First scan for PVs and VGs
|
||||||
|
# We need this for using md device as PV
|
||||||
|
/sbin/pvscan > /dev/null 2>&1
|
||||||
|
# /sbin/vgscan --mknodes > /dev/null 2>&1
|
||||||
|
|
||||||
end_time=$(($(date +%s)+${run_timeout}))
|
end_time=$(($(date +%s)+${run_timeout}))
|
||||||
while true; do
|
while true; do
|
||||||
/sbin/lvchange -aey $1
|
/sbin/lvchange -aey $1 > /dev/null 2>&1
|
||||||
|
|
||||||
if [ $? -eq 0 -a -e $1 ]; then
|
if [ $? -eq 0 -a -e $1 ]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@ -114,7 +158,8 @@ function activate_lvm()
|
|||||||
|
|
||||||
function deactivate_lvm()
|
function deactivate_lvm()
|
||||||
{
|
{
|
||||||
/sbin/lvchange -aen $1
|
/sbin/lvchange -aen $1 > /dev/null 2>&1
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
# We may have to deactivate the VG now, but can ignore errors:
|
# We may have to deactivate the VG now, but can ignore errors:
|
||||||
# /sbin/vgchange -an ${1%/*} || :
|
# /sbin/vgchange -an ${1%/*} || :
|
||||||
@ -219,7 +264,6 @@ function parse_par()
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
push "$t $s"
|
push "$t $s"
|
||||||
|
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,11 +282,11 @@ case "$command" in
|
|||||||
fi
|
fi
|
||||||
lastparam=${dmmd##*;}
|
lastparam=${dmmd##*;}
|
||||||
usedevice=${lastparam%(*}
|
usedevice=${lastparam%(*}
|
||||||
xenstore-write $XENBUS_PATH/node "$usedevice"
|
xenstore-write $XENBUS_PATH/node "$usedevice"
|
||||||
write_dev "$usedevice"
|
write_dev "$usedevice"
|
||||||
release_lock "dmmd"
|
release_lock "dmmd"
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
|
||||||
remove)
|
remove)
|
||||||
p=`xenstore-read $XENBUS_PATH/params` || true
|
p=`xenstore-read $XENBUS_PATH/params` || true
|
||||||
|
37
xen.changes
37
xen.changes
@ -1,3 +1,29 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
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
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Feb 11 09:29:01 MST 2016 - carnold@suse.com
|
Thu Feb 11 09:29:01 MST 2016 - carnold@suse.com
|
||||||
|
|
||||||
@ -35,6 +61,17 @@ Thu Feb 11 09:29:01 MST 2016 - carnold@suse.com
|
|||||||
xsa167.patch
|
xsa167.patch
|
||||||
xsa168.patch
|
xsa168.patch
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
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
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Feb 5 08:51:16 MST 2016 - carnold@suse.com
|
Fri Feb 5 08:51:16 MST 2016 - carnold@suse.com
|
||||||
|
|
||||||
|
118
xen.libxl.dmmd.patch
Normal file
118
xen.libxl.dmmd.patch
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
References: bsc#954872
|
||||||
|
|
||||||
|
---
|
||||||
|
tools/libxl/libxl.c | 4 ++++
|
||||||
|
tools/libxl/libxl_device.c | 3 ++-
|
||||||
|
tools/libxl/libxl_dm.c | 34 +++++++++++++++++++++++++++++-----
|
||||||
|
tools/libxl/libxlu_disk_l.l | 2 ++
|
||||||
|
4 files changed, 37 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
Index: xen-4.6.1-testing/tools/libxl/libxl.c
|
||||||
|
===================================================================
|
||||||
|
--- xen-4.6.1-testing.orig/tools/libxl/libxl.c
|
||||||
|
+++ xen-4.6.1-testing/tools/libxl/libxl.c
|
||||||
|
@@ -2791,6 +2791,10 @@ static void device_disk_add(libxl__egc *
|
||||||
|
/* now create a phy device to export the device to the guest */
|
||||||
|
goto do_backend_phy;
|
||||||
|
case LIBXL_DISK_BACKEND_QDISK:
|
||||||
|
+ if (disk->script) {
|
||||||
|
+ script = libxl__abs_path(gc, disk->script, libxl__xen_script_dir_path());
|
||||||
|
+ flexarray_append_pair(back, "script", script);
|
||||||
|
+ }
|
||||||
|
flexarray_append(back, "params");
|
||||||
|
flexarray_append(back, libxl__sprintf(gc, "%s:%s",
|
||||||
|
libxl__device_disk_string_of_format(disk->format), disk->pdev_path));
|
||||||
|
Index: xen-4.6.1-testing/tools/libxl/libxl_device.c
|
||||||
|
===================================================================
|
||||||
|
--- xen-4.6.1-testing.orig/tools/libxl/libxl_device.c
|
||||||
|
+++ xen-4.6.1-testing/tools/libxl/libxl_device.c
|
||||||
|
@@ -235,7 +235,8 @@ static int disk_try_backend(disk_try_bac
|
||||||
|
return backend;
|
||||||
|
|
||||||
|
case LIBXL_DISK_BACKEND_QDISK:
|
||||||
|
- if (a->disk->script) goto bad_script;
|
||||||
|
+ LOG(DEBUG, "Disk vdev=%s, uses script=%s on %s backend",
|
||||||
|
+ a->disk->vdev, a->disk->script, libxl_disk_backend_to_string(backend));
|
||||||
|
return backend;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Index: xen-4.6.1-testing/tools/libxl/libxl_dm.c
|
||||||
|
===================================================================
|
||||||
|
--- xen-4.6.1-testing.orig/tools/libxl/libxl_dm.c
|
||||||
|
+++ xen-4.6.1-testing/tools/libxl/libxl_dm.c
|
||||||
|
@@ -700,6 +700,30 @@ static char *dm_spice_options(libxl__gc
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void libxl__suse_node_to_path(libxl__gc *gc, int domid, const libxl_device_disk *dp, const char **pdev_path)
|
||||||
|
+{
|
||||||
|
+ libxl_ctx *ctx = libxl__gc_owner(gc);
|
||||||
|
+ char *be_path, *node;
|
||||||
|
+ libxl__device device;
|
||||||
|
+ libxl_device_disk disk;
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ disk = *dp;
|
||||||
|
+ rc = libxl__device_from_disk(gc, domid, &disk, &device);
|
||||||
|
+ if (rc) {
|
||||||
|
+ LIBXL__LOG(ctx, LIBXL__LOG_WARNING, "libxl__device_from_disk failed %d", rc);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ be_path = libxl__device_backend_path(gc, &device);
|
||||||
|
+
|
||||||
|
+ node = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/node", be_path));
|
||||||
|
+ if (!node)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ LIBXL__LOG(ctx, LIBXL__LOG_WARNING, "replacing '%s' with '%s' from %s/node, just for qemu-xen", *pdev_path, node, be_path);
|
||||||
|
+ *pdev_path = node;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int libxl__build_device_model_args_new(libxl__gc *gc,
|
||||||
|
const char *dm, int guest_domid,
|
||||||
|
const libxl_domain_config *guest_config,
|
||||||
|
@@ -1099,7 +1123,9 @@ static int libxl__build_device_model_arg
|
||||||
|
libxl__device_disk_dev_number(disks[i].vdev, &disk, &part);
|
||||||
|
const char *format = qemu_disk_format_string(disks[i].format);
|
||||||
|
char *drive;
|
||||||
|
- const char *pdev_path;
|
||||||
|
+ const char *pdev_path = disks[i].pdev_path;
|
||||||
|
+
|
||||||
|
+ libxl__suse_node_to_path(gc, guest_domid, disks + i, &pdev_path);
|
||||||
|
|
||||||
|
if (dev_number == -1) {
|
||||||
|
LIBXL__LOG(ctx, LIBXL__LOG_WARNING, "unable to determine"
|
||||||
|
@@ -1115,7 +1141,7 @@ static int libxl__build_device_model_arg
|
||||||
|
else
|
||||||
|
drive = libxl__sprintf
|
||||||
|
(gc, "file=%s,if=ide,index=%d,readonly=%s,media=cdrom,format=%s,cache=writeback,id=ide-%i",
|
||||||
|
- disks[i].pdev_path, disk, disks[i].readwrite ? "off" : "on", format, dev_number);
|
||||||
|
+ pdev_path, disk, disks[i].readwrite ? "off" : "on", format, dev_number);
|
||||||
|
} else {
|
||||||
|
if (disks[i].format == LIBXL_DISK_FORMAT_EMPTY) {
|
||||||
|
LIBXL__LOG(ctx, LIBXL__LOG_WARNING, "cannot support"
|
||||||
|
@@ -1131,10 +1157,8 @@ static int libxl__build_device_model_arg
|
||||||
|
|
||||||
|
if (disks[i].backend == LIBXL_DISK_BACKEND_TAP) {
|
||||||
|
format = qemu_disk_format_string(LIBXL_DISK_FORMAT_RAW);
|
||||||
|
- pdev_path = libxl__blktap_devpath(gc, disks[i].pdev_path,
|
||||||
|
+ pdev_path = libxl__blktap_devpath(gc, pdev_path,
|
||||||
|
disks[i].format);
|
||||||
|
- } else {
|
||||||
|
- pdev_path = disks[i].pdev_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Index: xen-4.6.1-testing/tools/libxl/libxlu_disk_l.l
|
||||||
|
===================================================================
|
||||||
|
--- xen-4.6.1-testing.orig/tools/libxl/libxlu_disk_l.l
|
||||||
|
+++ xen-4.6.1-testing/tools/libxl/libxlu_disk_l.l
|
||||||
|
@@ -210,6 +210,8 @@ target=.* { STRIP(','); SAVESTRING("targ
|
||||||
|
free(newscript);
|
||||||
|
}
|
||||||
|
|
||||||
|
+dmmd:/.* { DPC->had_depr_prefix=1; DEPRECATE(0); }
|
||||||
|
+npiv:/.* { DPC->had_depr_prefix=1; DEPRECATE(0); }
|
||||||
|
tapdisk:/.* { DPC->had_depr_prefix=1; DEPRECATE(0); }
|
||||||
|
tap2?:/.* { DPC->had_depr_prefix=1; DEPRECATE(0); }
|
||||||
|
aio:/.* { DPC->had_depr_prefix=1; DEPRECATE(0); }
|
17
xen.spec
17
xen.spec
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package xen
|
# 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
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@ -15,7 +15,6 @@
|
|||||||
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
# needssslcertforbuild
|
# needssslcertforbuild
|
||||||
|
|
||||||
Name: xen
|
Name: xen
|
||||||
@ -207,11 +206,14 @@ Patch1: 55f7f9d2-libxl-slightly-refine-pci-assignable-add-remove-handlin
|
|||||||
Patch2: 5628fc67-libxl-No-emulated-disk-driver-for-xvdX-disk.patch
|
Patch2: 5628fc67-libxl-No-emulated-disk-driver-for-xvdX-disk.patch
|
||||||
Patch3: 5644b756-x86-HVM-don-t-inject-DB-with-error-code.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
|
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
|
Patch15501: xsa155-xen-0001-xen-Add-RING_COPY_REQUEST.patch
|
||||||
Patch15502: xsa155-xen-0002-blktap2-Use-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
|
Patch15503: xsa155-xen-0003-libvchan-Read-prod-cons-only-once.patch
|
||||||
Patch162: xsa162-qemuu.patch
|
Patch162: xsa162-qemuu.patch
|
||||||
Patch164: xsa164.patch
|
Patch164: xsa164.patch
|
||||||
|
Patch170: xsa170.patch
|
||||||
# Upstream qemu
|
# Upstream qemu
|
||||||
Patch250: VNC-Support-for-ExtendedKeyEvent-client-message.patch
|
Patch250: VNC-Support-for-ExtendedKeyEvent-client-message.patch
|
||||||
Patch251: 0001-net-move-the-tap-buffer-into-TAPState.patch
|
Patch251: 0001-net-move-the-tap-buffer-into-TAPState.patch
|
||||||
@ -254,6 +256,9 @@ Patch288: CVE-2013-4533-qemut-pxa2xx-buffer-overrun-on-incoming-migration.
|
|||||||
Patch289: CVE-2015-5278-qemut-Infinite-loop-in-ne2000_receive-function.patch
|
Patch289: CVE-2015-5278-qemut-Infinite-loop-in-ne2000_receive-function.patch
|
||||||
Patch290: CVE-2015-6855-qemuu-ide-divide-by-zero-issue.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
|
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
|
# Our platform specific patches
|
||||||
Patch321: xen-destdir.patch
|
Patch321: xen-destdir.patch
|
||||||
Patch322: vif-bridge-no-iptables.patch
|
Patch322: vif-bridge-no-iptables.patch
|
||||||
@ -309,6 +314,7 @@ Patch471: qemu-xen-enable-spice-support.patch
|
|||||||
Patch472: tigervnc-long-press.patch
|
Patch472: tigervnc-long-press.patch
|
||||||
Patch473: xendomains-libvirtd-conflict.patch
|
Patch473: xendomains-libvirtd-conflict.patch
|
||||||
Patch474: CVE-2014-0222-blktap-qcow1-validate-l2-table-size.patch
|
Patch474: CVE-2014-0222-blktap-qcow1-validate-l2-table-size.patch
|
||||||
|
Patch475: xen.libxl.dmmd.patch
|
||||||
# Hypervisor and PV driver Patches
|
# Hypervisor and PV driver Patches
|
||||||
Patch501: x86-ioapic-ack-default.patch
|
Patch501: x86-ioapic-ack-default.patch
|
||||||
Patch502: x86-cpufreq-report.patch
|
Patch502: x86-cpufreq-report.patch
|
||||||
@ -528,11 +534,14 @@ Authors:
|
|||||||
%patch2 -p1
|
%patch2 -p1
|
||||||
%patch3 -p1
|
%patch3 -p1
|
||||||
%patch4 -p1
|
%patch4 -p1
|
||||||
|
%patch15401 -p1
|
||||||
|
%patch15402 -p1
|
||||||
%patch15501 -p1
|
%patch15501 -p1
|
||||||
%patch15502 -p1
|
%patch15502 -p1
|
||||||
%patch15503 -p1
|
%patch15503 -p1
|
||||||
%patch162 -p1
|
%patch162 -p1
|
||||||
%patch164 -p1
|
%patch164 -p1
|
||||||
|
%patch170 -p1
|
||||||
# Upstream qemu patches
|
# Upstream qemu patches
|
||||||
%patch250 -p1
|
%patch250 -p1
|
||||||
%patch251 -p1
|
%patch251 -p1
|
||||||
@ -575,6 +584,9 @@ Authors:
|
|||||||
%patch289 -p1
|
%patch289 -p1
|
||||||
%patch290 -p1
|
%patch290 -p1
|
||||||
%patch291 -p1
|
%patch291 -p1
|
||||||
|
%patch292 -p1
|
||||||
|
%patch293 -p1
|
||||||
|
%patch294 -p1
|
||||||
# Our platform specific patches
|
# Our platform specific patches
|
||||||
%patch321 -p1
|
%patch321 -p1
|
||||||
%patch322 -p1
|
%patch322 -p1
|
||||||
@ -630,6 +642,7 @@ Authors:
|
|||||||
%patch472 -p1
|
%patch472 -p1
|
||||||
%patch473 -p1
|
%patch473 -p1
|
||||||
%patch474 -p1
|
%patch474 -p1
|
||||||
|
%patch475 -p1
|
||||||
# Hypervisor and PV driver Patches
|
# Hypervisor and PV driver Patches
|
||||||
%patch501 -p1
|
%patch501 -p1
|
||||||
%patch502 -p1
|
%patch502 -p1
|
||||||
|
31
xsa154-fix.patch
Normal file
31
xsa154-fix.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
Subject: x86: fix unintended fallthrough case from XSA-154
|
||||||
|
From: Andrew Cooper andrew.cooper3@citrix.com Thu Feb 18 15:10:07 2016 +0100
|
||||||
|
Date: Thu Feb 18 15:10:07 2016 +0100:
|
||||||
|
Git: 8dd6d1c099865ee5f5916616a0ca79cd943c46f9
|
||||||
|
|
||||||
|
... and annotate the other deliberate one: Coverity objects otherwise.
|
||||||
|
|
||||||
|
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||||
|
|
||||||
|
One of the two instances was actually a bug.
|
||||||
|
|
||||||
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -853,9 +853,11 @@ get_page_from_l1e(
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
- if ( is_hardware_domain(l1e_owner) )
|
||||||
|
+ if ( !is_hardware_domain(l1e_owner) )
|
||||||
|
+ break;
|
||||||
|
+ /* fallthrough */
|
||||||
|
case -1:
|
||||||
|
- return 0;
|
||||||
|
+ return 0;
|
||||||
|
default:
|
||||||
|
ASSERT_UNREACHABLE();
|
||||||
|
}
|
375
xsa154.patch
Normal file
375
xsa154.patch
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
References: bsc#965315 - CVE-2016-2270 XSA-154
|
||||||
|
|
||||||
|
x86: enforce consistent cachability of MMIO mappings
|
||||||
|
|
||||||
|
We've been told by Intel that inconsistent cachability between
|
||||||
|
multiple mappings of the same page can affect system stability only
|
||||||
|
when the affected page is an MMIO one. Since the stale data issue is
|
||||||
|
of no relevance to the hypervisor (since all guest memory accesses go
|
||||||
|
through proper accessors and validation), handling of RAM pages
|
||||||
|
remains unchanged here. Any MMIO mapped by domains however needs to be
|
||||||
|
done consistently (all cachable mappings or all uncachable ones), in
|
||||||
|
order to avoid Machine Check exceptions. Since converting existing
|
||||||
|
cachable mappings to uncachable (at the time an uncachable mapping
|
||||||
|
gets established) would in the PV case require tracking all mappings,
|
||||||
|
allow MMIO to only get mapped uncachable (UC, UC-, or WC).
|
||||||
|
|
||||||
|
This also implies that in the PV case we mustn't use the L1 PTE update
|
||||||
|
fast path when cachability flags get altered.
|
||||||
|
|
||||||
|
Since in the HVM case at least for now we want to continue honoring
|
||||||
|
pinned cachability attributes for pages not mapped by the hypervisor,
|
||||||
|
special case handling of r/o MMIO pages (forcing UC) gets added there.
|
||||||
|
Arguably the counterpart change to p2m-pt.c may not be necessary, since
|
||||||
|
UC- (which already gets enforced there) is probably strict enough.
|
||||||
|
|
||||||
|
Note that the shadow code changes include fixing the write protection
|
||||||
|
of r/o MMIO ranges: shadow_l1e_remove_flags() and its siblings, other
|
||||||
|
than l1e_remove_flags() and alike, return the new PTE (and hence
|
||||||
|
ignoring their return values makes them no-ops).
|
||||||
|
|
||||||
|
This is CVE-2016-2270 / XSA-154.
|
||||||
|
|
||||||
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||||||
|
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||||||
|
|
||||||
|
Index: xen-4.6.1-testing/docs/misc/xen-command-line.markdown
|
||||||
|
===================================================================
|
||||||
|
--- xen-4.6.1-testing.orig/docs/misc/xen-command-line.markdown
|
||||||
|
+++ xen-4.6.1-testing/docs/misc/xen-command-line.markdown
|
||||||
|
@@ -1080,6 +1080,15 @@ limit is ignored by Xen.
|
||||||
|
|
||||||
|
Specify if the MMConfig space should be enabled.
|
||||||
|
|
||||||
|
+### mmio-relax
|
||||||
|
+> `= <boolean> | all`
|
||||||
|
+
|
||||||
|
+> Default: `false`
|
||||||
|
+
|
||||||
|
+By default, domains may not create cached mappings to MMIO regions.
|
||||||
|
+This option relaxes the check for Domain 0 (or when using `all`, all PV
|
||||||
|
+domains), to permit the use of cacheable MMIO mappings.
|
||||||
|
+
|
||||||
|
### msi
|
||||||
|
> `= <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;
|
||||||
|
}
|
||||||
|
|
83
xsa170.patch
Normal file
83
xsa170.patch
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
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: 刘令 <liuling-it@360.cn>
|
||||||
|
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.6.1-testing/xen/arch/x86/hvm/vmx/vmx.c
|
||||||
|
===================================================================
|
||||||
|
--- xen-4.6.1-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
|
||||||
|
+++ xen-4.6.1-testing/xen/arch/x86/hvm/vmx/vmx.c
|
||||||
|
@@ -2879,7 +2879,7 @@ static int vmx_handle_apic_write(void)
|
||||||
|
void vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||||
|
{
|
||||||
|
unsigned long exit_qualification, exit_reason, idtv_info, intr_info = 0;
|
||||||
|
- unsigned int vector = 0;
|
||||||
|
+ unsigned int vector = 0, mode;
|
||||||
|
struct vcpu *v = current;
|
||||||
|
|
||||||
|
__vmread(GUEST_RIP, ®s->rip);
|
||||||
|
@@ -3468,6 +3468,41 @@ void vmx_vmexit_handler(struct cpu_user_
|
||||||
|
out:
|
||||||
|
if ( nestedhvm_vcpu_in_guestmode(v) )
|
||||||
|
nvmx_idtv_handling();
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * VM entry will fail (causing the guest to get crashed) if rIP (and
|
||||||
|
+ * rFLAGS, but we don't have an issue there) doesn't meet certain
|
||||||
|
+ * criteria. As we must not allow less than fully privileged mode to have
|
||||||
|
+ * such an effect on the domain, we correct rIP in that case (accepting
|
||||||
|
+ * this not being architecturally correct behavior, as the injected #GP
|
||||||
|
+ * fault will then not see the correct [invalid] return address).
|
||||||
|
+ * And since we know the guest will crash, we crash it right away if it
|
||||||
|
+ * already is in most privileged mode.
|
||||||
|
+ */
|
||||||
|
+ mode = vmx_guest_x86_mode(v);
|
||||||
|
+ if ( mode == 8 ? !is_canonical_address(regs->rip)
|
||||||
|
+ : regs->rip != regs->_eip )
|
||||||
|
+ {
|
||||||
|
+ struct segment_register ss;
|
||||||
|
+
|
||||||
|
+ gprintk(XENLOG_WARNING, "Bad rIP %lx for mode %u\n", regs->rip, mode);
|
||||||
|
+
|
||||||
|
+ vmx_get_segment_register(v, x86_seg_ss, &ss);
|
||||||
|
+ if ( ss.attr.fields.dpl )
|
||||||
|
+ {
|
||||||
|
+ __vmread(VM_ENTRY_INTR_INFO, &intr_info);
|
||||||
|
+ if ( !(intr_info & INTR_INFO_VALID_MASK) )
|
||||||
|
+ hvm_inject_hw_exception(TRAP_gp_fault, 0);
|
||||||
|
+ /* Need to fix rIP nevertheless. */
|
||||||
|
+ if ( mode == 8 )
|
||||||
|
+ regs->rip = (long)(regs->rip << (64 - VADDR_BITS)) >>
|
||||||
|
+ (64 - VADDR_BITS);
|
||||||
|
+ else
|
||||||
|
+ regs->rip = regs->_eip;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ domain_crash(v->domain);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void vmx_vmenter_helper(const struct cpu_user_regs *regs)
|
Loading…
Reference in New Issue
Block a user