diff options
author | Leonardo Arena <rnalrd@alpinelinux.org> | 2018-03-06 12:31:09 +0000 |
---|---|---|
committer | Leonardo Arena <rnalrd@alpinelinux.org> | 2018-03-06 12:31:18 +0000 |
commit | 1fb3325abc8bc3f37fa93c0663908c29e9154087 (patch) | |
tree | 54b27d3ec068a4bbd647b5afe89f9f45eb5af43c /main | |
parent | 44ec7e4406170dec0bcab3fc699115efa72fb094 (diff) | |
download | aports-1fb3325abc8bc3f37fa93c0663908c29e9154087.tar.bz2 aports-1fb3325abc8bc3f37fa93c0663908c29e9154087.tar.xz |
main/xen: security fixes
Diffstat (limited to 'main')
-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.patch | 40 |
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; + } |