aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2016-11-25 16:54:20 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2016-11-25 17:00:23 +0000
commit64afb5ab10d6bdced5921588f38124df06eb3783 (patch)
tree05fb0feaf82dab5ebf38b9cc6c173ea2891f55f4
parent9a2f0cb09a04c388d44a68a62311b3e04c0550c8 (diff)
downloadaports-64afb5ab10d6bdced5921588f38124df06eb3783.tar.gz
aports-64afb5ab10d6bdced5921588f38124df06eb3783.tar.bz2
aports-64afb5ab10d6bdced5921588f38124df06eb3783.tar.xz
main/xen: fix various security issues
- XSA-198 CVE-2016-9379 CVE-2016-9380 delimiter injection vulnerabilities in pygrub - XSA-197 CVE-2016-9381 qemu incautious about shared ring processing - XSA-196 CVE-2016-9377 CVE-2016-9378 x86 software interrupt injection mis-handled - XSA-195 CVE-2016-9383 x86 64-bit bit test instruction emulation broken - XSA-194 CVE-2016-9384 guest 32-bit ELF symbol table load leaking host data - XSA-193 CVE-2016-9385 x86 segment base write emulation lacking canonical address checks - XSA-192 CVE-2016-9382 x86 task switch to VM86 mode mis-handled - XSA-191 CVE-2016-9386 x86 null segments not always treated as unusable fixes #6495
-rw-r--r--main/xen/APKBUILD54
-rw-r--r--main/xen/xsa191.patch152
-rw-r--r--main/xen/xsa192.patch64
-rw-r--r--main/xen/xsa193-4.7.patch68
-rw-r--r--main/xen/xsa194.patch144
-rw-r--r--main/xen/xsa195.patch45
-rw-r--r--main/xen/xsa196-0001-x86-emul-Correct-the-IDT-entry-calculation-in-inject.patch61
-rw-r--r--main/xen/xsa196-0002-x86-svm-Fix-injection-of-software-interrupts.patch76
-rw-r--r--main/xen/xsa197-qemut.patch65
-rw-r--r--main/xen/xsa197-qemuu.patch63
-rw-r--r--main/xen/xsa198.patch62
11 files changed, 853 insertions, 1 deletions
diff --git a/main/xen/APKBUILD b/main/xen/APKBUILD
index d06b4243a0..f067ac030d 100644
--- a/main/xen/APKBUILD
+++ b/main/xen/APKBUILD
@@ -3,7 +3,7 @@
# Maintainer: William Pitcock <nenolod@dereferenced.org>
pkgname=xen
pkgver=4.7.1
-pkgrel=0
+pkgrel=1
pkgdesc="Xen hypervisor"
url="http://www.xen.org/"
arch="x86_64 armhf"
@@ -26,6 +26,17 @@ makedepends="$depends_dev autoconf automake libtool "
# - CVE-2016-7094 XSA-187
# 4.7.0-r5:
# - CVE-2016-7777 XSA-190
+# 4.7.1-r1:
+# - CVE-2016-9386 XSA-191
+# - CVE-2016-9382 XSA-192
+# - CVE-2016-9385 XSA-193
+# - CVE-2016-9384 XSA-194
+# - CVE-2016-9383 XSA-195
+# - CVE-2016-9377 XSA-196
+# - CVE-2016-9378 XSA-196
+# - CVE-2016-9381 XSA-197
+# - CVE-2016-9379 XSA-198
+# - CVE-2016-9380 XSA-198
case "$CARCH" in
x86*)
@@ -69,6 +80,17 @@ source="http://bits.xensource.com/oss-xen/release/$pkgver/$pkgname-$pkgver.tar.g
http://xenbits.xen.org/xen-extfiles/zlib-$_ZLIB_VERSION.tar.gz
http://xenbits.xen.org/xen-extfiles/ipxe-git-$_IPXE_GIT_TAG.tar.gz
+ xsa191.patch
+ xsa192.patch
+ xsa193-4.7.patch
+ xsa194.patch
+ xsa195.patch
+ xsa196-0001-x86-emul-Correct-the-IDT-entry-calculation-in-inject.patch
+ xsa196-0002-x86-svm-Fix-injection-of-software-interrupts.patch
+ xsa197-qemut.patch
+ xsa197-qemuu.patch
+ xsa198.patch
+
qemu-coroutine-gthread.patch
qemu-xen_paths.patch
@@ -299,6 +321,16 @@ cec05e7785497c5e19da2f114b934ffd pciutils-2.2.9.tar.bz2
e26becb8a6a2b6695f6b3e8097593db8 tpm_emulator-0.7.4.tar.gz
debc62758716a169df9f62e6ab2bc634 zlib-1.2.3.tar.gz
7496268cebf47d5c9ccb0696e3b26065 ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz
+b3ccddb149c8f9af4eb5dcbc230fc391 xsa191.patch
+002cef87f605db2cd9a6ec5230685554 xsa192.patch
+0bde9ad287f8a586fb47abc2f393287e xsa193-4.7.patch
+2a37b54c1cfdf422a680652d05683b3f xsa194.patch
+03ee88fdd719a6e2cdd53b698b14bfa0 xsa195.patch
+362e7460fa4e5db3a5e1c2a4209718cf xsa196-0001-x86-emul-Correct-the-IDT-entry-calculation-in-inject.patch
+3f66b6bb7129867f857fe25916c32d84 xsa196-0002-x86-svm-Fix-injection-of-software-interrupts.patch
+7587583e9746ee46c39d48e693c97a2e xsa197-qemut.patch
+6d42e09101a5c6f8da5ee7caea4e0cc5 xsa197-qemuu.patch
+e8d3ee1e904071920a6afbbf6a27aad2 xsa198.patch
de1a3db370b87cfb0bddb51796b50315 qemu-coroutine-gthread.patch
08bfdf8caff5d631f53660bf3fd4edaf qemu-xen_paths.patch
e449bb3359b490804ffc7b0ae08d62a0 hotplug-vif-vtrill.patch
@@ -344,6 +376,16 @@ f60ae61cfbd5da1d849d0beaa21f593c38dac9359f0b3ddc612f447408265b24 pciutils-2.2.9
4e48ea0d83dd9441cc1af04ab18cd6c961b9fa54d5cbf2c2feee038988dea459 tpm_emulator-0.7.4.tar.gz
1795c7d067a43174113fdf03447532f373e1c6c57c08d61d9e4e9be5e244b05e zlib-1.2.3.tar.gz
632ce8c193ccacc3012bd354bdb733a4be126f7c098e111930aa41dad537405c ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz
+dca534cf4d3711ea8797846a18238ca16cc9e7a24a887300db22c3ba3d95c199 xsa191.patch
+687b0216eefd5ecef8a3135cc6f542cb3d9ff35e8e9696a157703e84656c35e8 xsa192.patch
+f1b0092c585ebffe83d6ed7df94885ec5dfcb4227bdb33f421bad9febb8135a1 xsa193-4.7.patch
+4dad65417d9ff3c86e763d3c88cf8de79b58a9981d531f641ae0dd0dcedce911 xsa194.patch
+6ab5f13b81e3bbf6096020f4c3beeffaff67a075cab67e033ba27d199b41cec1 xsa195.patch
+c4122280f3786416231ae5f0660123446d29e9ac5cd3ffb92784ed36edeec8b7 xsa196-0001-x86-emul-Correct-the-IDT-entry-calculation-in-inject.patch
+25671c44c746d4d0e8f7e2b109926c013b440e0bf225156282052ec38536e347 xsa196-0002-x86-svm-Fix-injection-of-software-interrupts.patch
+effa90c9ea5e76afeee8d89359b45201826b992d616c2dc118507b4e5926c57b xsa197-qemut.patch
+ecb1fac79d7d17db993800b0b9aeb24d8cec90d4877d80ed1b1d548401acf36c xsa197-qemuu.patch
+0e4533ad2157c03ab309bd12a54f5ff325f03edbe97f23c60a16a3f378c75eae xsa198.patch
3941f99b49c7e8dafc9fae8aad2136a14c6d84533cd542cc5f1040a41ef7c6fe qemu-coroutine-gthread.patch
e4e5e838e259a3116978aabbcebc1865a895179a7fcbf4bad195c83e9b4c0f98 qemu-xen_paths.patch
dd1e784bc455eb62cb85b3fa24bfc34f575ceaab9597ef6a2f1ee7ff7b3cae0a hotplug-vif-vtrill.patch
@@ -389,6 +431,16 @@ c2bc9ffc8583aeae71cee9ddcc4418969768d4e3764d47307da54f93981c0109fb07d84b061b3a36
4928b5b82f57645be9408362706ff2c4d9baa635b21b0d41b1c82930e8c60a759b1ea4fa74d7e6c7cae1b7692d006aa5cb72df0c3b88bf049779aa2b566f9d35 tpm_emulator-0.7.4.tar.gz
021b958fcd0d346c4ba761bcf0cc40f3522de6186cf5a0a6ea34a70504ce9622b1c2626fce40675bc8282cf5f5ade18473656abc38050f72f5d6480507a2106e zlib-1.2.3.tar.gz
c5cb1cdff40d2d71fd3e692a9d0efadf2aa17290daf5195391a1c81ddd9dfc913a8e44d5be2b12be85b2a5565ea31631c99c7053564f2fb2225c80ea0bb0e4a4 ipxe-git-9a93db3f0947484e30e753bbd61a10b17336e20e.tar.gz
+7484f63adc5f74d1c9cf335a6698cbfa782198aea2008ccea91a7dd9de13ca5e046497dd116bd56605fab6c59feba91b206ca5dc12d6e13f3229640aae2f7173 xsa191.patch
+13670f640f36d216b276dc4fcf73745cb81e54381afbee7452d8e058166a468dc4467dbdeb3e22154f66d5ef70b796f0a0f0f0080dcb4c3587d7f15fe7b9abc6 xsa192.patch
+6a20d6b192849af32e7db59f61d7686cbd4e0542741f3b6ddef2133f102212ba3ebc93901e5d74cdd54747e188a4eb8060b8843c10878e3bc9c567af678a6bd1 xsa193-4.7.patch
+a5119a779e23d39524639bded6fe1d1e8dce8ef3c36798a43477f27f9631c6d2e1324708f574deb697131641d2cf86de2f4754887325f67c2961e6c7dbaae0bc xsa194.patch
+2b32a360c13590f24de8ebb1cd18eb17eada444034a394739c21306be708ba5924ea1448e0d120c0f61f9472bce45e80439e3fd5779f4be72d367ce5c55b6ec0 xsa195.patch
+d76d457343a1a2cd08d6a3fcaf063569638862d5491c5eb3100bc3902d3f4845c5a9a6ceed16e2be405ecfc924d786e7a0e2407c002c59da344a10e8e183e758 xsa196-0001-x86-emul-Correct-the-IDT-entry-calculation-in-inject.patch
+3f47f78f83f01af57c51eee5c6a51466c59d23ddcbbf0c107539166840faed756af113b139c73aea74534ebceb304c0b6b69a394e47c3a9a5499342cce6d5cf8 xsa196-0002-x86-svm-Fix-injection-of-software-interrupts.patch
+e25e8f99c129c51da735103542da332b38d54502dd4dccc824383f8e086ce969afaac7da8ad4011bea5745e160e5c2020f4e58daccc9cc69542ff3fc7157761c xsa197-qemut.patch
+68b5a4f5b8dbe1a0c6a55f126839f02c13bf6ff393cee71c33a06deae61ce4cd4ebdf2cc3bf2594e71fad0e766221fdc23c2055550db63bd0662b930ab8c2acc xsa197-qemuu.patch
+b61429fbf4d1677a8dab2710ab21335f18b3f998f2e5e19e45a4727f71b9671b3d1bd709bef3594cbaa5a47f339c3b8a5cccf11dd361b993aa76d242b825549c xsa198.patch
c3c46f232f0bd9f767b232af7e8ce910a6166b126bd5427bb8dc325aeb2c634b956de3fc225cab5af72649070c8205cc8e1cab7689fc266c204f525086f1a562 qemu-coroutine-gthread.patch
1936ab39a1867957fa640eb81c4070214ca4856a2743ba7e49c0cd017917071a9680d015f002c57fa7b9600dbadd29dcea5887f50e6c133305df2669a7a933f3 qemu-xen_paths.patch
f095ea373f36381491ad36f0662fb4f53665031973721256b23166e596318581da7cbb0146d0beb2446729adfdb321e01468e377793f6563a67d68b8b0f7ffe3 hotplug-vif-vtrill.patch
diff --git a/main/xen/xsa191.patch b/main/xen/xsa191.patch
new file mode 100644
index 0000000000..956f1c97ad
--- /dev/null
+++ b/main/xen/xsa191.patch
@@ -0,0 +1,152 @@
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+Subject: x86/hvm: Fix the handling of non-present segments
+
+In 32bit, the data segments may be NULL to indicate that the segment is
+ineligible for use. In both 32bit and 64bit, the LDT selector may be NULL to
+indicate that the entire LDT is ineligible for use. However, nothing in Xen
+actually checks for this condition when performing other segmentation
+checks. (Note however that limit and writeability checks are correctly
+performed).
+
+Neither Intel nor AMD specify the exact behaviour of loading a NULL segment.
+Experimentally, AMD zeroes all attributes but leaves the base and limit
+unmodified. Intel zeroes the base, sets the limit to 0xfffffff and resets the
+attributes to just .G and .D/B.
+
+The use of the segment information in the VMCB/VMCS is equivalent to a native
+pipeline interacting with the segment cache. The present bit can therefore
+have a subtly different meaning, and it is now cooked to uniformly indicate
+whether the segment is usable or not.
+
+GDTR and IDTR don't have access rights like the other segments, but for
+consistency, they are treated as being present so no special casing is needed
+elsewhere in the segmentation logic.
+
+AMD hardware does not consider the present bit for %cs and %tr, and will
+function as if they were present. They are therefore unconditionally set to
+present when reading information from the VMCB, to maintain the new meaning of
+usability.
+
+Intel hardware has a separate unusable bit in the VMCS segment attributes.
+This bit is inverted and stored in the present field, so the hvm code can work
+with architecturally-common state.
+
+This is XSA-191.
+
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+---
+ xen/arch/x86/hvm/hvm.c | 8 ++++++++
+ xen/arch/x86/hvm/svm/svm.c | 4 ++++
+ xen/arch/x86/hvm/vmx/vmx.c | 20 +++++++++++---------
+ xen/arch/x86/x86_emulate/x86_emulate.c | 4 ++++
+ 4 files changed, 27 insertions(+), 9 deletions(-)
+
+diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
+index 704fd64..deb1783 100644
+--- a/xen/arch/x86/hvm/hvm.c
++++ b/xen/arch/x86/hvm/hvm.c
+@@ -2512,6 +2512,10 @@ bool_t hvm_virtual_to_linear_addr(
+ */
+ addr = (uint32_t)(addr + reg->base);
+
++ /* Segment not valid for use (cooked meaning of .p)? */
++ if ( !reg->attr.fields.p )
++ goto out;
++
+ switch ( access_type )
+ {
+ case hvm_access_read:
+@@ -2767,6 +2771,10 @@ static int hvm_load_segment_selector(
+ hvm_get_segment_register(
+ v, (sel & 4) ? x86_seg_ldtr : x86_seg_gdtr, &desctab);
+
++ /* Segment not valid for use (cooked meaning of .p)? */
++ if ( !desctab.attr.fields.p )
++ goto fail;
++
+ /* Check against descriptor table limit. */
+ if ( ((sel & 0xfff8) + 7) > desctab.limit )
+ goto fail;
+diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
+index 16427f6..4cba406 100644
+--- a/xen/arch/x86/hvm/svm/svm.c
++++ b/xen/arch/x86/hvm/svm/svm.c
+@@ -627,6 +627,7 @@ static void svm_get_segment_register(struct vcpu *v, enum x86_segment seg,
+ {
+ case x86_seg_cs:
+ memcpy(reg, &vmcb->cs, sizeof(*reg));
++ reg->attr.fields.p = 1;
+ reg->attr.fields.g = reg->limit > 0xFFFFF;
+ break;
+ case x86_seg_ds:
+@@ -660,13 +661,16 @@ static void svm_get_segment_register(struct vcpu *v, enum x86_segment seg,
+ case x86_seg_tr:
+ svm_sync_vmcb(v);
+ memcpy(reg, &vmcb->tr, sizeof(*reg));
++ reg->attr.fields.p = 1;
+ reg->attr.fields.type |= 0x2;
+ break;
+ case x86_seg_gdtr:
+ memcpy(reg, &vmcb->gdtr, sizeof(*reg));
++ reg->attr.bytes = 0x80;
+ break;
+ case x86_seg_idtr:
+ memcpy(reg, &vmcb->idtr, sizeof(*reg));
++ reg->attr.bytes = 0x80;
+ break;
+ case x86_seg_ldtr:
+ svm_sync_vmcb(v);
+diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
+index 9a8f694..a652c52 100644
+--- a/xen/arch/x86/hvm/vmx/vmx.c
++++ b/xen/arch/x86/hvm/vmx/vmx.c
+@@ -1035,10 +1035,12 @@ void vmx_get_segment_register(struct vcpu *v, enum x86_segment seg,
+ reg->sel = sel;
+ reg->limit = limit;
+
+- reg->attr.bytes = (attr & 0xff) | ((attr >> 4) & 0xf00);
+- /* Unusable flag is folded into Present flag. */
+- if ( attr & (1u<<16) )
+- reg->attr.fields.p = 0;
++ /*
++ * Fold VT-x representation into Xen's representation. The Present bit is
++ * unconditionally set to the inverse of unusable.
++ */
++ reg->attr.bytes =
++ (!(attr & (1u << 16)) << 7) | (attr & 0x7f) | ((attr >> 4) & 0xf00);
+
+ /* Adjust for virtual 8086 mode */
+ if ( v->arch.hvm_vmx.vmx_realmode && seg <= x86_seg_tr
+@@ -1118,11 +1120,11 @@ static void vmx_set_segment_register(struct vcpu *v, enum x86_segment seg,
+ }
+ }
+
+- attr = ((attr & 0xf00) << 4) | (attr & 0xff);
+-
+- /* Not-present must mean unusable. */
+- if ( !reg->attr.fields.p )
+- attr |= (1u << 16);
++ /*
++ * Unfold Xen representation into VT-x representation. The unusable bit
++ * is unconditionally set to the inverse of present.
++ */
++ attr = (!(attr & (1u << 7)) << 16) | ((attr & 0xf00) << 4) | (attr & 0xff);
+
+ /* VMX has strict consistency requirement for flag G. */
+ attr |= !!(limit >> 20) << 15;
+diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
+index 7a707dc..7cb6f98 100644
+--- a/xen/arch/x86/x86_emulate/x86_emulate.c
++++ b/xen/arch/x86/x86_emulate/x86_emulate.c
+@@ -1367,6 +1367,10 @@ protmode_load_seg(
+ &desctab, ctxt)) )
+ return rc;
+
++ /* Segment not valid for use (cooked meaning of .p)? */
++ if ( !desctab.attr.fields.p )
++ goto raise_exn;
++
+ /* Check against descriptor table limit. */
+ if ( ((sel & 0xfff8) + 7) > desctab.limit )
+ goto raise_exn;
diff --git a/main/xen/xsa192.patch b/main/xen/xsa192.patch
new file mode 100644
index 0000000000..b573a132c9
--- /dev/null
+++ b/main/xen/xsa192.patch
@@ -0,0 +1,64 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: x86/HVM: don't load LDTR with VM86 mode attrs during task switch
+
+Just like TR, LDTR is purely a protected mode facility and hence needs
+to be loaded accordingly. Also move its loading to where it
+architecurally belongs.
+
+This is XSA-192.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+--- a/xen/arch/x86/hvm/hvm.c
++++ b/xen/arch/x86/hvm/hvm.c
+@@ -2728,17 +2728,16 @@ static void hvm_unmap_entry(void *p)
+ }
+
+ static int hvm_load_segment_selector(
+- enum x86_segment seg, uint16_t sel)
++ enum x86_segment seg, uint16_t sel, unsigned int eflags)
+ {
+ struct segment_register desctab, cs, segr;
+ struct desc_struct *pdesc, desc;
+ u8 dpl, rpl, cpl;
+ bool_t writable;
+ int fault_type = TRAP_invalid_tss;
+- struct cpu_user_regs *regs = guest_cpu_user_regs();
+ struct vcpu *v = current;
+
+- if ( regs->eflags & X86_EFLAGS_VM )
++ if ( eflags & X86_EFLAGS_VM )
+ {
+ segr.sel = sel;
+ segr.base = (uint32_t)sel << 4;
+@@ -2986,6 +2985,8 @@ void hvm_task_switch(
+ if ( rc != HVMCOPY_okay )
+ goto out;
+
++ if ( hvm_load_segment_selector(x86_seg_ldtr, tss.ldt, 0) )
++ goto out;
+
+ if ( hvm_set_cr3(tss.cr3, 1) )
+ goto out;
+@@ -3008,13 +3009,12 @@ void hvm_task_switch(
+ }
+
+ exn_raised = 0;
+- if ( hvm_load_segment_selector(x86_seg_ldtr, tss.ldt) ||
+- hvm_load_segment_selector(x86_seg_es, tss.es) ||
+- hvm_load_segment_selector(x86_seg_cs, tss.cs) ||
+- hvm_load_segment_selector(x86_seg_ss, tss.ss) ||
+- hvm_load_segment_selector(x86_seg_ds, tss.ds) ||
+- hvm_load_segment_selector(x86_seg_fs, tss.fs) ||
+- hvm_load_segment_selector(x86_seg_gs, tss.gs) )
++ if ( hvm_load_segment_selector(x86_seg_es, tss.es, tss.eflags) ||
++ hvm_load_segment_selector(x86_seg_cs, tss.cs, tss.eflags) ||
++ hvm_load_segment_selector(x86_seg_ss, tss.ss, tss.eflags) ||
++ hvm_load_segment_selector(x86_seg_ds, tss.ds, tss.eflags) ||
++ hvm_load_segment_selector(x86_seg_fs, tss.fs, tss.eflags) ||
++ hvm_load_segment_selector(x86_seg_gs, tss.gs, tss.eflags) )
+ exn_raised = 1;
+
+ rc = hvm_copy_to_guest_virt(
diff --git a/main/xen/xsa193-4.7.patch b/main/xen/xsa193-4.7.patch
new file mode 100644
index 0000000000..c5486efa54
--- /dev/null
+++ b/main/xen/xsa193-4.7.patch
@@ -0,0 +1,68 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: x86/PV: writes of %fs and %gs base MSRs require canonical addresses
+
+Commit c42494acb2 ("x86: fix FS/GS base handling when using the
+fsgsbase feature") replaced the use of wrmsr_safe() on these paths
+without recognizing that wr{f,g}sbase() use just wrmsrl() and that the
+WR{F,G}SBASE instructions also raise #GP for non-canonical input.
+
+Similarly arch_set_info_guest() needs to prevent non-canonical
+addresses from getting stored into state later to be loaded by context
+switch code. For consistency also check stack pointers and LDT base.
+DR0..3, otoh, already get properly checked in set_debugreg() (albeit
+we discard the error there).
+
+The SHADOW_GS_BASE check isn't strictly necessary, but I think we
+better avoid trying the WRMSR if we know it's going to fail.
+
+This is XSA-193.
+
+Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+--- a/xen/arch/x86/domain.c
++++ b/xen/arch/x86/domain.c
+@@ -890,7 +890,13 @@ int arch_set_info_guest(
+ {
+ if ( !compat )
+ {
+- if ( !is_canonical_address(c.nat->user_regs.eip) ||
++ if ( !is_canonical_address(c.nat->user_regs.rip) ||
++ !is_canonical_address(c.nat->user_regs.rsp) ||
++ !is_canonical_address(c.nat->kernel_sp) ||
++ (c.nat->ldt_ents && !is_canonical_address(c.nat->ldt_base)) ||
++ !is_canonical_address(c.nat->fs_base) ||
++ !is_canonical_address(c.nat->gs_base_kernel) ||
++ !is_canonical_address(c.nat->gs_base_user) ||
+ !is_canonical_address(c.nat->event_callback_eip) ||
+ !is_canonical_address(c.nat->syscall_callback_eip) ||
+ !is_canonical_address(c.nat->failsafe_callback_eip) )
+--- a/xen/arch/x86/traps.c
++++ b/xen/arch/x86/traps.c
+@@ -2723,19 +2723,22 @@ static int emulate_privileged_op(struct
+ switch ( regs->_ecx )
+ {
+ case MSR_FS_BASE:
+- if ( is_pv_32bit_domain(currd) )
++ if ( is_pv_32bit_domain(currd) ||
++ !is_canonical_address(msr_content) )
+ goto fail;
+ wrfsbase(msr_content);
+ v->arch.pv_vcpu.fs_base = msr_content;
+ break;
+ case MSR_GS_BASE:
+- if ( is_pv_32bit_domain(currd) )
++ if ( is_pv_32bit_domain(currd) ||
++ !is_canonical_address(msr_content) )
+ goto fail;
+ wrgsbase(msr_content);
+ v->arch.pv_vcpu.gs_base_kernel = msr_content;
+ break;
+ case MSR_SHADOW_GS_BASE:
+- if ( is_pv_32bit_domain(currd) )
++ if ( is_pv_32bit_domain(currd) ||
++ !is_canonical_address(msr_content) )
+ goto fail;
+ if ( wrmsr_safe(MSR_SHADOW_GS_BASE, msr_content) )
+ goto fail;
diff --git a/main/xen/xsa194.patch b/main/xen/xsa194.patch
new file mode 100644
index 0000000000..946bd8783d
--- /dev/null
+++ b/main/xen/xsa194.patch
@@ -0,0 +1,144 @@
+From 71096b016f7fd54a72af73576948cb25cf42ebcb Mon Sep 17 00:00:00 2001
+From: Roger Pau Monné <roger.pau@citrix.com>Date: Wed, 2 Nov 2016 15:02:00 +0000
+Subject: [PATCH] libelf: fix stack memory leak when loading 32 bit symbol
+ tables
+
+The 32 bit Elf structs are smaller than the 64 bit ones, which means that
+when loading them there's some padding left uninitialized at the end of each
+struct (because the size indicated in e_ehsize and e_shentsize is
+smaller than the size of elf_ehdr and elf_shdr).
+
+Fix this by introducing a new helper that is used to set
+[caller_]xdest_{base/size} and that takes care of performing the appropriate
+memset of the region. This newly introduced helper is then used to set and
+unset xdest_{base/size} in elf_load_bsdsyms. Now that the full struct
+is zeroed, there's no need to specifically zero the undefined section.
+
+This is XSA-194.
+
+Suggested-by: Ian Jackson <ian.jackson@eu.citrix.com>
+
+Also remove the open coded (and redundant with the earlier
+elf_memset_unchecked()) use of caller_xdest_* from elf_init().
+
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
+---
+ xen/common/libelf/libelf-loader.c | 14 +++-----------
+ xen/common/libelf/libelf-tools.c | 11 +++++++++--
+ xen/include/xen/libelf.h | 15 +++++++++------
+ 3 files changed, 21 insertions(+), 19 deletions(-)
+
+diff --git a/xen/common/libelf/libelf-loader.c b/xen/common/libelf/libelf-loader.c
+index 4d3ae4d..bc1f87b 100644
+--- a/xen/common/libelf/libelf-loader.c
++++ b/xen/common/libelf/libelf-loader.c
+@@ -43,8 +43,6 @@ elf_errorstatus elf_init(struct elf_binary *elf, const char *image_input, size_t
+ elf->ehdr = ELF_MAKE_HANDLE(elf_ehdr, (elf_ptrval)image_input);
+ elf->class = elf_uval_3264(elf, elf->ehdr, e32.e_ident[EI_CLASS]);
+ elf->data = elf_uval_3264(elf, elf->ehdr, e32.e_ident[EI_DATA]);
+- elf->caller_xdest_base = NULL;
+- elf->caller_xdest_size = 0;
+
+ /* Sanity check phdr. */
+ offset = elf_uval(elf, elf->ehdr, e_phoff) +
+@@ -284,9 +282,8 @@ do { \
+ #define SYMTAB_INDEX 1
+ #define STRTAB_INDEX 2
+
+- /* Allow elf_memcpy_safe to write to symbol_header. */
+- elf->caller_xdest_base = &header;
+- elf->caller_xdest_size = sizeof(header);
++ /* Allow elf_memcpy_safe to write to header. */
++ elf_set_xdest(elf, &header, sizeof(header));
+
+ /*
+ * Calculate the position of the various elements in GUEST MEMORY SPACE.
+@@ -319,11 +316,7 @@ do { \
+ elf_store_field_bitness(elf, header_handle, e_phentsize, 0);
+ elf_store_field_bitness(elf, header_handle, e_phnum, 0);
+
+- /* Zero the undefined section. */
+- section_handle = ELF_MAKE_HANDLE(elf_shdr,
+- ELF_REALPTR2PTRVAL(&header.elf_header.section[SHN_UNDEF]));
+ shdr_size = elf_uval(elf, elf->ehdr, e_shentsize);
+- elf_memset_safe(elf, ELF_HANDLE_PTRVAL(section_handle), 0, shdr_size);
+
+ /*
+ * The symtab section header is going to reside in section[SYMTAB_INDEX],
+@@ -404,8 +397,7 @@ do { \
+ }
+
+ /* Remove permissions from elf_memcpy_safe. */
+- elf->caller_xdest_base = NULL;
+- elf->caller_xdest_size = 0;
++ elf_set_xdest(elf, NULL, 0);
+
+ #undef SYMTAB_INDEX
+ #undef STRTAB_INDEX
+diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
+index 5a4757b..e73e729 100644
+--- a/xen/common/libelf/libelf-tools.c
++++ b/xen/common/libelf/libelf-tools.c
+@@ -59,8 +59,7 @@ bool elf_access_ok(struct elf_binary * elf,
+ return 1;
+ if ( elf_ptrval_in_range(ptrval, size, elf->dest_base, elf->dest_size) )
+ return 1;
+- if ( elf_ptrval_in_range(ptrval, size,
+- elf->caller_xdest_base, elf->caller_xdest_size) )
++ if ( elf_ptrval_in_range(ptrval, size, elf->xdest_base, elf->xdest_size) )
+ return 1;
+ elf_mark_broken(elf, "out of range access");
+ return 0;
+@@ -373,6 +372,14 @@ bool elf_phdr_is_loadable(struct elf_binary *elf, ELF_HANDLE_DECL(elf_phdr) phdr
+ return ((p_type == PT_LOAD) && (p_flags & (PF_R | PF_W | PF_X)) != 0);
+ }
+
++void elf_set_xdest(struct elf_binary *elf, void *addr, uint64_t size)
++{
++ elf->xdest_base = addr;
++ elf->xdest_size = size;
++ if ( addr != NULL )
++ elf_memset_safe(elf, ELF_REALPTR2PTRVAL(addr), 0, size);
++}
++
+ /*
+ * Local variables:
+ * mode: C
+diff --git a/xen/include/xen/libelf.h b/xen/include/xen/libelf.h
+index 95b5370..cf62bc7 100644
+--- a/xen/include/xen/libelf.h
++++ b/xen/include/xen/libelf.h
+@@ -210,13 +210,11 @@ struct elf_binary {
+ uint64_t bsd_symtab_pend;
+
+ /*
+- * caller's other acceptable destination
+- *
+- * Again, these are trusted and must be valid (or 0) so long
+- * as the struct elf_binary is in use.
++ * caller's other acceptable destination.
++ * Set by elf_set_xdest. Do not set these directly.
+ */
+- void *caller_xdest_base;
+- uint64_t caller_xdest_size;
++ void *xdest_base;
++ uint64_t xdest_size;
+
+ #ifndef __XEN__
+ /* misc */
+@@ -494,5 +492,10 @@ static inline void ELF_ADVANCE_DEST(struct elf_binary *elf, uint64_t amount)
+ }
+ }
+
++/* Specify a (single) additional destination, to which the image may
++ * cause writes. As with dest_base and dest_size, the values provided
++ * are trusted and must be valid so long as the struct elf_binary
++ * is in use or until elf_set_xdest(,0,0) is called. */
++void elf_set_xdest(struct elf_binary *elf, void *addr, uint64_t size);
+
+ #endif /* __XEN_LIBELF_H__ */
+--
+2.1.4
+
diff --git a/main/xen/xsa195.patch b/main/xen/xsa195.patch
new file mode 100644
index 0000000000..a193a5cca0
--- /dev/null
+++ b/main/xen/xsa195.patch
@@ -0,0 +1,45 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: x86emul: fix huge bit offset handling
+
+We must never chop off the high 32 bits.
+
+This is XSA-195.
+
+Reported-by: George Dunlap <george.dunlap@citrix.com>
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+--- a/xen/arch/x86/x86_emulate/x86_emulate.c
++++ b/xen/arch/x86/x86_emulate/x86_emulate.c
+@@ -2549,6 +2549,12 @@ x86_emulate(
+ else
+ {
+ /*
++ * Instructions such as bt can reference an arbitrary offset from
++ * their memory operand, but the instruction doing the actual
++ * emulation needs the appropriate op_bytes read from memory.
++ * Adjust both the source register and memory operand to make an
++ * equivalent instruction.
++ *
+ * EA += BitOffset DIV op_bytes*8
+ * BitOffset = BitOffset MOD op_bytes*8
+ * DIV truncates towards negative infinity.
+@@ -2560,14 +2566,15 @@ x86_emulate(
+ src.val = (int32_t)src.val;
+ if ( (long)src.val < 0 )
+ {
+- unsigned long byte_offset;
+- byte_offset = op_bytes + (((-src.val-1) >> 3) & ~(op_bytes-1));
++ unsigned long byte_offset =
++ op_bytes + (((-src.val - 1) >> 3) & ~(op_bytes - 1L));
++
+ ea.mem.off -= byte_offset;
+ src.val = (byte_offset << 3) + src.val;
+ }
+ else
+ {
+- ea.mem.off += (src.val >> 3) & ~(op_bytes - 1);
++ ea.mem.off += (src.val >> 3) & ~(op_bytes - 1L);
+ src.val &= (op_bytes << 3) - 1;
+ }
+ }
diff --git a/main/xen/xsa196-0001-x86-emul-Correct-the-IDT-entry-calculation-in-inject.patch b/main/xen/xsa196-0001-x86-emul-Correct-the-IDT-entry-calculation-in-inject.patch
new file mode 100644
index 0000000000..7193e9ad5a
--- /dev/null
+++ b/main/xen/xsa196-0001-x86-emul-Correct-the-IDT-entry-calculation-in-inject.patch
@@ -0,0 +1,61 @@
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+Subject: x86/emul: Correct the IDT entry calculation in inject_swint()
+
+The logic, as introduced in c/s 36ebf14ebe "x86/emulate: support for emulating
+software event injection" is buggy. The size of an IDT entry depends on long
+mode being active, not the width of the code segment currently in use.
+
+In particular, this means that a compatibility code segment which hits
+emulation for software event injection will end up using an incorrect offset
+in the IDT for DPL/Presence checking. In practice, this only occurs on old
+AMD hardware lacking NRip support; all newer AMD hardware, and all Intel
+hardware bypass this path in the emulator.
+
+While here, fix a minor issue with reading the IDT entry. The return value
+from ops->read() wasn't checked, but in reality the only failure case is if a
+pagefault occurs. This is not a realistic problem as the kernel will almost
+certainly crash with a double fault if this setup actually occured.
+
+This is part of XSA-196.
+
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+---
+ xen/arch/x86/x86_emulate/x86_emulate.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
+index 7a707dc..f74aa8f 100644
+--- a/xen/arch/x86/x86_emulate/x86_emulate.c
++++ b/xen/arch/x86/x86_emulate/x86_emulate.c
+@@ -1630,10 +1630,16 @@ static int inject_swint(enum x86_swint_type type,
+ {
+ if ( !in_realmode(ctxt, ops) )
+ {
+- unsigned int idte_size = (ctxt->addr_size == 64) ? 16 : 8;
+- unsigned int idte_offset = vector * idte_size;
++ unsigned int idte_size, idte_offset;
+ struct segment_register idtr;
+ uint32_t idte_ctl;
++ int lm = in_longmode(ctxt, ops);
++
++ if ( lm < 0 )
++ return X86EMUL_UNHANDLEABLE;
++
++ idte_size = lm ? 16 : 8;
++ idte_offset = vector * idte_size;
+
+ /* icebp sets the External Event bit despite being an instruction. */
+ error_code = (vector << 3) | ECODE_IDT |
+@@ -1661,8 +1667,9 @@ static int inject_swint(enum x86_swint_type type,
+ * Should strictly speaking read all 8/16 bytes of an entry,
+ * but we currently only care about the dpl and present bits.
+ */
+- ops->read(x86_seg_none, idtr.base + idte_offset + 4,
+- &idte_ctl, sizeof(idte_ctl), ctxt);
++ if ( (rc = ops->read(x86_seg_none, idtr.base + idte_offset + 4,
++ &idte_ctl, sizeof(idte_ctl), ctxt)) )
++ goto done;
+
+ /* Is this entry present? */
+ if ( !(idte_ctl & (1u << 15)) )
diff --git a/main/xen/xsa196-0002-x86-svm-Fix-injection-of-software-interrupts.patch b/main/xen/xsa196-0002-x86-svm-Fix-injection-of-software-interrupts.patch
new file mode 100644
index 0000000000..26580ff809
--- /dev/null
+++ b/main/xen/xsa196-0002-x86-svm-Fix-injection-of-software-interrupts.patch
@@ -0,0 +1,76 @@
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+Subject: x86/svm: Fix injection of software interrupts
+
+The non-NextRip logic in c/s 36ebf14eb "x86/emulate: support for emulating
+software event injection" was based on an older version of the AMD software
+manual. The manual was later corrected, following findings from that series.
+
+I took the original wording of "not supported without NextRIP" to mean that
+X86_EVENTTYPE_SW_INTERRUPT was not eligible for use. It turns out that this
+is not the case, and the new wording is clearer on the matter.
+
+Despite testing the original patch series on non-NRip hardware, the
+swint-emulation XTF test case focuses on the debug vectors; it never ended up
+executing an `int $n` instruction for a vector which wasn't also an exception.
+
+During a vmentry, the use of X86_EVENTTYPE_HW_EXCEPTION comes with a vector
+check to ensure that it is only used with exception vectors. Xen's use of
+X86_EVENTTYPE_HW_EXCEPTION for `int $n` injection has always been buggy on AMD
+hardware.
+
+Fix this by always using X86_EVENTTYPE_SW_INTERRUPT.
+
+Print and decode the eventinj information in svm_vmcb_dump(), as it has
+several invalid combinations which cause vmentry failures.
+
+This is part of XSA-196.
+
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+---
+ xen/arch/x86/hvm/svm/svm.c | 13 +++++--------
+ xen/arch/x86/hvm/svm/svmdebug.c | 4 ++++
+ 2 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
+index 4391744..76efc3e 100644
+--- a/xen/arch/x86/hvm/svm/svm.c
++++ b/xen/arch/x86/hvm/svm/svm.c
+@@ -1231,17 +1231,14 @@ static void svm_inject_trap(const struct hvm_trap *trap)
+ {
+ case X86_EVENTTYPE_SW_INTERRUPT: /* int $n */
+ /*
+- * Injection type 4 (software interrupt) is only supported with
+- * NextRIP support. Without NextRIP, the emulator will have performed
+- * DPL and presence checks for us.
++ * Software interrupts (type 4) cannot be properly injected if the
++ * processor doesn't support NextRIP. Without NextRIP, the emulator
++ * will have performed DPL and presence checks for us, and will have
++ * moved eip forward if appropriate.
+ */
+ if ( cpu_has_svm_nrips )
+- {
+ vmcb->nextrip = regs->eip + _trap.insn_len;
+- event.fields.type = X86_EVENTTYPE_SW_INTERRUPT;
+- }
+- else
+- event.fields.type = X86_EVENTTYPE_HW_EXCEPTION;
++ event.fields.type = X86_EVENTTYPE_SW_INTERRUPT;
+ break;
+
+ case X86_EVENTTYPE_PRI_SW_EXCEPTION: /* icebp */
+diff --git a/xen/arch/x86/hvm/svm/svmdebug.c b/xen/arch/x86/hvm/svm/svmdebug.c
+index ded5d19..f93dfed 100644
+--- a/xen/arch/x86/hvm/svm/svmdebug.c
++++ b/xen/arch/x86/hvm/svm/svmdebug.c
+@@ -48,6 +48,10 @@ void svm_vmcb_dump(const char *from, struct vmcb_struct *vmcb)
+ vmcb->tlb_control,
+ (unsigned long long)vmcb->_vintr.bytes,
+ (unsigned long long)vmcb->interrupt_shadow);
++ printk("eventinj %016"PRIx64", valid? %d, ec? %d, type %u, vector %#x\n",
++ vmcb->eventinj.bytes, vmcb->eventinj.fields.v,
++ vmcb->eventinj.fields.ev, vmcb->eventinj.fields.type,
++ vmcb->eventinj.fields.vector);
+ printk("exitcode = %#Lx exitintinfo = %#Lx\n",
+ (unsigned long long)vmcb->exitcode,
+ (unsigned long long)vmcb->exitintinfo.bytes);
diff --git a/main/xen/xsa197-qemut.patch b/main/xen/xsa197-qemut.patch
new file mode 100644
index 0000000000..878c347b91
--- /dev/null
+++ b/main/xen/xsa197-qemut.patch
@@ -0,0 +1,65 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: xen: fix ioreq handling
+
+Avoid double fetches and bounds check size to avoid overflowing
+internal variables.
+
+This is XSA-197.
+
+Reported-by: yanghongke <yanghongke@huawei.com>
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Ian Jackson <ian.jackson@eu.citrix.com>
+
+--- a/i386-dm/helper2.c
++++ b/tools/qemu-xen-traditional/i386-dm/helper2.c
+@@ -375,6 +375,11 @@ static void cpu_ioreq_pio(CPUState *env,
+ {
+ uint32_t i;
+
++ if (req->size > sizeof(unsigned long)) {
++ fprintf(stderr, "PIO: bad size (%u)\n", req->size);
++ exit(-1);
++ }
++
+ if (req->dir == IOREQ_READ) {
+ if (!req->data_is_ptr) {
+ req->data = do_inp(env, req->addr, req->size);
+@@ -404,6 +409,11 @@ static void cpu_ioreq_move(CPUState *env
+ {
+ uint32_t i;
+
++ if (req->size > sizeof(req->data)) {
++ fprintf(stderr, "MMIO: bad size (%u)\n", req->size);
++ exit(-1);
++ }
++
+ if (!req->data_is_ptr) {
+ if (req->dir == IOREQ_READ) {
+ for (i = 0; i < req->count; i++) {
+@@ -516,11 +526,13 @@ static int __handle_buffered_iopage(CPUS
+ req.df = 1;
+ req.type = buf_req->type;
+ req.data_is_ptr = 0;
++ xen_rmb();
+ qw = (req.size == 8);
+ if (qw) {
+ buf_req = &buffered_io_page->buf_ioreq[(rdptr + 1) %
+ IOREQ_BUFFER_SLOT_NUM];
+ req.data |= ((uint64_t)buf_req->data) << 32;
++ xen_rmb();
+ }
+
+ __handle_ioreq(env, &req);
+@@ -552,7 +564,11 @@ static void cpu_handle_ioreq(void *opaqu
+
+ __handle_buffered_iopage(env);
+ if (req) {
+- __handle_ioreq(env, req);
++ ioreq_t copy = *req;
++
++ xen_rmb();
++ __handle_ioreq(env, &copy);
++ req->data = copy.data;
+
+ if (req->state != STATE_IOREQ_INPROCESS) {
+ fprintf(logfile, "Badness in I/O request ... not in service?!: "
diff --git a/main/xen/xsa197-qemuu.patch b/main/xen/xsa197-qemuu.patch
new file mode 100644
index 0000000000..079e8093d1
--- /dev/null
+++ b/main/xen/xsa197-qemuu.patch
@@ -0,0 +1,63 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: xen: fix ioreq handling
+
+Avoid double fetches and bounds check size to avoid overflowing
+internal variables.
+
+This is XSA-197.
+
+Reported-by: yanghongke <yanghongke@huawei.com>
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+
+--- a/xen-hvm.c
++++ b/tools/qemu-xen/xen-hvm.c
+@@ -810,6 +810,10 @@ static void cpu_ioreq_pio(ioreq_t *req)
+ trace_cpu_ioreq_pio(req, req->dir, req->df, req->data_is_ptr, req->addr,
+ req->data, req->count, req->size);
+
++ if (req->size > sizeof(uint32_t)) {
++ hw_error("PIO: bad size (%u)", req->size);
++ }
++
+ if (req->dir == IOREQ_READ) {
+ if (!req->data_is_ptr) {
+ req->data = do_inp(req->addr, req->size);
+@@ -846,6 +850,10 @@ static void cpu_ioreq_move(ioreq_t *req)
+ trace_cpu_ioreq_move(req, req->dir, req->df, req->data_is_ptr, req->addr,
+ req->data, req->count, req->size);
+
++ if (req->size > sizeof(req->data)) {
++ hw_error("MMIO: bad size (%u)", req->size);
++ }
++
+ if (!req->data_is_ptr) {
+ if (req->dir == IOREQ_READ) {
+ for (i = 0; i < req->count; i++) {
+@@ -1010,11 +1018,13 @@ static int handle_buffered_iopage(XenIOS
+ req.df = 1;
+ req.type = buf_req->type;
+ req.data_is_ptr = 0;
++ xen_rmb();
+ qw = (req.size == 8);
+ if (qw) {
+ buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
+ IOREQ_BUFFER_SLOT_NUM];
+ req.data |= ((uint64_t)buf_req->data) << 32;
++ xen_rmb();
+ }
+
+ handle_ioreq(state, &req);
+@@ -1045,7 +1055,11 @@ static void cpu_handle_ioreq(void *opaqu
+
+ handle_buffered_iopage(state);
+ if (req) {
+- handle_ioreq(state, req);
++ ioreq_t copy = *req;
++
++ xen_rmb();
++ handle_ioreq(state, &copy);
++ req->data = copy.data;
+
+ if (req->state != STATE_IOREQ_INPROCESS) {
+ fprintf(stderr, "Badness in I/O request ... not in service?!: "
diff --git a/main/xen/xsa198.patch b/main/xen/xsa198.patch
new file mode 100644
index 0000000000..dbf708491e
--- /dev/null
+++ b/main/xen/xsa198.patch
@@ -0,0 +1,62 @@
+From 71a389ae940bc52bf897a6e5becd73fd8ede94c5 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ian.jackson@eu.citrix.com>
+Date: Thu, 3 Nov 2016 16:37:40 +0000
+Subject: [PATCH] pygrub: Properly quote results, when returning them to the
+ caller:
+
+* When the caller wants sexpr output, use `repr()'
+ This is what Xend expects.
+
+ The returned S-expressions are now escaped and quoted by Python,
+ generally using '...'. Previously kernel and ramdisk were unquoted
+ and args was quoted with "..." but without proper escaping. This
+ change may break toolstacks which do not properly dequote the
+ returned S-expressions.
+
+* When the caller wants "simple" output, crash if the delimiter is
+ contained in the returned value.
+
+ With --output-format=simple it does not seem like this could ever
+ happen, because the bootloader config parsers all take line-based
+ input from the various bootloader config files.
+
+ With --output-format=simple0, this can happen if the bootloader
+ config file contains nul bytes.
+
+This is XSA-198.
+
+Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
+Tested-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+---
+ tools/pygrub/src/pygrub | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
+index 40f9584..dd0c8f7 100755
+--- a/tools/pygrub/src/pygrub
++++ b/tools/pygrub/src/pygrub
+@@ -721,14 +721,17 @@ def sniff_netware(fs, cfg):
+ return cfg
+
+ def format_sxp(kernel, ramdisk, args):
+- s = "linux (kernel %s)" % kernel
++ s = "linux (kernel %s)" % repr(kernel)
+ if ramdisk:
+- s += "(ramdisk %s)" % ramdisk
++ s += "(ramdisk %s)" % repr(ramdisk)
+ if args:
+- s += "(args \"%s\")" % args
++ s += "(args %s)" % repr(args)
+ return s
+
+ def format_simple(kernel, ramdisk, args, sep):
++ for check in (kernel, ramdisk, args):
++ if check is not None and sep in check:
++ raise RuntimeError, "simple format cannot represent delimiter-containing value"
+ s = ("kernel %s" % kernel) + sep
+ if ramdisk:
+ s += ("ramdisk %s" % ramdisk) + sep
+--
+2.1.4
+