Commit da85ca27 authored by Natanael Copa's avatar Natanael Copa

main/xen: upgrade to 4.7.2 and fix xsa210 and xsa211

parent 634a1883
......@@ -2,8 +2,8 @@
# Contributor: Roger Pau Monne <roger.pau@entel.upc.edu>
# Maintainer: William Pitcock <nenolod@dereferenced.org>
pkgname=xen
pkgver=4.7.1
pkgrel=5
pkgver=4.7.2
pkgrel=0
pkgdesc="Xen hypervisor"
url="http://www.xen.org/"
arch="x86_64 armhf"
......@@ -14,6 +14,7 @@ depends_dev="libressl-dev python2-dev e2fsprogs-dev gettext zlib-dev ncurses-dev
spice-dev gnutls-dev curl-dev libaio-dev lzo-dev xz-dev util-linux-dev
e2fsprogs-dev linux-headers argp-standalone perl-dev"
makedepends="$depends_dev autoconf automake libtool "
options="!strip"
# secfixes:
# 4.7.0-r0:
......@@ -52,6 +53,9 @@ makedepends="$depends_dev autoconf automake libtool "
# - CVE-2017-2615 XSA-208
# - CVE-2017-2620 XSA-209
# - XSA-210
# 4.7.2-r0:
# - CVE-2016-9603 XSA-211
# - CVE-2017-7228 XSA-212
case "$CARCH" in
x86*)
......@@ -65,9 +69,9 @@ esac
install=""
if [ "$CARCH" != "armhf" ]; then
subpackages="$pkgname-dbg"
fi
#if [ "$CARCH" != "armhf" ]; then
# subpackages="$pkgname-dbg"
#fi
subpackages="$subpackages $pkgname-doc $pkgname-dev $pkgname-libs $pkgname-hypervisor"
# grep _VERSION= stubdom/configure
......@@ -95,31 +99,9 @@ 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
xsa200-4.7.patch
xsa201-1.patch
xsa201-2.patch
xsa201-3-4.7.patch
xsa201-4.patch
xsa202.patch
xsa203-4.7.patch
xsa204-4.7.patch
xsa207.patch
xsa208-qemut.patch
xsa208-qemuu-4.7.patch
xsa209-0001-display-cirrus-ignore-source-pitch-value-as-needed-i.patch
xsa209-0002-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch
xsa209-qemut.patch
xsa211-qemut.patch
xsa211-qemuu-4.7.patch
xsa212.patch
qemu-coroutine-gthread.patch
qemu-xen_paths.patch
......@@ -322,6 +304,14 @@ package() {
"$pkgdir"/etc/xen/xen-consoles.logrotate
install -m755 xen-fd-is-file "$pkgdir"/usr/lib/xen/bin/xen-fd-is-file
# we need to exclude /usr/share when stripping
msg "Stripping binaries"
scanelf --recursive --nobanner --etype "ET_DYN,ET_EXEC" "$pkgdir"/usr/lib \
"$pkgdir"/usr/bin \
"$pkgdir"/usr/sbin \
| sed -e 's:^ET_DYN ::' -e 's:^ET_EXEC ::' \
| xargs strip
}
libs() {
......@@ -341,7 +331,7 @@ hypervisor() {
mv "$pkgdir"/boot "$subpkgdir"/
}
sha512sums="eb03244f5fa7b54402fcc1d38f1e69c0ea4536d5ab2f9859b41b5e94920ad9db20fb146e3c3d3635e9ca1d12e93ce0429e57f24bf53d4a2c4b69babc76ec724e xen-4.7.1.tar.gz
sha512sums="8f447e7feffec81fea5b5a4098968b8b8cebc6989e7b6a845413317644d5d328d6f12181d09266366200878ab6a29ab34c7235c1af7b55463a3fdaea40ee1500 xen-4.7.2.tar.gz
2e0b0fd23e6f10742a5517981e5171c6e88b0a93c83da701b296f5c0861d72c19782daab589a7eac3f9032152a0fc7eff7f5362db8fccc4859564a9aa82329cf gmp-4.3.2.tar.bz2
c2bc9ffc8583aeae71cee9ddcc4418969768d4e3764d47307da54f93981c0109fb07d84b061b3a3628bd00ba4d14a54742bc04848110eb3ae8ca25dbfbaabadb grub-0.97.tar.gz
1465b58279af1647f909450e394fe002ca165f0ff4a0254bfa9fe0e64316f50facdde2729d79a4e632565b4500cf4d6c74192ac0dd3bc9fe09129bbd67ba089d lwip-1.3.0.tar.gz
......@@ -351,30 +341,9 @@ 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
44274dbef002c70606c3e5cad46433868d37e7e3f79f0d3a3e19ac43892f77cc0bd48783ecf3abe270f1ebb8ee5f3bfe6d689b732483ec0ad4fcbd11a912ab2b xsa200-4.7.patch
67006c1ac5d0b01eb65b5a9b6583ef31c0df0cdb6331af983d972d9b0c4bc21416484d88445edb8ee8470becdc11bc88fad4a617aac40ae26610eb2bee40bd01 xsa201-1.patch
afed1ed3c5b4dd3a1d2c1c0fe824cdeb58efdc40fdaf5ce439deb2feef63141168114ea362fc5c683eb0494bb6bd3c76773b099495af21550ae3a1e5cb4e924d xsa201-2.patch
ad0f4217ef8218dac6997385690981e7a88d05b735e04779f582ad4a0307d8e7804c015971403133fe1d3334c628da784c696161768b275ed3ab64d6140293dc xsa201-3-4.7.patch
1761ca422fe9e3caee3442b43b84da49721a01ed8417f653c568695b08718c40be1493cc7a0a6145c7ce195c7fb0c753b190fe2f1782d5242e1e304c18005610 xsa201-4.patch
8f96ec62d9a159370d6c6257d45b7b9e87247ac1ca891033b8f3c9fb86f74d539b9c6d893d31289c6a0f00b967672f76ee9e6875a64d739dcda783ff2911681b xsa202.patch
b86ef48db23dacb51fbbdd55041bf08fac8aa0db76a272bb2f9d9be7195cd9a359a30fbbb61e040c66f23358f12ae102a92a30296fb18e4feb1023b58ffad4ff xsa203-4.7.patch
a2a091cd51ed54f5b5ba4131efc1c9cc0a69a647cea46415f73c29e5764efb00025e2e65bd5d24cf26f903263fce150b2b1c52ca5d61fd81dea7efe16abf57be xsa204-4.7.patch
89848dcdfaebf462765b2a32c9c57d5404930721ff92f7cb05c221a99be2b82fb23d31f91f52fbf32874a69065a2e8ad921460a3655f4b03cf827a8203137fac xsa207.patch
1ddae183299bd320a2ddb9ccb52ecab36c595e72cc87dde3308c15b4e354550372f289ef35a1ce19a180fed437abb18be83af2f39b96f93335cd3f4ae83390ec xsa208-qemut.patch
1fb853f7d428e21f13bb46f22df2cf0adc04f184a39fdfcd69fb4c14ffdaf8b13c118153544e59221c5513b2765c98b37d699a4ec1ffcea6ca455118a39cebd6 xsa208-qemuu-4.7.patch
5b5b470c174e2144a4854795a1a7c4a1c514351fac7b6cf56e634a06cfd71438fb5cd95cac3239819ceef0b4b7d2903f181ed8835bad2aa97d843dd18da76d5c xsa209-0001-display-cirrus-ignore-source-pitch-value-as-needed-i.patch
ba64118f4016347b9c95df3c339f22cb9211e8604666cbc29c34c2a7e565f8b6a3ced7ea1c89cfd5211d6b26a5ba58b63e8852486c8f328b3167c2a919498548 xsa209-0002-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch
46cd186741c22cb34ca7e98fd0d9af974610c8a7c8a38d434fa878803a9365039f8c4e6338174319b026fbdd9b36c6139c03815bdccb8287f33ff843a5167c5e xsa209-qemut.patch
a3d1975afabf344b01af992642a93088e42d7655c955d38d50f00b9388cadeedaea88b6afb1db7558703cb356024a81afaee3e5cdfd76b571df9e6604e6ee035 xsa211-qemut.patch
7b1bae43d578ee1195c509760b14d15771987d685cfa2603ae07c49e1f4c9f8aea3240ebc1c14a8a1afa6d41be4e20f540ea14ca5e07e47714000ad2c9cc9cb6 xsa211-qemuu-4.7.patch
d012556c6b439629c5e4284a0de2f5ae70cda3db4f6f42373b8719509fec3bb0bb667a50484fd1e6c1129dcd2bff550a3eb9ead0f676fb626e6263ac98023e06 xsa212.patch
c3c46f232f0bd9f767b232af7e8ce910a6166b126bd5427bb8dc325aeb2c634b956de3fc225cab5af72649070c8205cc8e1cab7689fc266c204f525086f1a562 qemu-coroutine-gthread.patch
1936ab39a1867957fa640eb81c4070214ca4856a2743ba7e49c0cd017917071a9680d015f002c57fa7b9600dbadd29dcea5887f50e6c133305df2669a7a933f3 qemu-xen_paths.patch
f095ea373f36381491ad36f0662fb4f53665031973721256b23166e596318581da7cbb0146d0beb2446729adfdb321e01468e377793f6563a67d68b8b0f7ffe3 hotplug-vif-vtrill.patch
......
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;
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(
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;
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
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;
}
}
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)) )
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(-)