X-Original-To: alpine-aports@lists.alpinelinux.org Received: from mail-qk0-f173.google.com (mail-qk0-f173.google.com [209.85.220.173]) by lists.alpinelinux.org (Postfix) with ESMTP id 1C8445C55EC for ; Tue, 12 Sep 2017 21:19:29 +0000 (GMT) Received: by mail-qk0-f173.google.com with SMTP id z143so27978456qkb.3 for ; Tue, 12 Sep 2017 14:19:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=RWyRkWjdtSxNKkzzSh/rdVgDT234hQg/bvZRj4fqqL0=; b=Buv5JFZ4KMo1FV8Kum3bx+EkpnTT1SI8vGp9JesgDBCk+zKY1VxiEtuk8I5sNAw/tu Yj5HqKbxICWP9bs68edQROi6tuHc1HuLm3HI+oWv5puR2fjsM+ksWSe2jUGuIFBKKUyS J3bL4S+qyc9McJelM796euwN7nXdKkFgVGKk8mIBEvWwyPdVBUNzZLXSUYP69tDde4AM tPCPkiQqHr2ODPeM1Ezm/oc3zWz7u+wYzM4W1hRLgYPuwL5iTLFA57E7FPXxuC85KmRq F6SA6s+AlclKttdN1VKLfSx4S4HQBJfVrgyAsadqvW40fGqqETUAWASiO1Z9xh8oKhd6 YUzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=RWyRkWjdtSxNKkzzSh/rdVgDT234hQg/bvZRj4fqqL0=; b=Ql/hB5PIGx/9r1McAzQR97eATPi06NKGvl2kN5y9Gwh0YP2YMjzYi0TaM07dXe8V1l zWsrSGNzkTxstm3E1S604BjCngrz71FwwDnmJtV+z21ecymtpVlqFsiPQZ4NrObMYcX2 FgXaNANdFjSx2WBeCH9mEvR92HAUUw3MudKUK/lgtMznRAcretd+CZr5XQbdKrrN93gW oDYDBrsaUb9seDYdIL8WiBDP8hMX1eEAAicHb06Uyq2IQa2Qpq78SqN+kv9ZmW8evcNi 6tRlr1Pta7BHsUiN0YzAX2ektcqies8L/4roJXlVlvUCj4puO/cWeBwj2gLc33qude2Y WMpQ== X-Gm-Message-State: AHPjjUhsv6+vDXw5njBafwra9eAnzz2vI2Sge5bJOOGJjAbWKSE4wcVQ WOPK7h3lU9WAIQWv X-Google-Smtp-Source: AOwi7QAXh5xtXU4O9zf4RmKfv+O+lJLVsoyX6FQGko3KLOtl6sdeZ/pM6B+NLM2d6UK8tB2HZfOdig== X-Received: by 10.55.10.76 with SMTP id 73mr20632772qkk.205.1505251168161; Tue, 12 Sep 2017 14:19:28 -0700 (PDT) Received: from localhost.localdomain (c-71-60-35-21.hsd1.pa.comcast.net. [71.60.35.21]) by smtp.googlemail.com with ESMTPSA id n34sm6096237qtf.10.2017.09.12.14.19.27 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Sep 2017 14:19:27 -0700 (PDT) From: Daniel Sabogal To: alpine-aports@lists.alpinelinux.org Subject: [alpine-aports] [PATCH] main/xen: security fixes (XSA-231, XSA-232, XSA-233, XSA-234) Date: Tue, 12 Sep 2017 17:21:02 -0400 Message-Id: <20170912212102.11403-2-dsabogalcc@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170912212102.11403-1-dsabogalcc@gmail.com> References: <20170912212102.11403-1-dsabogalcc@gmail.com> X-Mailinglist: alpine-aports Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: CVE-2017-14316 XSA-231 CVE-2017-14318 XSA-232 CVE-2017-14317 XSA-233 CVE-2017-14319 XSA-234 --- main/xen/APKBUILD | 15 +++- main/xen/xsa231-4.9.patch | 108 ++++++++++++++++++++++++++ main/xen/xsa232.patch | 23 ++++++ main/xen/xsa233.patch | 52 +++++++++++++ main/xen/xsa234-4.9.patch | 192 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 main/xen/xsa231-4.9.patch create mode 100644 main/xen/xsa232.patch create mode 100644 main/xen/xsa233.patch create mode 100644 main/xen/xsa234-4.9.patch diff --git a/main/xen/APKBUILD b/main/xen/APKBUILD index 3dacbf1ea1..68fcb0a156 100644 --- a/main/xen/APKBUILD +++ b/main/xen/APKBUILD @@ -3,7 +3,7 @@ # Maintainer: William Pitcock pkgname=xen pkgver=4.9.0 -pkgrel=3 +pkgrel=4 pkgdesc="Xen hypervisor" url="http://www.xen.org/" arch="x86_64 armhf aarch64" @@ -80,6 +80,11 @@ options="!strip" # - CVE-2017-12855 XSA-230 # 4.9.0-r2: # - XSA-235 +# 4.9.0-r4: +# - CVE-2017-14316 XSA-231 +# - CVE-2017-14318 XSA-232 +# - CVE-2017-14317 XSA-233 +# - CVE-2017-14319 XSA-234 case "$CARCH" in x86*) @@ -132,6 +137,10 @@ source="https://downloads.xenproject.org/release/$pkgname/$pkgver/$pkgname-$pkgv xsa227.patch xsa228.patch xsa230.patch + xsa231-4.9.patch + xsa232.patch + xsa233.patch + xsa234-4.9.patch xsa235-4.9.patch qemu-coroutine-gthread.patch @@ -390,6 +399,10 @@ c2bc9ffc8583aeae71cee9ddcc4418969768d4e3764d47307da54f93981c0109fb07d84b061b3a36 7d66494e833d46f8a213af0f2b107a12617d5e8b45c3b07daee229c75bd6aad98284bc0e19f15706d044b58273cc7f0c193ef8553faa22fadeae349689e763c8 xsa227.patch d406f14531af707325790909d08ce299ac2f2cb4b87f9a8ddb0fba10bd83bed84cc1633e07632cc2f841c50bc1a9af6240c89539a2e6ba6028cb127e218f86fc xsa228.patch df174a1675f74b73e78bc3cb1c9f16536199dfd1922c0cc545a807e92bc24941a816891838258e118f477109548487251a7eaccb2d1dd9b6994c8c76fc5b058f xsa230.patch +7ef6637112c3d24a3541d40ca79b8d5ed8a152401c8b7bfa4cde3e2e264544ba22d27c199d58f24616af2228f5e4075c2af2744d21a70b8cb4d4b1f1a7feedde xsa231-4.9.patch +fb742225a4f3dbf2a574c4a6e3ef61a5da0c91aaeed77a2247023bdefcd4e0b6c08f1c9ffb42eaac3d38739c401443c3cf7aebb507b1d779c415b6cbffabbc10 xsa232.patch +a322ac6c5ac2f858a59096108032fd42974eaaeeebd8f4966119149665f32bed281e333e743136e79add2e6f3844d88b6a3e4d5a685c2808702fd3a9e6396cd4 xsa233.patch +cafeef137cd82cefc3e974b42b974c6562e822c9b359efb654ac374e663d9fc123be210eec17b278f40eabb77c93d3bf0ff03e445607159ad0712808a609a906 xsa234-4.9.patch 8bab6e59577b51f0c6b8a547c9a37a257bd0460e7219512e899d25f80a74084745d2a4c54e55ad12526663d40f218cb8f833b71350220d36e3750d002ff43d29 xsa235-4.9.patch c3c46f232f0bd9f767b232af7e8ce910a6166b126bd5427bb8dc325aeb2c634b956de3fc225cab5af72649070c8205cc8e1cab7689fc266c204f525086f1a562 qemu-coroutine-gthread.patch 1936ab39a1867957fa640eb81c4070214ca4856a2743ba7e49c0cd017917071a9680d015f002c57fa7b9600dbadd29dcea5887f50e6c133305df2669a7a933f3 qemu-xen_paths.patch diff --git a/main/xen/xsa231-4.9.patch b/main/xen/xsa231-4.9.patch new file mode 100644 index 0000000000..251165e6bd --- /dev/null +++ b/main/xen/xsa231-4.9.patch @@ -0,0 +1,108 @@ +From: George Dunlap +Subject: xen/mm: make sure node is less than MAX_NUMNODES + +The output of MEMF_get_node(memflags) can be as large as nodeid_t can +hold (currently 255). This is then used as an index to arrays of size +MAX_NUMNODE, which is 64 on x86 and 1 on ARM, can be passed in by an +untrusted guest (via memory_exchange and increase_reservation) and is +not currently bounds-checked. + +Check the value in page_alloc.c before using it, and also check the +value in the hypercall call sites and return -EINVAL if appropriate. +Don't permit domains other than the hardware or control domain to +allocate node-constrained memory. + +This is XSA-231. + +Reported-by: Matthew Daley +Signed-off-by: George Dunlap +Signed-off-by: Jan Beulich +Reviewed-by: Andrew Cooper + +--- a/xen/common/memory.c ++++ b/xen/common/memory.c +@@ -411,6 +411,31 @@ static void decrease_reservation(struct + a->nr_done = i; + } + ++static bool propagate_node(unsigned int xmf, unsigned int *memflags) ++{ ++ const struct domain *currd = current->domain; ++ ++ BUILD_BUG_ON(XENMEMF_get_node(0) != NUMA_NO_NODE); ++ BUILD_BUG_ON(MEMF_get_node(0) != NUMA_NO_NODE); ++ ++ if ( XENMEMF_get_node(xmf) == NUMA_NO_NODE ) ++ return true; ++ ++ if ( is_hardware_domain(currd) || is_control_domain(currd) ) ++ { ++ if ( XENMEMF_get_node(xmf) >= MAX_NUMNODES ) ++ return false; ++ ++ *memflags |= MEMF_node(XENMEMF_get_node(xmf)); ++ if ( xmf & XENMEMF_exact_node_request ) ++ *memflags |= MEMF_exact_node; ++ } ++ else if ( xmf & XENMEMF_exact_node_request ) ++ return false; ++ ++ return true; ++} ++ + static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg) + { + struct xen_memory_exchange exch; +@@ -483,6 +508,12 @@ static long memory_exchange(XEN_GUEST_HA + } + } + ++ if ( unlikely(!propagate_node(exch.out.mem_flags, &memflags)) ) ++ { ++ rc = -EINVAL; ++ goto fail_early; ++ } ++ + d = rcu_lock_domain_by_any_id(exch.in.domid); + if ( d == NULL ) + { +@@ -501,7 +532,6 @@ static long memory_exchange(XEN_GUEST_HA + d, + XENMEMF_get_address_bits(exch.out.mem_flags) ? : + (BITS_PER_LONG+PAGE_SHIFT))); +- memflags |= MEMF_node(XENMEMF_get_node(exch.out.mem_flags)); + + for ( i = (exch.nr_exchanged >> in_chunk_order); + i < (exch.in.nr_extents >> in_chunk_order); +@@ -864,12 +894,8 @@ static int construct_memop_from_reservat + } + read_unlock(&d->vnuma_rwlock); + } +- else +- { +- a->memflags |= MEMF_node(XENMEMF_get_node(r->mem_flags)); +- if ( r->mem_flags & XENMEMF_exact_node_request ) +- a->memflags |= MEMF_exact_node; +- } ++ else if ( unlikely(!propagate_node(r->mem_flags, &a->memflags)) ) ++ return -EINVAL; + + return 0; + } +--- a/xen/common/page_alloc.c ++++ b/xen/common/page_alloc.c +@@ -706,9 +706,13 @@ static struct page_info *alloc_heap_page + if ( node >= MAX_NUMNODES ) + node = cpu_to_node(smp_processor_id()); + } ++ else if ( unlikely(node >= MAX_NUMNODES) ) ++ { ++ ASSERT_UNREACHABLE(); ++ return NULL; ++ } + first_node = node; + +- ASSERT(node < MAX_NUMNODES); + ASSERT(zone_lo <= zone_hi); + ASSERT(zone_hi < NR_ZONES); + diff --git a/main/xen/xsa232.patch b/main/xen/xsa232.patch new file mode 100644 index 0000000000..9e5f35c7d6 --- /dev/null +++ b/main/xen/xsa232.patch @@ -0,0 +1,23 @@ +From: Andrew Cooper +Subject: grant_table: fix GNTTABOP_cache_flush handling + +Don't fall over a NULL grant_table pointer when the owner of the domain +is a system domain (DOMID_{XEN,IO} etc). + +This is XSA-232. + +Reported-by: Matthew Daley +Signed-off-by: Andrew Cooper +Reviewed-by: Jan Beulich + +--- a/xen/common/grant_table.c ++++ b/xen/common/grant_table.c +@@ -3053,7 +3053,7 @@ static int cache_flush(gnttab_cache_flus + + page = mfn_to_page(mfn); + owner = page_get_owner_and_reference(page); +- if ( !owner ) ++ if ( !owner || !owner->grant_table ) + { + rcu_unlock_domain(d); + return -EPERM; diff --git a/main/xen/xsa233.patch b/main/xen/xsa233.patch new file mode 100644 index 0000000000..6013c52b41 --- /dev/null +++ b/main/xen/xsa233.patch @@ -0,0 +1,52 @@ +From: Juergen Gross +Subject: tools/xenstore: dont unlink connection object twice + +A connection object of a domain with associated stubdom has two +parents: the domain and the stubdom. When cleaning up the list of +active domains in domain_cleanup() make sure not to unlink the +connection twice from the same domain. This could happen when the +domain and its stubdom are being destroyed at the same time leading +to the domain loop being entered twice. + +Additionally don't use talloc_free() in this case as it will remove +a random parent link, leading eventually to a memory leak. Use +talloc_unlink() instead specifying the context from which the +connection object should be removed. + +This is XSA-233. + +Reported-by: Eric Chanudet +Signed-off-by: Juergen Gross +Reviewed-by: Ian Jackson + +--- a/tools/xenstore/xenstored_domain.c ++++ b/tools/xenstore/xenstored_domain.c +@@ -221,10 +221,11 @@ static int destroy_domain(void *_domain) + static void domain_cleanup(void) + { + xc_dominfo_t dominfo; +- struct domain *domain, *tmp; ++ struct domain *domain; + int notify = 0; + +- list_for_each_entry_safe(domain, tmp, &domains, list) { ++ again: ++ list_for_each_entry(domain, &domains, list) { + if (xc_domain_getinfo(*xc_handle, domain->domid, 1, + &dominfo) == 1 && + dominfo.domid == domain->domid) { +@@ -236,8 +237,12 @@ static void domain_cleanup(void) + if (!dominfo.dying) + continue; + } +- talloc_free(domain->conn); +- notify = 0; /* destroy_domain() fires the watch */ ++ if (domain->conn) { ++ talloc_unlink(talloc_autofree_context(), domain->conn); ++ domain->conn = NULL; ++ notify = 0; /* destroy_domain() fires the watch */ ++ goto again; ++ } + } + + if (notify) diff --git a/main/xen/xsa234-4.9.patch b/main/xen/xsa234-4.9.patch new file mode 100644 index 0000000000..8dbf401720 --- /dev/null +++ b/main/xen/xsa234-4.9.patch @@ -0,0 +1,192 @@ +From: Jan Beulich +Subject: gnttab: also validate PTE permissions upon destroy/replace + +In order for PTE handling to match up with the reference counting done +by common code, presence and writability of grant mapping PTEs must +also be taken into account; validating just the frame number is not +enough. This is in particular relevant if a guest fiddles with grant +PTEs via non-grant hypercalls. + +Note that the flags being passed to replace_grant_host_mapping() +already happen to be those of the existing mapping, so no new function +parameter is needed. + +This is XSA-234. + +Reported-by: Andrew Cooper +Signed-off-by: Jan Beulich +Reviewed-by: Andrew Cooper + +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c +@@ -4058,7 +4058,8 @@ static int create_grant_pte_mapping( + } + + static int destroy_grant_pte_mapping( +- uint64_t addr, unsigned long frame, struct domain *d) ++ uint64_t addr, unsigned long frame, unsigned int grant_pte_flags, ++ struct domain *d) + { + int rc = GNTST_okay; + void *va; +@@ -4104,17 +4105,29 @@ static int destroy_grant_pte_mapping( + + ol1e = *(l1_pgentry_t *)va; + +- /* Check that the virtual address supplied is actually mapped to frame. */ +- if ( unlikely(l1e_get_pfn(ol1e) != frame) ) ++ /* ++ * Check that the PTE supplied actually maps frame (with appropriate ++ * permissions). ++ */ ++ if ( unlikely(l1e_get_pfn(ol1e) != frame) || ++ unlikely((l1e_get_flags(ol1e) ^ grant_pte_flags) & ++ (_PAGE_PRESENT | _PAGE_RW)) ) + { + page_unlock(page); +- gdprintk(XENLOG_WARNING, +- "PTE entry %"PRIpte" for address %"PRIx64" doesn't match frame %lx\n", +- l1e_get_intpte(ol1e), addr, frame); ++ gdprintk(XENLOG_ERR, ++ "PTE %"PRIpte" at %"PRIx64" doesn't match grant (%"PRIpte")\n", ++ l1e_get_intpte(ol1e), addr, ++ l1e_get_intpte(l1e_from_pfn(frame, grant_pte_flags))); + rc = GNTST_general_error; + goto failed; + } + ++ if ( unlikely((l1e_get_flags(ol1e) ^ grant_pte_flags) & ++ ~(_PAGE_AVAIL | PAGE_CACHE_ATTRS)) ) ++ gdprintk(XENLOG_WARNING, ++ "PTE flags %x at %"PRIx64" don't match grant (%x)\n", ++ l1e_get_flags(ol1e), addr, grant_pte_flags); ++ + /* Delete pagetable entry. */ + if ( unlikely(!UPDATE_ENTRY + (l1, +@@ -4123,7 +4136,8 @@ static int destroy_grant_pte_mapping( + 0)) ) + { + page_unlock(page); +- gdprintk(XENLOG_WARNING, "Cannot delete PTE entry at %p\n", va); ++ gdprintk(XENLOG_WARNING, "Cannot delete PTE entry at %"PRIx64"\n", ++ addr); + rc = GNTST_general_error; + goto failed; + } +@@ -4191,7 +4205,8 @@ static int create_grant_va_mapping( + } + + static int replace_grant_va_mapping( +- unsigned long addr, unsigned long frame, l1_pgentry_t nl1e, struct vcpu *v) ++ unsigned long addr, unsigned long frame, unsigned int grant_pte_flags, ++ l1_pgentry_t nl1e, struct vcpu *v) + { + l1_pgentry_t *pl1e, ol1e; + unsigned long gl1mfn; +@@ -4227,20 +4242,33 @@ static int replace_grant_va_mapping( + + ol1e = *pl1e; + +- /* Check that the virtual address supplied is actually mapped to frame. */ +- if ( unlikely(l1e_get_pfn(ol1e) != frame) ) +- { +- gdprintk(XENLOG_WARNING, +- "PTE entry %lx for address %lx doesn't match frame %lx\n", +- l1e_get_pfn(ol1e), addr, frame); ++ /* ++ * Check that the virtual address supplied is actually mapped to frame ++ * (with appropriate permissions). ++ */ ++ if ( unlikely(l1e_get_pfn(ol1e) != frame) || ++ unlikely((l1e_get_flags(ol1e) ^ grant_pte_flags) & ++ (_PAGE_PRESENT | _PAGE_RW)) ) ++ { ++ gdprintk(XENLOG_ERR, ++ "PTE %"PRIpte" for %lx doesn't match grant (%"PRIpte")\n", ++ l1e_get_intpte(ol1e), addr, ++ l1e_get_intpte(l1e_from_pfn(frame, grant_pte_flags))); + rc = GNTST_general_error; + goto unlock_and_out; + } + ++ if ( unlikely((l1e_get_flags(ol1e) ^ grant_pte_flags) & ++ ~(_PAGE_AVAIL | PAGE_CACHE_ATTRS)) ) ++ gdprintk(XENLOG_WARNING, ++ "PTE flags %x for %"PRIx64" don't match grant (%x)\n", ++ l1e_get_flags(ol1e), addr, grant_pte_flags); ++ + /* Delete pagetable entry. */ + if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, v, 0)) ) + { +- gdprintk(XENLOG_WARNING, "Cannot delete PTE entry at %p\n", pl1e); ++ gdprintk(XENLOG_WARNING, "Cannot delete PTE entry for %"PRIx64"\n", ++ addr); + rc = GNTST_general_error; + goto unlock_and_out; + } +@@ -4254,9 +4282,11 @@ static int replace_grant_va_mapping( + } + + static int destroy_grant_va_mapping( +- unsigned long addr, unsigned long frame, struct vcpu *v) ++ unsigned long addr, unsigned long frame, unsigned int grant_pte_flags, ++ struct vcpu *v) + { +- return replace_grant_va_mapping(addr, frame, l1e_empty(), v); ++ return replace_grant_va_mapping(addr, frame, grant_pte_flags, ++ l1e_empty(), v); + } + + static int create_grant_p2m_mapping(uint64_t addr, unsigned long frame, +@@ -4351,20 +4381,39 @@ int replace_grant_host_mapping( + unsigned long gl1mfn; + struct page_info *l1pg; + int rc; ++ unsigned int grant_pte_flags; + + if ( paging_mode_external(current->domain) ) + return replace_grant_p2m_mapping(addr, frame, new_addr, flags); + ++ grant_pte_flags = ++ _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_GNTTAB | _PAGE_NX; ++ ++ if ( flags & GNTMAP_application_map ) ++ grant_pte_flags |= _PAGE_USER; ++ if ( !(flags & GNTMAP_readonly) ) ++ grant_pte_flags |= _PAGE_RW; ++ /* ++ * On top of the explicit settings done by create_grant_host_mapping() ++ * also open-code relevant parts of adjust_guest_l1e(). Don't mirror ++ * available and cachability flags, though. ++ */ ++ if ( !is_pv_32bit_domain(curr->domain) ) ++ grant_pte_flags |= (grant_pte_flags & _PAGE_USER) ++ ? _PAGE_GLOBAL ++ : _PAGE_GUEST_KERNEL | _PAGE_USER; ++ + if ( flags & GNTMAP_contains_pte ) + { + if ( !new_addr ) +- return destroy_grant_pte_mapping(addr, frame, curr->domain); ++ return destroy_grant_pte_mapping(addr, frame, grant_pte_flags, ++ curr->domain); + + return GNTST_general_error; + } + + if ( !new_addr ) +- return destroy_grant_va_mapping(addr, frame, curr); ++ return destroy_grant_va_mapping(addr, frame, grant_pte_flags, curr); + + pl1e = guest_map_l1e(new_addr, &gl1mfn); + if ( !pl1e ) +@@ -4412,7 +4461,7 @@ int replace_grant_host_mapping( + put_page(l1pg); + guest_unmap_l1e(pl1e); + +- rc = replace_grant_va_mapping(addr, frame, ol1e, curr); ++ rc = replace_grant_va_mapping(addr, frame, grant_pte_flags, ol1e, curr); + if ( rc && !paging_mode_refcounts(curr->domain) ) + put_page_from_l1e(ol1e, curr->domain); + -- 2.14.1 --- Unsubscribe: alpine-aports+unsubscribe@lists.alpinelinux.org Help: alpine-aports+help@lists.alpinelinux.org ---