Hello community,

here is the log from the commit of package xen for openSUSE:Factory checked in 
at 2018-05-13 15:55:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/xen (Old)
 and      /work/SRC/openSUSE:Factory/.xen.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "xen"

Sun May 13 15:55:00 2018 rev:247 rq:605943 version:4.10.0_20

Changes:
--------
--- /work/SRC/openSUSE:Factory/xen/xen.changes  2018-04-27 16:00:39.633358022 
+0200
+++ /work/SRC/openSUSE:Factory/.xen.new/xen.changes     2018-05-13 
15:55:05.864152498 +0200
@@ -1,0 +2,29 @@
+Wed May  9 08:32:42 MDT 2018 - carn...@suse.com
+
+- bsc#1092543 - GCC 8: xen build fails
+  5ac72a48-gcc8.patch
+  5ac72a5f-gcc8.patch
+  5ac72a64-gcc8.patch
+  5ac72a69-gcc8.patch
+  5ac72a6e-gcc8.patch
+  5ac72a74-gcc8.patch
+  5ac72a7b-gcc8.patch
+  gcc8-inlining-failed.patch
+
+-------------------------------------------------------------------
+Wed Apr 25 09:45:03 MDT 2018 - carn...@suse.com
+
+- bsc#1090820 - VUL-0: CVE-2018-8897: xen: x86: mishandling of
+  debug exceptions (XSA-260)
+  xsa260-1.patch
+  xsa260-2.patch
+  xsa260-3.patch
+  xsa260-4.patch
+- bsc#1090822 - VUL-0: xen: x86 vHPET interrupt injection errors
+  (XSA-261)
+  xsa261.patch
+- bsc#1090823 - VUL-0: xen: qemu may drive Xen into unbounded loop
+  (XSA-262)
+  xsa262.patch
+
+-------------------------------------------------------------------
@@ -4,2 +33,2 @@
-- bsc#1089152 - VUL-0: xen: Information leak via crafted
-  user-supplied CDROM (XSA-258)
+- bsc#1089152 - VUL-0: CVE-2018-10472: xen: Information leak via
+  crafted user-supplied CDROM (XSA-258)
@@ -7,2 +36,2 @@
-- bsc#1089635 - VUL-0: xen: x86: PV guest may crash Xen with XPTI
-  (XSA-259)
+- bsc#1089635 - VUL-0: CVE-2018-10471: xen: x86: PV guest may crash
+  Xen with XPTI (XSA-259)

New:
----
  5ac72a48-gcc8.patch
  5ac72a5f-gcc8.patch
  5ac72a64-gcc8.patch
  5ac72a69-gcc8.patch
  5ac72a6e-gcc8.patch
  5ac72a74-gcc8.patch
  5ac72a7b-gcc8.patch
  gcc8-inlining-failed.patch
  xsa260-1.patch
  xsa260-2.patch
  xsa260-3.patch
  xsa260-4.patch
  xsa261.patch
  xsa262.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ xen.spec ++++++
--- /var/tmp/diff_new_pack.lVeVER/_old  2018-05-13 15:55:08.912041275 +0200
+++ /var/tmp/diff_new_pack.lVeVER/_new  2018-05-13 15:55:08.912041275 +0200
@@ -126,7 +126,7 @@
 BuildRequires:  pesign-obs-integration
 %endif
 
-Version:        4.10.0_18
+Version:        4.10.0_20
 Release:        0
 Summary:        Xen Virtualization: Hypervisor (aka VMM aka Microkernel)
 License:        GPL-2.0
@@ -224,8 +224,21 @@
 Patch61:        5a9eb890-x86-remove-CR-reads-from-exit-to-guest-path.patch
 Patch62:        5aa2b6b9-cpufreq-ondemand-CPU-offlining-race.patch
 Patch63:        5aaa9878-x86-vlapic-clear-TMR-bit-for-edge-triggered-intr.patch
+Patch64:        5ac72a48-gcc8.patch
+Patch65:        5ac72a5f-gcc8.patch
+Patch66:        5ac72a64-gcc8.patch
+Patch67:        5ac72a69-gcc8.patch
+Patch68:        5ac72a6e-gcc8.patch
+Patch69:        5ac72a74-gcc8.patch
+Patch70:        5ac72a7b-gcc8.patch
 Patch258:       xsa258.patch
 Patch259:       xsa259.patch
+Patch26001:     xsa260-1.patch
+Patch26002:     xsa260-2.patch
+Patch26003:     xsa260-3.patch
+Patch26004:     xsa260-4.patch
+Patch261:       xsa261.patch
+Patch262:       xsa262.patch
 # Our platform specific patches
 Patch400:       xen-destdir.patch
 Patch401:       vif-bridge-no-iptables.patch
@@ -239,6 +252,7 @@
 Patch421:       xenpaging.doc.patch
 Patch422:       stubdom-have-iovec.patch
 Patch423:       vif-route.patch
+Patch424:       gcc8-inlining-failed.patch
 # Other bug fixes or features
 Patch451:       xenconsole-no-multiple-connections.patch
 Patch452:       hibernate.patch
@@ -479,8 +493,21 @@
 %patch61 -p1
 %patch62 -p1
 %patch63 -p1
+%patch64 -p1
+%patch65 -p1
+%patch66 -p1
+%patch67 -p1
+%patch68 -p1
+%patch69 -p1
+%patch70 -p1
 %patch258 -p1
 %patch259 -p1
+%patch26001 -p1
+%patch26002 -p1
+%patch26003 -p1
+%patch26004 -p1
+%patch261 -p1
+%patch262 -p1
 # Our platform specific patches
 %patch400 -p1
 %patch401 -p1
@@ -494,6 +521,7 @@
 %patch421 -p1
 %patch422 -p1
 %patch423 -p1
+%patch424 -p1
 # Other bug fixes or features
 %patch451 -p1
 %patch452 -p1

++++++ 5ac72a48-gcc8.patch ++++++
Subject: tools/libxc: fix strncpy size
From: Marek Marczykowski-Górecki marma...@invisiblethingslab.com Thu Apr 5 
03:50:49 2018 +0200
Date: Fri Apr 6 09:05:28 2018 +0100:
Git: fa7789ef18bd2e716997937af71b2e4b5b00a159

gcc-8 warns about possible truncation of trailing '\0'.
Final character is overridden by '\0' anyway, so don't bother to copy
it.

This fixes compile failure:

    xc_pm.c: In function 'xc_set_cpufreq_gov':
    xc_pm.c:308:5: error: 'strncpy' specified bound 16 equals destination size 
[-Werror=stringop-truncation]
         strncpy(scaling_governor, govname, CPUFREQ_NAME_LEN);
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    cc1: all warnings being treated as errors

Signed-off-by: Marek Marczykowski-Górecki <marma...@invisiblethingslab.com>
Acked-by: Wei Liu <wei.l...@citrix.com>
Release-Acked-by: Juergen Gross <jgr...@suse.com>

diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c
index 67e2418e3f..6f8d548e44 100644
--- a/tools/libxc/xc_pm.c
+++ b/tools/libxc/xc_pm.c
@@ -305,7 +305,7 @@ int xc_set_cpufreq_gov(xc_interface *xch, int cpuid, char 
*govname)
     sysctl.cmd = XEN_SYSCTL_pm_op;
     sysctl.u.pm_op.cmd = SET_CPUFREQ_GOV;
     sysctl.u.pm_op.cpuid = cpuid;
-    strncpy(scaling_governor, govname, CPUFREQ_NAME_LEN);
+    strncpy(scaling_governor, govname, CPUFREQ_NAME_LEN - 1);
     scaling_governor[CPUFREQ_NAME_LEN - 1] = '\0';
 
     return xc_sysctl(xch, &sysctl);
++++++ 5ac72a5f-gcc8.patch ++++++
Subject: tools/misc: fix hypothetical buffer overflow in xen-lowmemd
From: Marek Marczykowski-Górecki marma...@invisiblethingslab.com Thu Apr 5 
03:50:50 2018 +0200
Date: Fri Apr 6 09:05:51 2018 +0100:
Git: 27751d89248c8c5eef6d8b56eb8f7d2084145080

gcc-8 complains:

    xen-lowmemd.c: In function 'handle_low_mem':
    xen-lowmemd.c:80:55: error: '%s' directive output may be truncated writing 
up to 511 bytes into a region of size 489 [-Werror=format-truncation=]
             snprintf(error, BUFSZ,"Failed to write target %s to xenstore", 
data);
                                                           ^~               ~~~~
    xen-lowmemd.c:80:9: note: 'snprintf' output between 36 and 547 bytes into a 
destination of size 512
             snprintf(error, BUFSZ,"Failed to write target %s to xenstore", 
data);
             
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In practice it wouldn't happen, because 'data' contains string
representation of 64-bit unsigned number (20 characters at most).
But place a limit to mute gcc warning.

Signed-off-by: Marek Marczykowski-Górecki <marma...@invisiblethingslab.com>
Acked-by: Wei Liu <wei.l...@citrix.com>
Release-Acked-by: Juergen Gross <jgr...@suse.com>

diff --git a/tools/misc/xen-lowmemd.c b/tools/misc/xen-lowmemd.c
index 865a54cec1..79ad34cb4a 100644
--- a/tools/misc/xen-lowmemd.c
+++ b/tools/misc/xen-lowmemd.c
@@ -77,7 +77,7 @@ void handle_low_mem(void)
     if (!xs_write(xs_handle, XBT_NULL, 
             "/local/domain/0/memory/target", data, strlen(data)))
     {
-        snprintf(error, BUFSZ,"Failed to write target %s to xenstore", data);
+        snprintf(error, BUFSZ,"Failed to write target %.24s to xenstore", 
data);
         perror(error);
     }
 }
++++++ 5ac72a64-gcc8.patch ++++++
Subject: tools/xenpmd: fix possible '\0' truncation
From: Marek Marczykowski-Górecki marma...@invisiblethingslab.com Thu Apr 5 
03:50:53 2018 +0200
Date: Fri Apr 6 09:05:56 2018 +0100:
Git: 938c8f53b1f80175c6f7a1399efdb984abb0cb8b

gcc-8 complains:
    xenpmd.c:207:9: error: 'strncpy' specified bound 32 equals destination size 
[-Werror=stringop-truncation]
             strncpy(info->oem_info, attrib_value, 32);
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    xenpmd.c:201:9: error: 'strncpy' specified bound 32 equals destination size 
[-Werror=stringop-truncation]
             strncpy(info->battery_type, attrib_value, 32);
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    xenpmd.c:195:9: error: 'strncpy' specified bound 32 equals destination size 
[-Werror=stringop-truncation]
             strncpy(info->serial_number, attrib_value, 32);
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    xenpmd.c:189:9: error: 'strncpy' specified bound 32 equals destination size 
[-Werror=stringop-truncation]
             strncpy(info->model_number, attrib_value, 32);
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Copy 31 chars, then make sure terminating '\0' is present. Those fields
are passed to strlen and as '%s' for snprintf later.

Signed-off-by: Marek Marczykowski-Górecki <marma...@invisiblethingslab.com>
Acked-by: Wei Liu <wei.l...@citrix.com>
Release-Acked-by: Juergen Gross <jgr...@suse.com>

diff --git a/tools/xenpmd/xenpmd.c b/tools/xenpmd/xenpmd.c
index 689c8fd670..56412a9a81 100644
--- a/tools/xenpmd/xenpmd.c
+++ b/tools/xenpmd/xenpmd.c
@@ -186,25 +186,29 @@ void set_attribute_battery_info(char *attrib_name,
 
     if ( strstr(attrib_name, "model number") ) 
     {
-        strncpy(info->model_number, attrib_value, 32);
+        strncpy(info->model_number, attrib_value, 31);
+        info->model_number[31] = '\0';
         return;
     }
 
     if ( strstr(attrib_name, "serial number") ) 
     {
-        strncpy(info->serial_number, attrib_value, 32);
+        strncpy(info->serial_number, attrib_value, 31);
+        info->serial_number[31] = '\0';
         return;
     }
 
     if ( strstr(attrib_name, "battery type") ) 
     {
-        strncpy(info->battery_type, attrib_value, 32);
+        strncpy(info->battery_type, attrib_value, 31);
+        info->battery_type[31] = '\0';
         return;
     }
 
     if ( strstr(attrib_name, "OEM info") ) 
     {
-        strncpy(info->oem_info, attrib_value, 32);
+        strncpy(info->oem_info, attrib_value, 31);
+        info->oem_info[31] = '\0';
         return;
     }
 
++++++ 5ac72a69-gcc8.patch ++++++
Subject: tools/gdbsx: fix -Wstringop-truncation warning
From: Marek Marczykowski-Górecki marma...@invisiblethingslab.com Thu Apr 5 
03:50:54 2018 +0200
Date: Fri Apr 6 09:06:01 2018 +0100:
Git: 7f601f7c341c80d554615556d60e3b8ed1e5ad4f

gcc-8 complains:

    gx_main.c: In function 'prepare_stop_reply':
    gx_main.c:385:9: error: 'strncpy' output truncated before terminating nul 
copying 6 bytes from a string of the same length [-Werror=stringop-truncation]
             strncpy(buf, "watch:", 6);
             ^~~~~~~~~~~~~~~~~~~~~~~~~

Since terminating '\0' isn't needed here at all, switch to memcpy.

Signed-off-by: Marek Marczykowski-Górecki <marma...@invisiblethingslab.com>
Acked-by: Wei Liu <wei.l...@citrix.com>
Release-Acked-by: Juergen Gross <jgr...@suse.com>

diff --git a/tools/debugger/gdbsx/gx/gx_main.c 
b/tools/debugger/gdbsx/gx/gx_main.c
index a908c45e1d..6dfa501145 100644
--- a/tools/debugger/gdbsx/gx/gx_main.c
+++ b/tools/debugger/gdbsx/gx/gx_main.c
@@ -382,7 +382,7 @@ prepare_stop_reply(enum target_signal sig, char *buf, 
vcpuid_t vcpu)
 
     /* TBD: check if we stopped because of watchpoint */
     if (watchpoint_stop()) {
-        strncpy(buf, "watch:", 6);
+        memcpy(buf, "watch:", 6);
         buf += 6;
         /* TBD: **/
     }
++++++ 5ac72a6e-gcc8.patch ++++++
Subject: tools/blktap2: fix possible '\0' truncation
From: Marek Marczykowski-Górecki marma...@invisiblethingslab.com Thu Apr 5 
03:50:52 2018 +0200
Date: Fri Apr 6 09:06:06 2018 +0100:
Git: 850e89b3ef1a7be6b71fa7ae22333c884e08431a

gcc-8 complains:

    tapdisk-vbd.c: In function 'tapdisk_vbd_resume_ring':
    tapdisk-vbd.c:1671:53: error: 'snprintf' output may be truncated before the 
last format character [-Werror=format-truncation=]
       snprintf(params.name, sizeof(params.name) - 1, "%s", message);
                                                         ^
    tapdisk-vbd.c:1671:3: note: 'snprintf' output between 1 and 256 bytes into 
a destination of size 255
       snprintf(params.name, sizeof(params.name) - 1, "%s", message);
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The "- 1" in buffer size should be actually applied to message, to leave
place for terminating '\0', not the other way around (truncate '\0' even
if it would fit).

    In function 'tapdisk_control_open_image',
        inlined from 'tapdisk_control_handle_request' at 
tapdisk-control.c:660:10:
    tapdisk-control.c:465:2: error: 'strncpy' specified bound 256 equals 
destination size [-Werror=stringop-truncation]
      strncpy(params.name, vbd->name, BLKTAP2_MAX_MESSAGE_LEN);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    In function 'tapdisk_control_create_socket',
        inlined from 'tapdisk_control_open' at tapdisk-control.c:836:9:
    tapdisk-control.c:793:2: error: 'strncpy' specified bound 108 equals 
destination size [-Werror=stringop-truncation]
      strncpy(saddr.sun_path, td_control.path, sizeof(saddr.sun_path));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    block-qcow.c: In function 'qcow_create':
    block-qcow.c:1216:5: error: 'strncpy' specified bound 4096 equals 
destination size [-Werror=stringop-truncation]
         strncpy(backing_filename, backing_file,
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          sizeof(backing_filename));
          ~~~~~~~~~~~~~~~~~~~~~~~~~

I those cases, reduce size of copied string and make sure final '\0' is
added.

Signed-off-by: Marek Marczykowski-Górecki <marma...@invisiblethingslab.com>
Acked-by: Wei Liu <wei.l...@citrix.com>
Release-Acked-by: Juergen Gross <jgr...@suse.com>

diff --git a/tools/blktap2/drivers/block-qcow.c 
b/tools/blktap2/drivers/block-qcow.c
index b45bcaa077..ae439221ab 100644
--- a/tools/blktap2/drivers/block-qcow.c
+++ b/tools/blktap2/drivers/block-qcow.c
@@ -1214,7 +1214,8 @@ int qcow_create(const char *filename, uint64_t total_size,
                        if (p && (p - backing_file) >= 2) {
                                /* URL like but exclude "c:" like filenames */
                                strncpy(backing_filename, backing_file,
-                                       sizeof(backing_filename));
+                                       sizeof(backing_filename) - 1);
+                               backing_filename[sizeof(backing_filename) - 1] 
= '\0';
                        } else {
                                if (realpath(backing_file, backing_filename) == 
NULL ||
                                    stat(backing_filename, &st) != 0) {
diff --git a/tools/blktap2/drivers/tapdisk-control.c 
b/tools/blktap2/drivers/tapdisk-control.c
index 0b5cf3cdd3..3ca5713063 100644
--- a/tools/blktap2/drivers/tapdisk-control.c
+++ b/tools/blktap2/drivers/tapdisk-control.c
@@ -462,7 +462,8 @@ tapdisk_control_open_image(struct 
tapdisk_control_connection *connection,
 
        params.capacity = image.size;
        params.sector_size = image.secsize;
-       strncpy(params.name, vbd->name, BLKTAP2_MAX_MESSAGE_LEN);
+       strncpy(params.name, vbd->name, BLKTAP2_MAX_MESSAGE_LEN - 1);
+       params.name[BLKTAP2_MAX_MESSAGE_LEN - 1] = '\0';
 
        err = ioctl(vbd->ring.fd, BLKTAP2_IOCTL_CREATE_DEVICE, &params);
        if (err && errno != EEXIST) {
@@ -790,7 +791,7 @@ tapdisk_control_create_socket(char **socket_path)
        }
 
        memset(&saddr, 0, sizeof(saddr));
-       strncpy(saddr.sun_path, td_control.path, sizeof(saddr.sun_path));
+       strncpy(saddr.sun_path, td_control.path, sizeof(saddr.sun_path) - 1);
        saddr.sun_family = AF_UNIX;
 
        err = bind(td_control.socket,
diff --git a/tools/blktap2/drivers/tapdisk-vbd.c 
b/tools/blktap2/drivers/tapdisk-vbd.c
index fd4999a5ec..842a427861 100644
--- a/tools/blktap2/drivers/tapdisk-vbd.c
+++ b/tools/blktap2/drivers/tapdisk-vbd.c
@@ -1668,7 +1668,8 @@ out:
 
                params.sector_size = image.secsize;
                params.capacity    = image.size;
-               snprintf(params.name, sizeof(params.name) - 1, "%s", message);
+               snprintf(params.name, sizeof(params.name),
+                        "%.*s", (int)sizeof(params.name) - 1, message);
 
                ioctl(vbd->ring.fd, BLKTAP2_IOCTL_SET_PARAMS, &params);
                td_flag_clear(vbd->state, TD_VBD_PAUSED);
++++++ 5ac72a74-gcc8.patch ++++++
Subject: tools/blktap2: fix hypothetical buffer overflow
From: Marek Marczykowski-Górecki marma...@invisiblethingslab.com Thu Apr 5 
03:50:51 2018 +0200
Date: Fri Apr 6 09:06:12 2018 +0100:
Git: 3a633c261426f06627d88bf7feca6ff87f692f16

gcc-8 complains:

    vhd-util-read.c: In function 'vhd_util_read':
    vhd-util-read.c:50:24: error: '%lu' directive output may be truncated 
writing between 1 and 20 bytes into a region of size 15 
[-Werror=format-truncation=]
      snprintf(nbuf, nsize, "%" PRIu64, num);
                            ^~~
    vhd-util-read.c:50:25: note: format string is defined here
      snprintf(nbuf, nsize, "%" PRIu64, num);
    vhd-util-read.c:50:24: note: directive argument in the range [0, 
18446744073709551614]
      snprintf(nbuf, nsize, "%" PRIu64, num);
                            ^~~
    vhd-util-read.c:50:2: note: 'snprintf' output between 2 and 21 bytes into a 
destination of size 15
      snprintf(nbuf, nsize, "%" PRIu64, num);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    vhd-util-read.c:43:24: error: '%#lx' directive output may be truncated 
writing between 1 and 18 bytes into a region of size 15 
[-Werror=format-truncation=]
      snprintf(nbuf, nsize, "%#" PRIx64 , num);
                            ^~~~
    vhd-util-read.c:43:25: note: format string is defined here
      snprintf(nbuf, nsize, "%#" PRIx64 , num);
    vhd-util-read.c:43:24: note: directive argument in the range [0, 
18446744073709551614]
      snprintf(nbuf, nsize, "%#" PRIx64 , num);
                            ^~~~
    vhd-util-read.c:43:2: note: 'snprintf' output between 2 and 19 bytes into a 
destination of size 15
      snprintf(nbuf, nsize, "%#" PRIx64 , num);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Make the buffer larger.

Signed-off-by: Marek Marczykowski-Górecki <marma...@invisiblethingslab.com>
Acked-by: Wei Liu <wei.l...@citrix.com>
Release-Acked-by: Juergen Gross <jgr...@suse.com>

diff --git a/tools/blktap2/vhd/lib/vhd-util-read.c 
b/tools/blktap2/vhd/lib/vhd-util-read.c
index ac4d833cbc..f29066169f 100644
--- a/tools/blktap2/vhd/lib/vhd-util-read.c
+++ b/tools/blktap2/vhd/lib/vhd-util-read.c
@@ -34,7 +34,7 @@
 #include "libvhd.h"
 #include "vhd-util.h"
 
-#define nsize     15
+#define nsize     24
 static char nbuf[nsize];
 
 static inline char *
++++++ 5ac72a7b-gcc8.patch ++++++
Subject: tools/kdd: mute spurious gcc warning
From: Marek Marczykowski-Górecki marma...@invisiblethingslab.com Thu Apr 5 
03:50:55 2018 +0200
Date: Fri Apr 6 09:06:19 2018 +0100:
Git: 437e00fea04becc91c1b6bc1c0baa636b067a5cc

gcc-8 complains:

    kdd.c:698:13: error: 'memcpy' offset [-204, -717] is out of the bounds [0, 
216] of object 'ctrl' with type 'kdd_ctrl' {aka 'union <anonymous>'} 
[-Werror=array-bounds]
                 memcpy(buf, ((uint8_t *)&ctrl.c32) + offset, len);
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    kdd.c: In function 'kdd_select_callback':
    kdd.c:642:14: note: 'ctrl' declared here
         kdd_ctrl ctrl;
                  ^~~~

But this is impossible - 'offset' is unsigned and correctly validated
few lines before.

Signed-off-by: Marek Marczykowski-Górecki <marma...@invisiblethingslab.com>
Acked-by: Wei Liu <wei.l...@citrix.com>
Release-Acked-by: Juergen Gross <jgr...@suse.com>

diff --git a/tools/debugger/kdd/kdd.c b/tools/debugger/kdd/kdd.c
index 1bd5dd5992..61d769ece9 100644
--- a/tools/debugger/kdd/kdd.c
+++ b/tools/debugger/kdd/kdd.c
@@ -695,7 +695,10 @@ static void kdd_handle_read_ctrl(kdd_state *s)
             KDD_LOG(s, "Request outside of known control space\n");
             len = 0;
         } else {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
             memcpy(buf, ((uint8_t *)&ctrl.c32) + offset, len);
+#pragma GCC diagnostic pop
         }
     }
 
++++++ README.SUSE ++++++
--- /var/tmp/diff_new_pack.lVeVER/_old  2018-05-13 15:55:09.252028868 +0200
+++ /var/tmp/diff_new_pack.lVeVER/_new  2018-05-13 15:55:09.256028723 +0200
@@ -91,20 +91,15 @@
 use virtual network and block device drivers in the unprivileged VMs to access
 the physical network and block drivers in the VM server.
 
-For simplicity, SUSE ships a single Xen-enabled Linux kernel, rather than
-separate privileged and unprivileged kernels.  As most of the hardware drivers
-are modules anyway, using this kernel as an unprivileged kernel has very
-little extra overhead.
-
-The kernel is contained in the kernel-xen package, which you need to install to
-use Xen.
+SUSE ships a single PVOPS enabled Linux kernel that may be used for booting
+natively and also with the Xen hypervisor.
 
 
 Booting
 -------
-If you installed Xen during the initial SUSE installation, or installed one
-of the kernel-xen* packages later, a "XEN" option should exist in your Grub
-bootloader.  Select that to boot SUSE on top of Xen.
+If you installed Xen during the initial SUSE installation, or installed xen
+later, a "XEN" option should exist in your Grub bootloader.  Select that to
+boot SUSE on top of Xen.
 
 If you want to add additional entries, or modify the existing ones, you may
 run the YaST2 Boot Loader program.
@@ -531,7 +526,7 @@
 ---------------
 First try to get Linux running on bare metal before trying with Xen.
 
-Be sure your Xen hypervisor (xen) and VM kernels (kernel-xen) are compatible.
+Be sure your Xen hypervisor (xen) and VM kernels are compatible.
 The hypervisor and domain 0 kernel are a matched set, and usually must be
 upgraded together.  Consult the online documentation for a matrix of supported
 32- and 64-bit combinations

++++++ gcc8-inlining-failed.patch ++++++
References: bsc#1092543

Fixes several errors like this:

/usr/include/bits/string_fortified.h:31:1: error: inlining failed in call to 
always_inline 'memcpy': target specific option mismatch
 __NTH (memcpy (void *__restrict __dest, const void *__restrict __src,
 ^~~~~
fuzz-emul.c:66:5: note: called from here
     memcpy(dst, &s->corpus->data[s->data_index], size);


--- xen-4.10.0-testing/tools/fuzz/x86_instruction_emulator/Makefile.orig        
2018-05-09 13:28:32.319422725 -0600
+++ xen-4.10.0-testing/tools/fuzz/x86_instruction_emulator/Makefile     
2018-05-09 13:28:52.686645554 -0600
@@ -21,7 +21,7 @@ asm/%: asm ;
 x86-emulate.c x86-emulate.h: %:
        [ -L $* ] || ln -sf $(XEN_ROOT)/tools/tests/x86_emulator/$*
 
-CFLAGS += $(CFLAGS_xeninclude) -D__XEN_TOOLS__ -I.
+CFLAGS += $(CFLAGS_xeninclude) -D__XEN_TOOLS__ -I. -U_FORTIFY_SOURCE 
-U__USE_FORTIFY_LEVEL
 
 GCOV_FLAGS := --coverage
 %-cov.o: %.c
++++++ xsa260-1.patch ++++++
From: Andrew Cooper <andrew.coop...@citrix.com>
Subject: x86/traps: Fix %dr6 handing in #DB handler

Most bits in %dr6 accumulate, rather than being set directly based on the
current source of #DB.  Have the handler follow the manuals guidance, which
avoids leaking hypervisor debugging activities into guest context.

This is part of XSA-260 / CVE-2018-8897.

Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com>
Reviewed-by: Jan Beulich <jbeul...@suse.com>

--- a/xen/arch/x86/traps.c      2018-04-13 15:29:36.006747135 +0200
+++ b/xen/arch/x86/traps.c      2018-04-13 15:44:57.015516185 +0200
@@ -1761,11 +1761,36 @@ static void ler_enable(void)
 
 void do_debug(struct cpu_user_regs *regs)
 {
+    unsigned long dr6;
     struct vcpu *v = current;
 
+    /* Stash dr6 as early as possible. */
+    dr6 = read_debugreg(6);
+
     if ( debugger_trap_entry(TRAP_debug, regs) )
         return;
 
+    /*
+     * At the time of writing (March 2018), on the subject of %dr6:
+     *
+     * The Intel manual says:
+     *   Certain debug exceptions may clear bits 0-3. The remaining contents
+     *   of the DR6 register are never cleared by the processor. To avoid
+     *   confusion in identifying debug exceptions, debug handlers should
+     *   clear the register (except bit 16, which they should set) before
+     *   returning to the interrupted task.
+     *
+     * The AMD manual says:
+     *   Bits 15:13 of the DR6 register are not cleared by the processor and
+     *   must be cleared by software after the contents have been read.
+     *
+     * Some bits are reserved set, some are reserved clear, and some bits
+     * which were previously reserved set are reused and cleared by hardware.
+     * For future compatibility, reset to the default value, which will allow
+     * us to spot any bit being changed by hardware to its non-default value.
+     */
+    write_debugreg(6, X86_DR6_DEFAULT);
+
     if ( !guest_mode(regs) )
     {
         if ( regs->eflags & X86_EFLAGS_TF )
@@ -1798,7 +1823,8 @@ void do_debug(struct cpu_user_regs *regs
     }
 
     /* Save debug status register where guest OS can peek at it */
-    v->arch.debugreg[6] = read_debugreg(6);
+    v->arch.debugreg[6] |= (dr6 & ~X86_DR6_DEFAULT);
+    v->arch.debugreg[6] &= (dr6 | ~X86_DR6_DEFAULT);
 
     ler_enable();
     pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
--- a/xen/include/asm-x86/debugreg.h    2015-02-11 09:36:29.000000000 +0100
+++ b/xen/include/asm-x86/debugreg.h    2018-04-13 15:44:57.015516185 +0200
@@ -24,6 +24,8 @@
 #define DR_STATUS_RESERVED_ZERO (~0xffffeffful) /* Reserved, read as zero */
 #define DR_STATUS_RESERVED_ONE  0xffff0ff0ul /* Reserved, read as one */
 
+#define X86_DR6_DEFAULT 0xffff0ff0ul    /* Default %dr6 value. */
+
 /* Now define a bunch of things for manipulating the control register.
    The top two bytes of the control register consist of 4 fields of 4
    bits - each field corresponds to one of the four debug registers,
++++++ xsa260-2.patch ++++++
From: Andrew Cooper <andrew.coop...@citrix.com>
Subject: x86/pv: Move exception injection into {,compat_}test_all_events()

This allows paths to jump straight to {,compat_}test_all_events() and have
injection of pending exceptions happen automatically, rather than requiring
all calling paths to handle exceptions themselves.

The normal exception path is simplified as a result, and
compat_post_handle_exception() is removed entirely.

This is part of XSA-260 / CVE-2018-8897.

Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com>
Reviewed-by: Jan Beulich <jbeul...@suse.com>

Index: xen-4.10.0-testing/xen/arch/x86/x86_64/compat/entry.S
===================================================================
--- xen-4.10.0-testing.orig/xen/arch/x86/x86_64/compat/entry.S
+++ xen-4.10.0-testing/xen/arch/x86/x86_64/compat/entry.S
@@ -41,6 +41,12 @@ ENTRY(compat_test_all_events)
         leaq  irq_stat+IRQSTAT_softirq_pending(%rip),%rcx
         cmpl  $0,(%rcx,%rax,1)
         jne   compat_process_softirqs
+
+        /* Inject exception if pending. */
+        lea   VCPU_trap_bounce(%rbx), %rdx
+        testb $TBF_EXCEPTION, TRAPBOUNCE_flags(%rdx)
+        jnz   .Lcompat_process_trapbounce
+
         testb $1,VCPU_mce_pending(%rbx)
         jnz   compat_process_mce
 .Lcompat_test_guest_nmi:
@@ -70,6 +76,15 @@ compat_process_softirqs:
         call  do_softirq
         jmp   compat_test_all_events
 
+        ALIGN
+/* %rbx: struct vcpu, %rdx: struct trap_bounce */
+.Lcompat_process_trapbounce:
+        sti
+.Lcompat_bounce_exception:
+        call  compat_create_bounce_frame
+        movb  $0, TRAPBOUNCE_flags(%rdx)
+        jmp   compat_test_all_events
+
        ALIGN
 /* %rbx: struct vcpu */
 compat_process_mce:
@@ -191,15 +206,6 @@ ENTRY(cr4_pv32_restore)
         xor   %eax, %eax
         ret
 
-/* %rdx: trap_bounce, %rbx: struct vcpu */
-ENTRY(compat_post_handle_exception)
-        testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
-        jz    compat_test_all_events
-.Lcompat_bounce_exception:
-        call  compat_create_bounce_frame
-        movb  $0,TRAPBOUNCE_flags(%rdx)
-        jmp   compat_test_all_events
-
 /* See lstar_enter for entry register state. */
 ENTRY(cstar_enter)
         /* sti could live here when we don't switch page tables below. */
Index: xen-4.10.0-testing/xen/arch/x86/x86_64/entry.S
===================================================================
--- xen-4.10.0-testing.orig/xen/arch/x86/x86_64/entry.S
+++ xen-4.10.0-testing/xen/arch/x86/x86_64/entry.S
@@ -201,6 +201,12 @@ test_all_events:
         leaq  irq_stat+IRQSTAT_softirq_pending(%rip),%rcx
         cmpl  $0,(%rcx,%rax,1)
         jne   process_softirqs
+
+        /* Inject exception if pending. */
+        lea   VCPU_trap_bounce(%rbx), %rdx
+        testb $TBF_EXCEPTION, TRAPBOUNCE_flags(%rdx)
+        jnz   .Lprocess_trapbounce
+
         testb $1,VCPU_mce_pending(%rbx)
         jnz   process_mce
 .Ltest_guest_nmi:
@@ -229,6 +235,15 @@ process_softirqs:
         jmp  test_all_events
 
         ALIGN
+/* %rbx: struct vcpu, %rdx struct trap_bounce */
+.Lprocess_trapbounce:
+        sti
+.Lbounce_exception:
+        call  create_bounce_frame
+        movb  $0, TRAPBOUNCE_flags(%rdx)
+        jmp   test_all_events
+
+        ALIGN
 /* %rbx: struct vcpu */
 process_mce:
         testb $1 << VCPU_TRAP_MCE,VCPU_async_exception_mask(%rbx)
@@ -648,15 +663,9 @@ handle_exception_saved:
         mov   %r15, STACK_CPUINFO_FIELD(xen_cr3)(%r14)
         testb $3,UREGS_cs(%rsp)
         jz    restore_all_xen
-        leaq  VCPU_trap_bounce(%rbx),%rdx
         movq  VCPU_domain(%rbx),%rax
         testb $1,DOMAIN_is_32bit_pv(%rax)
-        jnz   compat_post_handle_exception
-        testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
-        jz    test_all_events
-.Lbounce_exception:
-        call  create_bounce_frame
-        movb  $0,TRAPBOUNCE_flags(%rdx)
+        jnz   compat_test_all_events
         jmp   test_all_events
 
 /* No special register assumptions. */
++++++ xsa260-3.patch ++++++
From: Andrew Cooper <andrew.coop...@citrix.com>
Subject: x86/traps: Use an Interrupt Stack Table for #DB

PV guests can use architectural corner cases to cause #DB to be raised after
transitioning into supervisor mode.

Use an interrupt stack table for #DB to prevent the exception being taken with
a guest controlled stack pointer.

This is part of XSA-260 / CVE-2018-8897.

Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com>
Reviewed-by: Jan Beulich <jbeul...@suse.com>

Index: xen-4.10.0-testing/xen/arch/x86/cpu/common.c
===================================================================
--- xen-4.10.0-testing.orig/xen/arch/x86/cpu/common.c
+++ xen-4.10.0-testing/xen/arch/x86/cpu/common.c
@@ -679,6 +679,7 @@ void load_system_tables(void)
                        [IST_MCE - 1] = stack_top + IST_MCE * PAGE_SIZE,
                        [IST_DF  - 1] = stack_top + IST_DF  * PAGE_SIZE,
                        [IST_NMI - 1] = stack_top + IST_NMI * PAGE_SIZE,
+                       [IST_DB  - 1] = stack_top + IST_DB  * PAGE_SIZE,
 
                        [IST_MAX ... ARRAY_SIZE(tss->ist) - 1] =
                                0x8600111111111111ul,
@@ -706,6 +707,7 @@ void load_system_tables(void)
        set_ist(&idt_tables[cpu][TRAP_double_fault],  IST_DF);
        set_ist(&idt_tables[cpu][TRAP_nmi],           IST_NMI);
        set_ist(&idt_tables[cpu][TRAP_machine_check], IST_MCE);
+       set_ist(&idt_tables[cpu][TRAP_debug],         IST_DB);
 
        /*
         * Bottom-of-stack must be 16-byte aligned!
Index: xen-4.10.0-testing/xen/arch/x86/hvm/svm/svm.c
===================================================================
--- xen-4.10.0-testing.orig/xen/arch/x86/hvm/svm/svm.c
+++ xen-4.10.0-testing/xen/arch/x86/hvm/svm/svm.c
@@ -1046,6 +1046,7 @@ static void svm_ctxt_switch_from(struct
     set_ist(&idt_tables[cpu][TRAP_double_fault],  IST_DF);
     set_ist(&idt_tables[cpu][TRAP_nmi],           IST_NMI);
     set_ist(&idt_tables[cpu][TRAP_machine_check], IST_MCE);
+    set_ist(&idt_tables[cpu][TRAP_debug],         IST_DB);
 }
 
 static void svm_ctxt_switch_to(struct vcpu *v)
@@ -1067,6 +1068,7 @@ static void svm_ctxt_switch_to(struct vc
     set_ist(&idt_tables[cpu][TRAP_double_fault],  IST_NONE);
     set_ist(&idt_tables[cpu][TRAP_nmi],           IST_NONE);
     set_ist(&idt_tables[cpu][TRAP_machine_check], IST_NONE);
+    set_ist(&idt_tables[cpu][TRAP_debug],         IST_NONE);
 
     svm_restore_dr(v);
 
Index: xen-4.10.0-testing/xen/arch/x86/smpboot.c
===================================================================
--- xen-4.10.0-testing.orig/xen/arch/x86/smpboot.c
+++ xen-4.10.0-testing/xen/arch/x86/smpboot.c
@@ -966,6 +966,7 @@ static int cpu_smpboot_alloc(unsigned in
     set_ist(&idt_tables[cpu][TRAP_double_fault],  IST_NONE);
     set_ist(&idt_tables[cpu][TRAP_nmi],           IST_NONE);
     set_ist(&idt_tables[cpu][TRAP_machine_check], IST_NONE);
+    set_ist(&idt_tables[cpu][TRAP_debug],         IST_NONE);
 
     for ( stub_page = 0, i = cpu & ~(STUBS_PER_PAGE - 1);
           i < nr_cpu_ids && i <= (cpu | (STUBS_PER_PAGE - 1)); ++i )
Index: xen-4.10.0-testing/xen/arch/x86/traps.c
===================================================================
--- xen-4.10.0-testing.orig/xen/arch/x86/traps.c
+++ xen-4.10.0-testing/xen/arch/x86/traps.c
@@ -325,13 +325,13 @@ static void show_guest_stack(struct vcpu
 /*
  * Notes for get_stack_trace_bottom() and get_stack_dump_bottom()
  *
- * Stack pages 0, 1 and 2:
+ * Stack pages 0 - 3:
  *   These are all 1-page IST stacks.  Each of these stacks have an exception
  *   frame and saved register state at the top.  The interesting bound for a
  *   trace is the word adjacent to this, while the bound for a dump is the
  *   very top, including the exception frame.
  *
- * Stack pages 3, 4 and 5:
+ * Stack pages 4 and 5:
  *   None of these are particularly interesting.  With MEMORY_GUARD, page 5 is
  *   explicitly not present, so attempting to dump or trace it is
  *   counterproductive.  Without MEMORY_GUARD, it is possible for a call chain
@@ -352,12 +352,12 @@ unsigned long get_stack_trace_bottom(uns
 {
     switch ( get_stack_page(sp) )
     {
-    case 0 ... 2:
+    case 0 ... 3:
         return ROUNDUP(sp, PAGE_SIZE) -
             offsetof(struct cpu_user_regs, es) - sizeof(unsigned long);
 
 #ifndef MEMORY_GUARD
-    case 3 ... 5:
+    case 4 ... 5:
 #endif
     case 6 ... 7:
         return ROUNDUP(sp, STACK_SIZE) -
@@ -372,11 +372,11 @@ unsigned long get_stack_dump_bottom(unsi
 {
     switch ( get_stack_page(sp) )
     {
-    case 0 ... 2:
+    case 0 ... 3:
         return ROUNDUP(sp, PAGE_SIZE) - sizeof(unsigned long);
 
 #ifndef MEMORY_GUARD
-    case 3 ... 5:
+    case 4 ... 5:
 #endif
     case 6 ... 7:
         return ROUNDUP(sp, STACK_SIZE) - sizeof(unsigned long);
@@ -1943,6 +1943,7 @@ void __init init_idt_traps(void)
     set_ist(&idt_table[TRAP_double_fault],  IST_DF);
     set_ist(&idt_table[TRAP_nmi],           IST_NMI);
     set_ist(&idt_table[TRAP_machine_check], IST_MCE);
+    set_ist(&idt_table[TRAP_debug],         IST_DB);
 
     /* CPU0 uses the master IDT. */
     idt_tables[0] = idt_table;
Index: xen-4.10.0-testing/xen/arch/x86/x86_64/entry.S
===================================================================
--- xen-4.10.0-testing.orig/xen/arch/x86/x86_64/entry.S
+++ xen-4.10.0-testing/xen/arch/x86/x86_64/entry.S
@@ -720,7 +720,7 @@ ENTRY(device_not_available)
 ENTRY(debug)
         pushq $0
         movl  $TRAP_debug,4(%rsp)
-        jmp   handle_exception
+        jmp   handle_ist_exception
 
 ENTRY(int3)
         pushq $0
Index: xen-4.10.0-testing/xen/include/asm-x86/processor.h
===================================================================
--- xen-4.10.0-testing.orig/xen/include/asm-x86/processor.h
+++ xen-4.10.0-testing/xen/include/asm-x86/processor.h
@@ -443,7 +443,8 @@ struct __packed __cacheline_aligned tss_
 #define IST_DF   1UL
 #define IST_NMI  2UL
 #define IST_MCE  3UL
-#define IST_MAX  3UL
+#define IST_DB   4UL
+#define IST_MAX  4UL
 
 /* Set the interrupt stack table used by a particular interrupt
  * descriptor table entry. */
++++++ xsa260-4.patch ++++++
From: Andrew Cooper <andrew.coop...@citrix.com>
Subject: x86/traps: Fix handling of #DB exceptions in hypervisor context

The WARN_ON() can be triggered by guest activities, and emits a full stack
trace without rate limiting.  Swap it out for a ratelimited printk with just
enough information to work out what is going on.

Not all #DB exceptions are traps, so blindly continuing is not a safe action
to take.  We don't let PV guests select these settings in the real %dr7 to
begin with, but for added safety against unexpected situations, detect the
fault cases and crash in an obvious manner.

This is part of XSA-260 / CVE-2018-8897.

Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com>
Reviewed-by: Jan Beulich <jbeul...@suse.com>

--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1809,16 +1809,44 @@ void do_debug(struct cpu_user_regs *regs
                 regs->eflags &= ~X86_EFLAGS_TF;
             }
         }
-        else
+
+        /*
+         * Check for fault conditions.  General Detect, and instruction
+         * breakpoints are faults rather than traps, at which point attempting
+         * to ignore and continue will result in a livelock.
+         */
+        if ( dr6 & DR_GENERAL_DETECT )
+        {
+            printk(XENLOG_ERR "Hit General Detect in Xen context\n");
+            fatal_trap(regs, 0);
+        }
+
+        if ( dr6 & (DR_TRAP3 | DR_TRAP2 | DR_TRAP1 | DR_TRAP0) )
         {
-            /*
-             * We ignore watchpoints when they trigger within Xen. This may
-             * happen when a buffer is passed to us which previously had a
-             * watchpoint set on it. No need to bump EIP; the only faulting
-             * trap is an instruction breakpoint, which can't happen to us.
-             */
-            WARN_ON(!search_exception_table(regs));
+            unsigned int bp, dr7 = read_debugreg(7) >> DR_CONTROL_SHIFT;
+
+            for ( bp = 0; bp < 4; ++bp )
+            {
+                if ( (dr6 & (1u << bp)) && /* Breakpoint triggered? */
+                     ((dr7 & (3u << (bp * DR_CONTROL_SIZE))) == 0) /* Insn? */ 
)
+                {
+                    printk(XENLOG_ERR
+                           "Hit instruction breakpoint in Xen context\n");
+                    fatal_trap(regs, 0);
+                }
+            }
         }
+
+        /*
+         * Whatever caused this #DB should be a trap.  Note it and continue.
+         * Guests can trigger this in certain corner cases, so ensure the
+         * message is ratelimited.
+         */
+        gprintk(XENLOG_WARNING,
+                "Hit #DB in Xen context: %04x:%p [%ps], stk %04x:%p, dr6 
%lx\n",
+                regs->cs, _p(regs->rip), _p(regs->rip),
+                regs->ss, _p(regs->rsp), dr6);
+
         goto out;
     }
 
++++++ xsa261.patch ++++++
From: Xen Project Security Team <secur...@xenproject.org>
Subject: x86/vpt: add support for IO-APIC routed interrupts

And modify the HPET code to make use of it. Currently HPET interrupts
are always treated as ISA and thus injected through the vPIC. This is
wrong because HPET interrupts when not in legacy mode should be
injected from the IO-APIC.

To make things worse, the supported interrupt routing values are set
to [20..23], which clearly falls outside of the ISA range, thus
leading to an ASSERT in debug builds or memory corruption in non-debug
builds because the interrupt injection code will write out of the
bounds of the arch.hvm_domain.vpic array.

Since the HPET interrupt source can change between ISA and IO-APIC
always destroy the timer before changing the mode, or else Xen risks
changing it while the timer is active.

Note that vpt interrupt injection is racy in the sense that the
vIO-APIC RTE entry can be written by the guest in between the call to
pt_irq_masked and hvm_ioapic_assert, or the call to pt_update_irq and
pt_intr_post. Those are not deemed to be security issues, but rather
quirks of the current implementation. In the worse case the guest
might lose interrupts or get multiple interrupt vectors injected for
the same timer source.

This is part of XSA-261.

Address actual and potential compiler warnings. Fix formatting.

Signed-off-by: Jan Beulich <jbeul...@suse.com>
---
Changes since v2:
 - Move fallthrough comment to be just above the case label.
 - Fix now stale comment in pt_update_irq.
 - Use NR_ISAIRQS instead of 16.
 - Expand commit message to mention the quirkiness of vpt interrupt
   injection.

Changes since v1:
 - Simply usage of gsi in pt_irq_masked.
 - Introduce hvm_ioapic_assert.
 - Fix pt->source == PTSRC_isa in create_periodic_time.

--- a/xen/arch/x86/hvm/hpet.c
+++ b/xen/arch/x86/hvm/hpet.c
@@ -264,13 +264,20 @@ static void hpet_set_timer(HPETState *h,
         diff = (timer_is_32bit(h, tn) && (-diff > HPET_TINY_TIME_SPAN))
             ? (uint32_t)diff : 0;
 
+    destroy_periodic_time(&h->pt[tn]);
     if ( (tn <= 1) && (h->hpet.config & HPET_CFG_LEGACY) )
+    {
         /* if LegacyReplacementRoute bit is set, HPET specification requires
            timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC,
            timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. */
         irq = (tn == 0) ? 0 : 8;
+        h->pt[tn].source = PTSRC_isa;
+    }
     else
+    {
         irq = timer_int_route(h, tn);
+        h->pt[tn].source = PTSRC_ioapic;
+    }
 
     /*
      * diff is the time from now when the timer should fire, for a periodic
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -41,6 +41,26 @@ static void assert_gsi(struct domain *d,
     vioapic_irq_positive_edge(d, ioapic_gsi);
 }
 
+int hvm_ioapic_assert(struct domain *d, unsigned int gsi, bool level)
+{
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
+    int vector;
+
+    if ( gsi >= hvm_irq->nr_gsis )
+    {
+        ASSERT_UNREACHABLE();
+        return -1;
+    }
+
+    spin_lock(&d->arch.hvm_domain.irq_lock);
+    if ( !level || hvm_irq->gsi_assert_count[gsi]++ == 0 )
+        assert_gsi(d, gsi);
+    vector = vioapic_get_vector(d, gsi);
+    spin_unlock(&d->arch.hvm_domain.irq_lock);
+
+    return vector;
+}
+
 static void assert_irq(struct domain *d, unsigned ioapic_gsi, unsigned pic_irq)
 {
     assert_gsi(d, ioapic_gsi);
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -107,31 +107,49 @@ static int pt_irq_vector(struct periodic
 static int pt_irq_masked(struct periodic_time *pt)
 {
     struct vcpu *v = pt->vcpu;
-    unsigned int gsi, isa_irq;
-    int mask;
-    uint8_t pic_imr;
+    unsigned int gsi = pt->irq;
 
-    if ( pt->source == PTSRC_lapic )
+    switch ( pt->source )
+    {
+    case PTSRC_lapic:
     {
         struct vlapic *vlapic = vcpu_vlapic(v);
+
         return (!vlapic_enabled(vlapic) ||
                 (vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_MASKED));
     }
 
-    isa_irq = pt->irq;
-    gsi = hvm_isa_irq_to_gsi(isa_irq);
-    pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr;
-    mask = vioapic_get_mask(v->domain, gsi);
-    if ( mask < 0 )
-    {
-        dprintk(XENLOG_WARNING, "d%u: invalid GSI (%u) for platform timer\n",
-                v->domain->domain_id, gsi);
-        domain_crash(v->domain);
-        return -1;
+    case PTSRC_isa:
+    {
+        uint8_t pic_imr = v->domain->arch.hvm_domain.vpic[pt->irq >> 3].imr;
+
+        /* Check if the interrupt is unmasked in the PIC. */
+        if ( !(pic_imr & (1 << (pt->irq & 7))) && vlapic_accept_pic_intr(v) )
+            return 0;
+
+        gsi = hvm_isa_irq_to_gsi(pt->irq);
+    }
+
+    /* Fallthrough to check if the interrupt is masked on the IO APIC. */
+    case PTSRC_ioapic:
+    {
+        int mask = vioapic_get_mask(v->domain, gsi);
+
+        if ( mask < 0 )
+        {
+            dprintk(XENLOG_WARNING,
+                    "d%d: invalid GSI (%u) for platform timer\n",
+                    v->domain->domain_id, gsi);
+            domain_crash(v->domain);
+            return -1;
+        }
+
+        return mask;
+    }
     }
 
-    return (((pic_imr & (1 << (isa_irq & 7))) || !vlapic_accept_pic_intr(v)) &&
-            mask);
+    ASSERT_UNREACHABLE();
+    return 1;
 }
 
 static void pt_lock(struct periodic_time *pt)
@@ -252,7 +270,7 @@ int pt_update_irq(struct vcpu *v)
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
     struct periodic_time *pt, *temp, *earliest_pt;
     uint64_t max_lag;
-    int irq, is_lapic, pt_vector;
+    int irq, pt_vector = -1;
 
     spin_lock(&v->arch.hvm_vcpu.tm_lock);
 
@@ -288,29 +306,26 @@ int pt_update_irq(struct vcpu *v)
 
     earliest_pt->irq_issued = 1;
     irq = earliest_pt->irq;
-    is_lapic = (earliest_pt->source == PTSRC_lapic);
 
     spin_unlock(&v->arch.hvm_vcpu.tm_lock);
 
-    /*
-     * If periodic timer interrut is handled by lapic, its vector in
-     * IRR is returned and used to set eoi_exit_bitmap for virtual
-     * interrupt delivery case. Otherwise return -1 to do nothing.
-     */
-    if ( is_lapic )
+    switch ( earliest_pt->source )
     {
+    case PTSRC_lapic:
+        /*
+         * If periodic timer interrupt is handled by lapic, its vector in
+         * IRR is returned and used to set eoi_exit_bitmap for virtual
+         * interrupt delivery case. Otherwise return -1 to do nothing.
+         */
         vlapic_set_irq(vcpu_vlapic(v), irq, 0);
         pt_vector = irq;
-    }
-    else
-    {
+        break;
+
+    case PTSRC_isa:
         hvm_isa_irq_deassert(v->domain, irq);
         if ( platform_legacy_irq(irq) && vlapic_accept_pic_intr(v) &&
              v->domain->arch.hvm_domain.vpic[irq >> 3].int_output )
-        {
             hvm_isa_irq_assert(v->domain, irq, NULL);
-            pt_vector = -1;
-        }
         else
         {
             pt_vector = hvm_isa_irq_assert(v->domain, irq, vioapic_get_vector);
@@ -321,6 +336,17 @@ int pt_update_irq(struct vcpu *v)
             if ( pt_vector < 0 || !vlapic_test_irq(vcpu_vlapic(v), pt_vector) )
                 pt_vector = -1;
         }
+        break;
+
+    case PTSRC_ioapic:
+        /*
+         * NB: At the moment IO-APIC routed interrupts generated by vpt devices
+         * (HPET) are edge-triggered.
+         */
+        pt_vector = hvm_ioapic_assert(v->domain, irq, false);
+        if ( pt_vector < 0 || !vlapic_test_irq(vcpu_vlapic(v), pt_vector) )
+            pt_vector = -1;
+        break;
     }
 
     return pt_vector;
@@ -418,7 +444,14 @@ void create_periodic_time(
     struct vcpu *v, struct periodic_time *pt, uint64_t delta,
     uint64_t period, uint8_t irq, time_cb *cb, void *data)
 {
-    ASSERT(pt->source != 0);
+    if ( !pt->source ||
+         (pt->irq >= NR_ISAIRQS && pt->source == PTSRC_isa) ||
+         (pt->irq >= hvm_domain_irq(v->domain)->nr_gsis &&
+          pt->source == PTSRC_ioapic) )
+    {
+        ASSERT_UNREACHABLE();
+        return;
+    }
 
     destroy_periodic_time(pt);
 
@@ -498,7 +531,7 @@ static void pt_adjust_vcpu(struct period
 {
     int on_list;
 
-    ASSERT(pt->source == PTSRC_isa);
+    ASSERT(pt->source == PTSRC_isa || pt->source == PTSRC_ioapic);
 
     if ( pt->vcpu == NULL )
         return;
--- a/xen/include/asm-x86/hvm/irq.h
+++ b/xen/include/asm-x86/hvm/irq.h
@@ -207,6 +207,9 @@ int hvm_set_pci_link_route(struct domain
 
 int hvm_inject_msi(struct domain *d, uint64_t addr, uint32_t data);
 
+/* Assert an IO APIC pin. */
+int hvm_ioapic_assert(struct domain *d, unsigned int gsi, bool level);
+
 void hvm_maybe_deassert_evtchn_irq(void);
 void hvm_assert_evtchn_irq(struct vcpu *v);
 void hvm_set_callback_via(struct domain *d, uint64_t via);
--- a/xen/include/asm-x86/hvm/vpt.h
+++ b/xen/include/asm-x86/hvm/vpt.h
@@ -44,6 +44,7 @@ struct periodic_time {
     bool_t warned_timeout_too_short;
 #define PTSRC_isa    1 /* ISA time source */
 #define PTSRC_lapic  2 /* LAPIC time source */
+#define PTSRC_ioapic 3 /* IOAPIC time source */
     u8 source;                  /* PTSRC_ */
     u8 irq;
     struct vcpu *vcpu;          /* vcpu timer interrupt delivers to */
++++++ xsa262.patch ++++++
From: Jan Beulich <jbeul...@suse.com>
Subject: x86/HVM: guard against emulator driving ioreq state in weird ways

In the case where hvm_wait_for_io() calls wait_on_xen_event_channel(),
p->state ends up being read twice in succession: once to determine that
state != p->state, and then again at the top of the loop.  This gives a
compromised emulator a chance to change the state back between the two
reads, potentially keeping Xen in a loop indefinitely.

Instead:
* Read p->state once in each of the wait_on_xen_event_channel() tests,
* re-use that value the next time around,
* and insist that the states continue to transition "forward" (with the
  exception of the transition to STATE_IOREQ_NONE).

This is XSA-262.

Signed-off-by: Jan Beulich <jbeul...@suse.com>
Reviewed-by: George Dunlap <george.dun...@citrix.com>

--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -87,14 +87,17 @@ static void hvm_io_assist(struct hvm_ior
 
 static bool hvm_wait_for_io(struct hvm_ioreq_vcpu *sv, ioreq_t *p)
 {
+    unsigned int prev_state = STATE_IOREQ_NONE;
+
     while ( sv->pending )
     {
         unsigned int state = p->state;
 
-        rmb();
-        switch ( state )
+        smp_rmb();
+
+    recheck:
+        if ( unlikely(state == STATE_IOREQ_NONE) )
         {
-        case STATE_IOREQ_NONE:
             /*
              * The only reason we should see this case is when an
              * emulator is dying and it races with an I/O being
@@ -102,14 +105,30 @@ static bool hvm_wait_for_io(struct hvm_i
              */
             hvm_io_assist(sv, ~0ul);
             break;
+        }
+
+        if ( unlikely(state < prev_state) )
+        {
+            gdprintk(XENLOG_ERR, "Weird HVM ioreq state transition %u -> %u\n",
+                     prev_state, state);
+            sv->pending = false;
+            domain_crash(sv->vcpu->domain);
+            return false; /* bail */
+        }
+
+        switch ( prev_state = state )
+        {
         case STATE_IORESP_READY: /* IORESP_READY -> NONE */
             p->state = STATE_IOREQ_NONE;
             hvm_io_assist(sv, p->data);
             break;
         case STATE_IOREQ_READY:  /* IOREQ_{READY,INPROCESS} -> IORESP_READY */
         case STATE_IOREQ_INPROCESS:
-            wait_on_xen_event_channel(sv->ioreq_evtchn, p->state != state);
-            break;
+            wait_on_xen_event_channel(sv->ioreq_evtchn,
+                                      ({ state = p->state;
+                                         smp_rmb();
+                                         state != prev_state; }));
+            goto recheck;
         default:
             gdprintk(XENLOG_ERR, "Weird HVM iorequest state %u\n", state);
             sv->pending = false;

Reply via email to