aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonardo Arena <rnalrd@alpinelinux.org>2018-03-06 12:31:09 +0000
committerLeonardo Arena <rnalrd@alpinelinux.org>2018-03-06 12:31:18 +0000
commit1fb3325abc8bc3f37fa93c0663908c29e9154087 (patch)
tree54b27d3ec068a4bbd647b5afe89f9f45eb5af43c
parent44ec7e4406170dec0bcab3fc699115efa72fb094 (diff)
downloadaports-1fb3325abc8bc3f37fa93c0663908c29e9154087.tar.bz2
aports-1fb3325abc8bc3f37fa93c0663908c29e9154087.tar.xz
main/xen: security fixes
CVE-2018-7540, XSA-252 CVE-2018-7541, XSA-255 CVE-2018-7542, XSA-256 Fixes #8614
-rw-r--r--main/xen/APKBUILD14
-rw-r--r--main/xen/xsa252-4.9.patch25
-rw-r--r--main/xen/xsa255-4.9-1.patch126
-rw-r--r--main/xen/xsa255-4.9-2.patch186
-rw-r--r--main/xen/xsa256.patch40
5 files changed, 390 insertions, 1 deletions
diff --git a/main/xen/APKBUILD b/main/xen/APKBUILD
index dbb5bc20cb..6c15139f69 100644
--- a/main/xen/APKBUILD
+++ b/main/xen/APKBUILD
@@ -3,7 +3,7 @@
# Maintainer: William Pitcock <nenolod@dereferenced.org>
pkgname=xen
pkgver=4.9.1
-pkgrel=3
+pkgrel=4
pkgdesc="Xen hypervisor"
url="http://www.xen.org/"
arch="x86_64 armhf aarch64"
@@ -108,6 +108,10 @@ options="!strip"
# - XSA-251
# 4.9.1-r3:
# - XSA-254 XPTI
+# 4.9.1-r4:
+# - CVE-2018-7540 XSA-252
+# - CVE-2018-7541 XSA-255
+# - CVE-2018-7542 XSA-256
case "$CARCH" in
x86*)
@@ -162,6 +166,10 @@ source="https://downloads.xenproject.org/release/$pkgname/$pkgver/$pkgname-$pkgv
xsa249.patch
xsa250.patch
xsa251.patch
+ xsa252-4.9.patch
+ xsa255-4.9-1.patch
+ xsa255-4.9-2.patch
+ xsa256.patch
0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch
0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch
@@ -433,6 +441,10 @@ c5e064543048751fda86ce64587493518da87d219ff077abb83ac13d8381ceb29f1b6479fc0b761b
05a2e954bab1877500eb5ed3a8c49edb27411ed3ec9dbfb2115b7804a3b03c6d45c9f08a7ed96ff2b586346f321142065a8c5a5d996468496b373637b6ee31b9 xsa249.patch
b3030f09ddb4f9e4a356519c7b74d393e8db085278a1e616788c81d19988699a6efdd8568277c25514f3298ca92e5a09e3cd08b0a308a4d2ddb55374a8445657 xsa250.patch
928153b48af2bd6b334058c5919880cfc7d665c63e0232932866941cbea6deb8d0d83f70dff0974d3df27fc84096beca51139a0b1c0585978f298256b3fd82eb xsa251.patch
+993febe7ac7d4add0f36a519fe461a40d32f16e23003dfb23e76883ecdd86474cd4a6f9d0a9190cc6bc8cad19afa652556f125a5d5edb4fa2e9f2e6a5e77b2b9 xsa252-4.9.patch
+3af678f3c4271da2bb1515b9a1e76d9b85b391fbb1e9cd521c66ac52d2984a15c6c1bb6fa8a1f408380e4c7462b1ef671f77245fee6eecef274f93ca47bc12bd xsa255-4.9-1.patch
+22bf18c5e0120d787c9ec04d10dfb4684a0849c5d7a80cbe400f8f2ee2ee64789c9e6fe5bedab579ca4928f3168f7a5c0c817f93c73ad1cf7ce702a4afe732ab xsa255-4.9-2.patch
+3bd2697a8ad66197264af8a713bf97152ed414c4b11910cc986c6adaa85bd86b4d35319675799edccf04aaff9ae48a58ca5c438cb6b5b95f60fffbfeec5e4faf xsa256.patch
cda45e5a564e429a1299f07ea496b0e0614f6b2d71a5dcd24f5efdb571cc54d74d04c8e0766279fe2acb7d9bb9cf8505281d6c7ba2d6334009e14a10f83096ee 0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch
bce07e4094ae3036dafdf9fe3aeb1f566281484e1398184d774af9ad371066c0e8af232b8d1ab5d450923fb482e6dea6dfb921976b87b20ab56a3f2b4486d0d4 0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch
ba09c54451fae35f3fc70e4f2a76791bc652ad373e87402ebc30c53f8e7db2368d52a9018cc28a5efcbcd77e85c9ae45d9580550f215a3f9bbf63bbd21ef938d 0003-x86-Meltdown-band-aid-against-malicious-64-bit-PV-gu.patch
diff --git a/main/xen/xsa252-4.9.patch b/main/xen/xsa252-4.9.patch
new file mode 100644
index 0000000000..4afc22a6f1
--- /dev/null
+++ b/main/xen/xsa252-4.9.patch
@@ -0,0 +1,25 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: memory: don't implicitly unpin for decrease-reservation
+
+It very likely was a mistake (copy-and-paste from domain cleanup code)
+to implicitly unpin here: The caller should really unpin itself before
+(or after, if they so wish) requesting the page to be removed.
+
+This is XSA-252.
+
+Reported-by: Jann Horn <jannh@google.com>
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+--- a/xen/common/memory.c
++++ b/xen/common/memory.c
+@@ -341,9 +341,6 @@ int guest_remove_page(struct domain *d,
+
+ rc = guest_physmap_remove_page(d, _gfn(gmfn), mfn, 0);
+
+- if ( !rc && test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
+- put_page_and_type(page);
+-
+ /*
+ * With the lack of an IOMMU on some platforms, domains with DMA-capable
+ * device must retrieve the same pfn when the hypercall populate_physmap
diff --git a/main/xen/xsa255-4.9-1.patch b/main/xen/xsa255-4.9-1.patch
new file mode 100644
index 0000000000..0365adf750
--- /dev/null
+++ b/main/xen/xsa255-4.9-1.patch
@@ -0,0 +1,126 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: gnttab/ARM: don't corrupt shared GFN array
+
+... by writing status GFNs to it. Introduce a second array instead.
+Also implement gnttab_status_gmfn() properly now that the information is
+suitably being tracked.
+
+While touching it anyway, remove a misguided (but luckily benign) upper
+bound check from gnttab_shared_gmfn(): We should never access beyond the
+bounds of that array.
+
+This is part of XSA-255.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+--- a/xen/arch/arm/domain.c
++++ b/xen/arch/arm/domain.c
+@@ -461,19 +461,37 @@ void startup_cpu_idle_loop(void)
+ struct domain *alloc_domain_struct(void)
+ {
+ struct domain *d;
++ unsigned int i, max_status_frames;
++
+ BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE);
+ d = alloc_xenheap_pages(0, 0);
+ if ( d == NULL )
+ return NULL;
+
+ clear_page(d);
+- d->arch.grant_table_gfn = xzalloc_array(gfn_t, max_grant_frames);
++
++ d->arch.grant_shared_gfn = xmalloc_array(gfn_t, max_grant_frames);
++ max_status_frames = grant_to_status_frames(max_grant_frames);
++ d->arch.grant_status_gfn = xmalloc_array(gfn_t, max_status_frames);
++ if ( !d->arch.grant_shared_gfn || !d->arch.grant_status_gfn )
++ {
++ free_domain_struct(d);
++ return NULL;
++ }
++
++ for ( i = 0; i < max_grant_frames; ++i )
++ d->arch.grant_shared_gfn[i] = INVALID_GFN;
++
++ for ( i = 0; i < max_status_frames; ++i )
++ d->arch.grant_status_gfn[i] = INVALID_GFN;
++
+ return d;
+ }
+
+ void free_domain_struct(struct domain *d)
+ {
+- xfree(d->arch.grant_table_gfn);
++ xfree(d->arch.grant_shared_gfn);
++ xfree(d->arch.grant_status_gfn);
+ free_xenheap_page(d);
+ }
+
+--- a/xen/arch/arm/mm.c
++++ b/xen/arch/arm/mm.c
+@@ -1148,6 +1148,7 @@ int xenmem_add_to_physmap_one(
+ int rc;
+ p2m_type_t t;
+ struct page_info *page = NULL;
++ bool status = false;
+
+ switch ( space )
+ {
+@@ -1165,6 +1166,7 @@ int xenmem_add_to_physmap_one(
+ mfn = virt_to_mfn(d->grant_table->status[idx]);
+ else
+ mfn = mfn_x(INVALID_MFN);
++ status = true;
+ }
+ else
+ {
+@@ -1180,7 +1182,10 @@ int xenmem_add_to_physmap_one(
+
+ if ( mfn != mfn_x(INVALID_MFN) )
+ {
+- d->arch.grant_table_gfn[idx] = gfn;
++ if ( status )
++ d->arch.grant_status_gfn[idx] = gfn;
++ else
++ d->arch.grant_shared_gfn[idx] = gfn;
+
+ t = p2m_ram_rw;
+ }
+--- a/xen/include/asm-arm/domain.h
++++ b/xen/include/asm-arm/domain.h
+@@ -50,7 +50,8 @@ struct arch_domain
+ struct p2m_domain p2m;
+
+ struct hvm_domain hvm_domain;
+- gfn_t *grant_table_gfn;
++ gfn_t *grant_shared_gfn;
++ gfn_t *grant_status_gfn;
+
+ struct vmmio vmmio;
+
+--- a/xen/include/asm-arm/grant_table.h
++++ b/xen/include/asm-arm/grant_table.h
+@@ -14,7 +14,6 @@ int replace_grant_host_mapping(unsigned
+ unsigned long new_gpaddr, unsigned int flags);
+ void gnttab_mark_dirty(struct domain *d, unsigned long l);
+ #define gnttab_create_status_page(d, t, i) do {} while (0)
+-#define gnttab_status_gmfn(d, t, i) (0)
+ #define gnttab_release_host_mappings(domain) 1
+ static inline int replace_grant_supported(void)
+ {
+@@ -29,8 +28,12 @@ static inline int replace_grant_supporte
+ } while ( 0 )
+
+ #define gnttab_shared_gmfn(d, t, i) \
+- ( ((i >= nr_grant_frames(d->grant_table)) && \
+- (i < max_grant_frames)) ? 0 : gfn_x(d->arch.grant_table_gfn[i]))
++ gfn_x(((i) >= nr_grant_frames(t)) ? INVALID_GFN \
++ : (d)->arch.grant_shared_gfn[i])
++
++#define gnttab_status_gmfn(d, t, i) \
++ gfn_x(((i) >= nr_status_frames(t)) ? INVALID_GFN \
++ : (d)->arch.grant_status_gfn[i])
+
+ #define gnttab_need_iommu_mapping(d) \
+ (is_domain_direct_mapped(d) && need_iommu(d))
diff --git a/main/xen/xsa255-4.9-2.patch b/main/xen/xsa255-4.9-2.patch
new file mode 100644
index 0000000000..ce225bde28
--- /dev/null
+++ b/main/xen/xsa255-4.9-2.patch
@@ -0,0 +1,186 @@
+From: Jan Beulich <jbeulich@suse.com>
+Subject: gnttab: don't blindly free status pages upon version change
+
+There may still be active mappings, which would trigger the respective
+BUG_ON(). Split the loop into one dealing with the page attributes and
+the second (when the first fully passed) freeing the pages. Return an
+error if any pages still have pending references.
+
+This is part of XSA-255.
+
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
+
+--- a/xen/arch/arm/mm.c
++++ b/xen/arch/arm/mm.c
+@@ -1180,12 +1180,22 @@ int xenmem_add_to_physmap_one(
+ mfn = mfn_x(INVALID_MFN);
+ }
+
++ if ( mfn != mfn_x(INVALID_MFN) &&
++ !gfn_eq(gnttab_get_frame_gfn(d, status, idx), INVALID_GFN) )
++ {
++ rc = guest_physmap_remove_page(d,
++ gnttab_get_frame_gfn(d, status, idx),
++ _mfn(mfn), 0);
++ if ( rc )
++ {
++ grant_write_unlock(d->grant_table);
++ return rc;
++ }
++ }
++
+ if ( mfn != mfn_x(INVALID_MFN) )
+ {
+- if ( status )
+- d->arch.grant_status_gfn[idx] = gfn;
+- else
+- d->arch.grant_shared_gfn[idx] = gfn;
++ gnttab_set_frame_gfn(d, status, idx, gfn);
+
+ t = p2m_ram_rw;
+ }
+--- a/xen/common/grant_table.c
++++ b/xen/common/grant_table.c
+@@ -1516,23 +1516,74 @@ status_alloc_failed:
+ return -ENOMEM;
+ }
+
+-static void
++static int
+ gnttab_unpopulate_status_frames(struct domain *d, struct grant_table *gt)
+ {
+- int i;
++ unsigned int i;
+
+ for ( i = 0; i < nr_status_frames(gt); i++ )
+ {
+ struct page_info *pg = virt_to_page(gt->status[i]);
++ gfn_t gfn = gnttab_get_frame_gfn(d, true, i);
++
++ /*
++ * For translated domains, recovering from failure after partial
++ * changes were made is more complicated than it seems worth
++ * implementing at this time. Hence respective error paths below
++ * crash the domain in such a case.
++ */
++ if ( paging_mode_translate(d) )
++ {
++ int rc = gfn_eq(gfn, INVALID_GFN)
++ ? 0
++ : guest_physmap_remove_page(d, gfn,
++ _mfn(page_to_mfn(pg)), 0);
++
++ if ( rc )
++ {
++ gprintk(XENLOG_ERR,
++ "Could not remove status frame %u (GFN %#lx) from P2M\n",
++ i, gfn_x(gfn));
++ domain_crash(d);
++ return rc;
++ }
++ gnttab_set_frame_gfn(d, true, i, INVALID_GFN);
++ }
+
+ BUG_ON(page_get_owner(pg) != d);
+ if ( test_and_clear_bit(_PGC_allocated, &pg->count_info) )
+ put_page(pg);
+- BUG_ON(pg->count_info & ~PGC_xen_heap);
++
++ if ( pg->count_info & ~PGC_xen_heap )
++ {
++ if ( paging_mode_translate(d) )
++ {
++ gprintk(XENLOG_ERR,
++ "Wrong page state %#lx of status frame %u (GFN %#lx)\n",
++ pg->count_info, i, gfn_x(gfn));
++ domain_crash(d);
++ }
++ else
++ {
++ if ( get_page(pg, d) )
++ set_bit(_PGC_allocated, &pg->count_info);
++ while ( i-- )
++ gnttab_create_status_page(d, gt, i);
++ }
++ return -EBUSY;
++ }
++
++ page_set_owner(pg, NULL);
++ }
++
++ for ( i = 0; i < nr_status_frames(gt); i++ )
++ {
+ free_xenheap_page(gt->status[i]);
+ gt->status[i] = NULL;
+ }
+ gt->nr_status_frames = 0;
++
++ return 0;
+ }
+
+ /*
+@@ -2774,8 +2825,9 @@ gnttab_set_version(XEN_GUEST_HANDLE_PARA
+ break;
+ }
+
+- if ( op.version < 2 && gt->gt_version == 2 )
+- gnttab_unpopulate_status_frames(currd, gt);
++ if ( op.version < 2 && gt->gt_version == 2 &&
++ (res = gnttab_unpopulate_status_frames(currd, gt)) != 0 )
++ goto out_unlock;
+
+ /* Make sure there's no crud left over from the old version. */
+ for ( i = 0; i < nr_grant_frames(gt); i++ )
+--- a/xen/include/asm-arm/grant_table.h
++++ b/xen/include/asm-arm/grant_table.h
+@@ -20,6 +20,17 @@ static inline int replace_grant_supporte
+ return 1;
+ }
+
++#define gnttab_set_frame_gfn(d, st, idx, gfn) \
++ do { \
++ ((st) ? (d)->arch.grant_status_gfn \
++ : (d)->arch.grant_shared_gfn)[idx] = (gfn); \
++ } while ( 0 )
++
++#define gnttab_get_frame_gfn(d, st, idx) ({ \
++ _gfn((st) ? gnttab_status_gmfn(d, (d)->grant_table, idx) \
++ : gnttab_shared_gmfn(d, (d)->grant_table, idx)); \
++})
++
+ #define gnttab_create_shared_page(d, t, i) \
+ do { \
+ share_xen_page_with_guest( \
+--- a/xen/include/asm-x86/grant_table.h
++++ b/xen/include/asm-x86/grant_table.h
+@@ -18,6 +18,14 @@ int create_grant_host_mapping(uint64_t a
+ int replace_grant_host_mapping(
+ uint64_t addr, unsigned long frame, uint64_t new_addr, unsigned int flags);
+
++#define gnttab_set_frame_gfn(d, st, idx, gfn) do {} while ( 0 )
++#define gnttab_get_frame_gfn(d, st, idx) ({ \
++ unsigned long mfn_ = (st) ? gnttab_status_mfn((d)->grant_table, idx) \
++ : gnttab_shared_mfn((d)->grant_table, idx); \
++ unsigned long gpfn_ = get_gpfn_from_mfn(mfn_); \
++ VALID_M2P(gpfn_) ? _gfn(gpfn_) : INVALID_GFN; \
++})
++
+ #define gnttab_create_shared_page(d, t, i) \
+ do { \
+ share_xen_page_with_guest( \
+@@ -33,11 +41,11 @@ int replace_grant_host_mapping(
+ } while ( 0 )
+
+
+-#define gnttab_shared_mfn(d, t, i) \
++#define gnttab_shared_mfn(t, i) \
+ ((virt_to_maddr((t)->shared_raw[i]) >> PAGE_SHIFT))
+
+ #define gnttab_shared_gmfn(d, t, i) \
+- (mfn_to_gmfn(d, gnttab_shared_mfn(d, t, i)))
++ (mfn_to_gmfn(d, gnttab_shared_mfn(t, i)))
+
+
+ #define gnttab_status_mfn(t, i) \
diff --git a/main/xen/xsa256.patch b/main/xen/xsa256.patch
new file mode 100644
index 0000000000..50ff24e17b
--- /dev/null
+++ b/main/xen/xsa256.patch
@@ -0,0 +1,40 @@
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+Subject: x86/hvm: Disallow the creation of HVM domains without Local APIC emulation
+
+There are multiple problems, not necesserily limited to:
+
+ * Guests which configure event channels via hvmop_set_evtchn_upcall_vector(),
+ or which hit %cr8 emulation will cause Xen to fall over a NULL vlapic->regs
+ pointer.
+
+ * On Intel hardware, disabling the TPR_SHADOW execution control without
+ reenabling CR8_{LOAD,STORE} interception means that the guests %cr8
+ accesses interact with the real TPR. Amongst other things, setting the
+ real TPR to 0xf blocks even IPIs from interrupting this CPU.
+
+ * On hardware which sets up the use of Interrupt Posting, including
+ IOMMU-Posting, guests run without the appropriate non-root configuration,
+ which at a minimum will result in dropped interrupts.
+
+Whether no-LAPIC mode is of any use at all remains to be seen.
+
+This is XSA-256.
+
+Reported-by: Ian Jackson <ian.jackson@eu.citrix.com>
+Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+
+diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
+index f93327b..f65fc12 100644
+--- a/xen/arch/x86/domain.c
++++ b/xen/arch/x86/domain.c
+@@ -413,7 +413,7 @@ static bool emulation_flags_ok(const struct domain *d, uint32_t emflags)
+ if ( is_hardware_domain(d) &&
+ emflags != (XEN_X86_EMU_LAPIC|XEN_X86_EMU_IOAPIC) )
+ return false;
+- if ( !is_hardware_domain(d) && emflags &&
++ if ( !is_hardware_domain(d) &&
+ emflags != XEN_X86_EMU_ALL && emflags != XEN_X86_EMU_LAPIC )
+ return false;
+ }