diff options
author | Leonardo Arena <rnalrd@alpinelinux.org> | 2018-03-12 10:55:24 +0000 |
---|---|---|
committer | Leonardo Arena <rnalrd@alpinelinux.org> | 2018-03-12 10:56:07 +0000 |
commit | 7a017e10fd6de2f5477c69120b540b2cd74652a1 (patch) | |
tree | a5f6be0bfe71b26f5926f652b443e1159d4b83d8 | |
parent | 19539511a24c68d6a70c19ae7f30e6a11736caff (diff) | |
download | aports-7a017e10fd6de2f5477c69120b540b2cd74652a1.tar.bz2 aports-7a017e10fd6de2f5477c69120b540b2cd74652a1.tar.xz |
main/xen: security fixes
-rw-r--r-- | main/xen/APKBUILD | 14 | ||||
-rw-r--r-- | main/xen/xsa252-4.9.patch | 25 | ||||
-rw-r--r-- | main/xen/xsa255-4.9-1.patch | 126 | ||||
-rw-r--r-- | main/xen/xsa255-4.9-2.patch | 186 | ||||
-rw-r--r-- | main/xen/xsa256-4.8.patch | 46 |
5 files changed, 396 insertions, 1 deletions
diff --git a/main/xen/APKBUILD b/main/xen/APKBUILD index 987dce584e..cf3165297b 100644 --- a/main/xen/APKBUILD +++ b/main/xen/APKBUILD @@ -3,7 +3,7 @@ # Maintainer: William Pitcock <nenolod@dereferenced.org> pkgname=xen pkgver=4.8.2 -pkgrel=5 +pkgrel=6 pkgdesc="Xen hypervisor" url="http://www.xen.org/" arch="x86_64 armhf" @@ -104,6 +104,10 @@ options="!strip" # - CVE-2017-17563 XSA-249 # - CVE-2017-17564 XSA-250 # - CVE-2017-17565 XSA-251 +# 4.8.2-r6: +# - CVE-2018-7540 XSA-252 +# - CVE-2018-7541 XSA-255 +# - CVE-2018-7542 XSA-256 case "$CARCH" in x86*) @@ -193,6 +197,10 @@ source="https://downloads.xenproject.org/release/xen/$pkgver/xen-$pkgver.tar.gz xsa249.patch xsa250.patch xsa251-4.8.patch + xsa252-4.9.patch + xsa255-4.9-1.patch + xsa255-4.9-2.patch + xsa256-4.8.patch 0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch 0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch @@ -469,6 +477,10 @@ b00f42d2069f273e204698177d2c36950cee759a92dfe7833c812ddff4dedde2c4a842980927ec4f 05a2e954bab1877500eb5ed3a8c49edb27411ed3ec9dbfb2115b7804a3b03c6d45c9f08a7ed96ff2b586346f321142065a8c5a5d996468496b373637b6ee31b9 xsa249.patch b3030f09ddb4f9e4a356519c7b74d393e8db085278a1e616788c81d19988699a6efdd8568277c25514f3298ca92e5a09e3cd08b0a308a4d2ddb55374a8445657 xsa250.patch 22ac1c788e5c4c6b03e4d6c04ef97819fda4d5fb22015aa3a79d2f9a7dbac050f0b516401c0392c237576087306a810155a2dcdc6918d3de46f1ceb06b0b8a25 xsa251-4.8.patch +993febe7ac7d4add0f36a519fe461a40d32f16e23003dfb23e76883ecdd86474cd4a6f9d0a9190cc6bc8cad19afa652556f125a5d5edb4fa2e9f2e6a5e77b2b9 xsa252-4.9.patch +3af678f3c4271da2bb1515b9a1e76d9b85b391fbb1e9cd521c66ac52d2984a15c6c1bb6fa8a1f408380e4c7462b1ef671f77245fee6eecef274f93ca47bc12bd xsa255-4.9-1.patch +22bf18c5e0120d787c9ec04d10dfb4684a0849c5d7a80cbe400f8f2ee2ee64789c9e6fe5bedab579ca4928f3168f7a5c0c817f93c73ad1cf7ce702a4afe732ab xsa255-4.9-2.patch +82d75a5711c6a0521ecd34b220e4830b169aef8a52edf98b3b93e27ece734751d8d47dfdbe6979b6518c683e3f0c623cbf344a5efd893f3fafcc06c8e89a5320 xsa256-4.8.patch c2b4a036bc9f0b43be40fb52e846bac2aa812f193acd2d58edb074b3a38b65dbb52a133150e574bd6e324fc4c93dc19ae5bafceeef44bd8c3610fd8a0b07072d 0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch 90746468ac83794e1e27fbf9bfb0d7f60ca0b85ceda0561f61f5ec328e2ea1428cc7ede7f1dca4e5a3398a7c27a46d6f9f0d2183c3b71e8ec1ac3ea2833a6a04 0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch 287d03637f5ff35b0ec27af268a6f750be0341dd51d40266f17d4581eba9a285dafef65e5420c4f8a8e21ffce98057d8fe0bff1e7008d5df21defd7448c6fb37 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-4.8.patch b/main/xen/xsa256-4.8.patch new file mode 100644 index 0000000000..019e6e6b97 --- /dev/null +++ b/main/xen/xsa256-4.8.patch @@ -0,0 +1,46 @@ +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 8817263..91b9ab7 100644 +--- a/xen/arch/x86/domain.c ++++ b/xen/arch/x86/domain.c +@@ -557,11 +557,9 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags, + return -EINVAL; + } + +- /* PVHv2 guests can request emulated APIC. */ +- if ( emflags && +- (is_hvm_domain(d) ? ((emflags != XEN_X86_EMU_ALL) && +- (emflags != XEN_X86_EMU_LAPIC)) : +- (emflags != XEN_X86_EMU_PIT)) ) ++ if ( is_hvm_domain(d) ? ((emflags != XEN_X86_EMU_ALL) && ++ (emflags != XEN_X86_EMU_LAPIC)) ++ : (emflags && emflags != XEN_X86_EMU_PIT) ) + { + printk(XENLOG_G_ERR "d%d: Xen does not allow %s domain creation " + "with the current selection of emulators: %#x\n", |