aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonardo Arena <rnalrd@alpinelinux.org>2016-05-09 13:12:24 +0000
committerLeonardo Arena <rnalrd@alpinelinux.org>2016-05-09 13:12:24 +0000
commit6ee4459a5f8f1757470b868e4874677e31fbb3fd (patch)
treed356bd4b7406111dc15e2c82a1a721545652d4d0
parent1e4709887b69db528ad1b8d34d303e1eb6f464dc (diff)
downloadaports-6ee4459a5f8f1757470b868e4874677e31fbb3fd.tar.bz2
aports-6ee4459a5f8f1757470b868e4874677e31fbb3fd.tar.xz
main/xen: security fixes (CVE-2016-3158, CVE-2016-3159, CVE-2016-3960). Fixes #5493
-rw-r--r--main/xen/APKBUILD10
-rw-r--r--main/xen/xsa172-4.3.patch25
-rw-r--r--main/xen/xsa173-4.3.patch251
3 files changed, 285 insertions, 1 deletions
diff --git a/main/xen/APKBUILD b/main/xen/APKBUILD
index 60a405ed9d..28e5c69900 100644
--- a/main/xen/APKBUILD
+++ b/main/xen/APKBUILD
@@ -3,7 +3,7 @@
# Maintainer: William Pitcock <nenolod@dereferenced.org>
pkgname=xen
pkgver=4.3.4
-pkgrel=2
+pkgrel=3
pkgdesc="Xen hypervisor"
url="http://www.xen.org/"
arch="x86_64"
@@ -36,6 +36,8 @@ source="http://bits.xensource.com/oss-xen/release/$pkgver/$pkgname-$pkgver.tar.g
xsa167-4.4.patch
xsa168.patch
xsa170-4.3.patch
+ xsa172-4.3.patch
+ xsa173-4.3.patch
fix-pod2man-choking.patch
@@ -236,6 +238,8 @@ dd4c8f838e9a9a322aa8b687a801bc2d xsa165-4.3.patch
1832af4e78d994617c18bd7df58e6409 xsa167-4.4.patch
b837726ce186fa61cfe7238b225b0335 xsa168.patch
f6db702ef56645a20afe9eaa31b64dda xsa170-4.3.patch
+f679096807ade5999f15299a53cd929c xsa172-4.3.patch
+add55a6d182d1aa0768b15936fbc0679 xsa173-4.3.patch
4c5455d1adc09752a835e241097fbc39 fix-pod2man-choking.patch
1080a6535288ba9f5c471c718a1ffde4 qemu-xen-websocket.patch
35bdea1d4e3ae2565edc7e40906efdd5 qemu-xen-tls-websockets.patch
@@ -279,6 +283,8 @@ bced245fb1111b7fa2db642971cceb0523e691367ba8bfbc6ff0da421f198c97 xsa165-4.3.pat
194c1ce89292f4cbb9980baa703095bcbeb5849abf46d193e07a98a0d8301f78 xsa167-4.4.patch
c95198a66485d6e538d113ce2b84630d77c15f597113c38fadd6bf1e24e4c8ec xsa168.patch
b35679bf7a35615d827efafff8d13c35ceec1184212e3c8ba110722b9ae8426f xsa170-4.3.patch
+6aac179620afcdbdab041163239019bc35b0e243f3bd16673caaec7d5a4d97ec xsa172-4.3.patch
+089c07f0c8237da674796f155ee7e3c0305efd11a59df30ef2c3d5f6b423bfea xsa173-4.3.patch
fcb5b9ff0bc4b4d39fed9b88891491b91628aa449914cfea321abe5da24c1da2 fix-pod2man-choking.patch
a391077b3a5dbc2296a3fa540d86dc3a8e0f780ba92cb94c899a6e9853863862 qemu-xen-websocket.patch
435dd428d83acdfde58888532a1cece1e9075b2a2460fe3f6cd33c7d400f2715 qemu-xen-tls-websockets.patch
@@ -322,6 +328,8 @@ f12e15fe6e67cc61ba462993f69e5c247ae58652fe84ecd5a2f48379a9734cafcb22c83c3398aeca
61c41491a6086a96bcdf830c7330d71561b6229cd71672075d00ef011e84e3e00b15a1ff650a8ec36a3936e970593c2ce0f986810cecca1d2f1973e1378c4e22 xsa167-4.4.patch
c55ee924b21edf54ce3c873d952a20f32f851661a13514528d42d2ef36767cfa9e31b1a42a4e0f40ff1011c692c406155fcc59be0c43fd44973cd0a5acee2ac7 xsa168.patch
ce51cac0961a1d51b437d97ee64ce810152264eeed5524d1d4cc2d54fe5dad7ec0bd2bbbcbd6ce822e563d4434ab2c3b0a9b3d55722fa1cb35c5983f2db9d826 xsa170-4.3.patch
+d0e2e08ff9c01ae482d835e1443de85ee6791731fd6bd2cabe31aef075bf178f46201f4774b2ad0178a61a501210e00a4d3c65ae583e0537457a102dd4508774 xsa172-4.3.patch
+654ec5e4456fefb3236ed53de0042793b8e55828774cddab0f8cb017fd575c117b2dc4ac7459cbcd474ada37afba5fca83b1dc47b477730bbbe038ddaadf20d3 xsa173-4.3.patch
2e95ad43bb66f928fe1e8caf474a3211571f75f79ea32aaa3eddb3aed9963444bd131006b67e682395af0d79118b2634bf808404693b813a94662d2a9d665ac2 fix-pod2man-choking.patch
062b2db5e5bd9b5a21e21ac4fbe60b9ef350487ebeb50d8051c1950715499f7cc3e3068e7e80950caa32c18709f0a7f7130d7fa91f6d774da7eb4a5d8d49b597 qemu-xen-websocket.patch
11eaccc346440ff285552f204d491e3b31bda1665c3219ecae3061b5d55db9dec885af0c031fa19c67e87bbe238002b1911bbd5bfea2f2ba0d61e6b3d0c952c9 qemu-xen-tls-websockets.patch
diff --git a/main/xen/xsa172-4.3.patch b/main/xen/xsa172-4.3.patch
new file mode 100644
index 0000000000..b072b79386
--- /dev/null
+++ b/main/xen/xsa172-4.3.patch
@@ -0,0 +1,25 @@
+x86: fix information leak on AMD CPUs
+
+The fix for XSA-52 was wrong, and so was the change synchronizing that
+new behavior to the FXRSTOR logic: AMD's manuals explictly state that
+writes to the ES bit are ignored, and it instead gets calculated from
+the exception and mask bits (it gets set whenever there is an unmasked
+exception, and cleared otherwise). Hence we need to follow that model
+in our workaround.
+
+This is XSA-172 / CVE-2016-3158.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+--- a/xen/arch/x86/xstate.c
++++ b/xen/arch/x86/xstate.c
+@@ -158,7 +158,7 @@ void xrstor(struct vcpu *v, uint64_t mas
+ * data block as a safe address because it should be in L1.
+ */
+ if ( (mask & ptr->xsave_hdr.xstate_bv & XSTATE_FP) &&
+- !(ptr->fpu_sse.fsw & 0x0080) &&
++ !(ptr->fpu_sse.fsw & ~ptr->fpu_sse.fcw & 0x003f) &&
+ boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+ asm volatile ( "fnclex\n\t" /* clear exceptions */
+ "ffree %%st(7)\n\t" /* clear stack tag */
diff --git a/main/xen/xsa173-4.3.patch b/main/xen/xsa173-4.3.patch
new file mode 100644
index 0000000000..fed2e46c34
--- /dev/null
+++ b/main/xen/xsa173-4.3.patch
@@ -0,0 +1,251 @@
+commit 95dd1b6e87b61222fc856724a5d828c9bdc30c80
+Author: Tim Deegan <tim@xen.org>
+Date: Wed Mar 16 17:07:18 2016 +0000
+
+ x86: limit GFNs to 32 bits for shadowed superpages.
+
+ Superpage shadows store the shadowed GFN in the backpointer field,
+ which for non-BIGMEM builds is 32 bits wide. Shadowing a superpage
+ mapping of a guest-physical address above 2^44 would lead to the GFN
+ being truncated there, and a crash when we come to remove the shadow
+ from the hash table.
+
+ Track the valid width of a GFN for each guest, including reporting it
+ through CPUID, and enforce it in the shadow pagetables. Set the
+ maximum witth to 32 for guests where this truncation could occur.
+
+ This is XSA-173.
+
+ Signed-off-by: Tim Deegan <tim@xen.org>
+ Signed-off-by: Jan Beulich <jbeulich@suse.com>
+
+Reported-by: Ling Liu <liuling-it@360.cn>
+diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
+index f449a8f..533558c 100644
+--- a/xen/arch/x86/cpu/common.c
++++ b/xen/arch/x86/cpu/common.c
+@@ -34,6 +34,7 @@ integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
+ struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
+
+ unsigned int paddr_bits __read_mostly = 36;
++unsigned int hap_paddr_bits __read_mostly = 36;
+
+ /*
+ * Default host IA32_CR_PAT value to cover all memory types.
+@@ -192,7 +193,7 @@ static void __init early_cpu_detect(void)
+
+ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
+ {
+- u32 tfms, xlvl, capability, excap, ebx;
++ u32 tfms, xlvl, capability, excap, eax, ebx;
+
+ /* Get vendor name */
+ cpuid(0x00000000, &c->cpuid_level,
+@@ -227,8 +228,11 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
+ }
+ if ( xlvl >= 0x80000004 )
+ get_model_name(c); /* Default name */
+- if ( xlvl >= 0x80000008 )
+- paddr_bits = cpuid_eax(0x80000008) & 0xff;
++ if ( xlvl >= 0x80000008 ) {
++ eax = cpuid_eax(0x80000008);
++ paddr_bits = eax & 0xff;
++ hap_paddr_bits = ((eax >> 16) & 0xff) ?: paddr_bits;
++ }
+ }
+
+ /* Might lift BIOS max_leaf=3 limit. */
+diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
+index 9dafcca..aee4aa1 100644
+--- a/xen/arch/x86/hvm/hvm.c
++++ b/xen/arch/x86/hvm/hvm.c
+@@ -2888,8 +2888,7 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
+ break;
+
+ case 0x80000008:
+- count = cpuid_eax(0x80000008);
+- count = (count >> 16) & 0xff ?: count & 0xff;
++ count = d->arch.paging.gfn_bits + PAGE_SHIFT;
+ if ( (*eax & 0xff) > count )
+ *eax = (*eax & ~0xff) | count;
+
+diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c
+index 70460b6..09511f0 100644
+--- a/xen/arch/x86/mm/guest_walk.c
++++ b/xen/arch/x86/mm/guest_walk.c
+@@ -94,6 +94,12 @@ void *map_domain_gfn(struct p2m_domain *p2m, gfn_t gfn, mfn_t *mfn,
+ struct page_info *page;
+ void *map;
+
++ if ( gfn_x(gfn) >> p2m->domain->arch.paging.gfn_bits )
++ {
++ *rc = _PAGE_INVALID_BIT;
++ return NULL;
++ }
++
+ /* Translate the gfn, unsharing if shared */
+ page = get_page_from_gfn_p2m(p2m->domain, p2m, gfn_x(gfn), p2mt, NULL,
+ q);
+@@ -294,20 +300,8 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
+ flags &= ~_PAGE_PAT;
+
+ if ( gfn_x(start) & GUEST_L2_GFN_MASK & ~0x1 )
+- {
+-#if GUEST_PAGING_LEVELS == 2
+- /*
+- * Note that _PAGE_INVALID_BITS is zero in this case, yielding a
+- * no-op here.
+- *
+- * Architecturally, the walk should fail if bit 21 is set (others
+- * aren't being checked at least in PSE36 mode), but we'll ignore
+- * this here in order to avoid specifying a non-natural, non-zero
+- * _PAGE_INVALID_BITS value just for that case.
+- */
+-#endif
+ rc |= _PAGE_INVALID_BITS;
+- }
++
+ /* Increment the pfn by the right number of 4k pages.
+ * Mask out PAT and invalid bits. */
+ start = _gfn((gfn_x(start) & ~GUEST_L2_GFN_MASK) +
+@@ -390,5 +384,11 @@ set_ad:
+ put_page(mfn_to_page(mfn_x(gw->l1mfn)));
+ }
+
++ /* If this guest has a restricted physical address space then the
++ * target GFN must fit within it. */
++ if ( !(rc & _PAGE_PRESENT)
++ && gfn_x(guest_l1e_get_gfn(gw->l1e)) >> d->arch.paging.gfn_bits )
++ rc |= _PAGE_INVALID_BITS;
++
+ return rc;
+ }
+diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
+index 66239b7..10c2951 100644
+--- a/xen/arch/x86/mm/hap/hap.c
++++ b/xen/arch/x86/mm/hap/hap.c
+@@ -421,6 +421,7 @@ static void hap_destroy_monitor_table(struct vcpu* v, mfn_t mmfn)
+ void hap_domain_init(struct domain *d)
+ {
+ INIT_PAGE_LIST_HEAD(&d->arch.paging.hap.freelist);
++ d->arch.paging.gfn_bits = hap_paddr_bits - PAGE_SHIFT;
+ }
+
+ /* return 0 for success, -errno for failure */
+diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c
+index 49d9e06..edbb544 100644
+--- a/xen/arch/x86/mm/shadow/common.c
++++ b/xen/arch/x86/mm/shadow/common.c
+@@ -48,6 +48,16 @@ void shadow_domain_init(struct domain *d, unsigned int domcr_flags)
+ INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.freelist);
+ INIT_PAGE_LIST_HEAD(&d->arch.paging.shadow.pinned_shadows);
+
++ d->arch.paging.gfn_bits = paddr_bits - PAGE_SHIFT;
++#ifndef CONFIG_BIGMEM
++ /*
++ * Shadowed superpages store GFNs in 32-bit page_info fields.
++ * Note that we cannot use guest_supports_superpages() here.
++ */
++ if ( is_hvm_domain(d) || opt_allow_superpage )
++ d->arch.paging.gfn_bits = 32;
++#endif
++
+ /* Use shadow pagetables for log-dirty support */
+ paging_log_dirty_init(d, shadow_enable_log_dirty,
+ shadow_disable_log_dirty, shadow_clean_dirty_bitmap);
+diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c
+index 96ba5f2..fa5aad4 100644
+--- a/xen/arch/x86/mm/shadow/multi.c
++++ b/xen/arch/x86/mm/shadow/multi.c
+@@ -527,7 +527,8 @@ _sh_propagate(struct vcpu *v,
+ ASSERT(GUEST_PAGING_LEVELS > 3 || level != 3);
+
+ /* Check there's something for the shadows to map to */
+- if ( !p2m_is_valid(p2mt) && !p2m_is_grant(p2mt) )
++ if ( (!p2m_is_valid(p2mt) && !p2m_is_grant(p2mt))
++ || gfn_x(target_gfn) >> d->arch.paging.gfn_bits )
+ {
+ *sp = shadow_l1e_empty();
+ goto done;
+diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
+index b477646..24ddabd 100644
+--- a/xen/include/asm-x86/domain.h
++++ b/xen/include/asm-x86/domain.h
+@@ -187,6 +187,9 @@ struct paging_domain {
+ /* log dirty support */
+ struct log_dirty_domain log_dirty;
+
++ /* Number of valid bits in a gfn. */
++ unsigned int gfn_bits;
++
+ /* preemption handling */
+ struct {
+ const struct domain *dom;
+diff --git a/xen/include/asm-x86/guest_pt.h b/xen/include/asm-x86/guest_pt.h
+index b62bc6a..e06826f 100644
+--- a/xen/include/asm-x86/guest_pt.h
++++ b/xen/include/asm-x86/guest_pt.h
+@@ -220,15 +220,17 @@ guest_supports_nx(struct vcpu *v)
+ }
+
+
+-/* Some bits are invalid in any pagetable entry. */
+-#if GUEST_PAGING_LEVELS == 2
+-#define _PAGE_INVALID_BITS (0)
+-#elif GUEST_PAGING_LEVELS == 3
+-#define _PAGE_INVALID_BITS \
+- get_pte_flags(((1ull<<63) - 1) & ~((1ull<<paddr_bits) - 1))
+-#else /* GUEST_PAGING_LEVELS == 4 */
++/*
++ * Some bits are invalid in any pagetable entry.
++ * Normal flags values get represented in 24-bit values (see
++ * get_pte_flags() and put_pte_flags()), so set bit 24 in
++ * addition to be able to flag out of range frame numbers.
++ */
++#if GUEST_PAGING_LEVELS == 3
+ #define _PAGE_INVALID_BITS \
+- get_pte_flags(((1ull<<52) - 1) & ~((1ull<<paddr_bits) - 1))
++ (_PAGE_INVALID_BIT | get_pte_flags(((1ull << 63) - 1) & ~(PAGE_SIZE - 1)))
++#else /* 2-level and 4-level */
++#define _PAGE_INVALID_BITS _PAGE_INVALID_BIT
+ #endif
+
+
+diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
+index 4fa4a61..3bcc5b8 100644
+--- a/xen/include/asm-x86/processor.h
++++ b/xen/include/asm-x86/processor.h
+@@ -193,6 +193,8 @@ extern bool_t opt_cpu_info;
+
+ /* Maximum width of physical addresses supported by the hardware */
+ extern unsigned int paddr_bits;
++/* Max physical address width supported within HAP guests */
++extern unsigned int hap_paddr_bits;
+
+ extern void identify_cpu(struct cpuinfo_x86 *);
+ extern void setup_clear_cpu_cap(unsigned int);
+diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h
+index c193c88..a48c650 100644
+--- a/xen/include/asm-x86/x86_64/page.h
++++ b/xen/include/asm-x86/x86_64/page.h
+@@ -166,6 +166,7 @@ typedef l4_pgentry_t root_pgentry_t;
+
+ #define USER_MAPPINGS_ARE_GLOBAL
+ #ifdef USER_MAPPINGS_ARE_GLOBAL
++
+ /*
+ * Bit 12 of a 24-bit flag mask. This corresponds to bit 52 of a pte.
+ * This is needed to distinguish between user and kernel PTEs since _PAGE_USER
+@@ -176,6 +177,12 @@ typedef l4_pgentry_t root_pgentry_t;
+ #define _PAGE_GUEST_KERNEL 0
+ #endif
+
++/*
++ * Bit 24 of a 24-bit flag mask! This is not any bit of a real pte,
++ * and is only used for signalling in variables that contain flags.
++ */
++#define _PAGE_INVALID_BIT (1U<<24)
++
+ #endif /* __X86_64_PAGE_H__ */
+
+ /*