head 1.2; access; symbols pkgsrc-2017Q4:1.1.0.4 pkgsrc-2017Q4-base:1.1 pkgsrc-2017Q3:1.1.0.2; locks; strict; comment @# @; 1.2 date 2018.01.24.23.29.32; author bouyer; state dead; branches; next 1.1; commitid WktdwS8UoS8bvboA; 1.1 date 2017.10.17.08.42.30; author bouyer; state Exp; branches 1.1.2.1 1.1.4.1; next ; commitid OJpItiWkoMToMnbA; 1.1.2.1 date 2017.10.17.08.42.30; author bsiegert; state dead; branches; next 1.1.2.2; commitid fTgNkUKfFJMQdrbA; 1.1.2.2 date 2017.10.17.19.02.25; author bsiegert; state Exp; branches; next ; commitid fTgNkUKfFJMQdrbA; 1.1.4.1 date 2018.01.28.15.23.24; author bsiegert; state dead; branches; next ; commitid hLOFEOUtck6sHEoA; desc @@ 1.2 log @Update xen 4.8 packages to 4.8.3. Changes since 4.8.2: include patches from all security advisory up to and including XSA254. While there pass XEN_VENDORVERSION=nb${PKGREVISION} to make so that 'xl info' shows the NetBSD PKGREVISION. If PKGREVISION is not available, define this as 'nb0'. @ text @$NetBSD: patch-XSA234,v 1.1 2017/10/17 08:42:30 bouyer Exp $ 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 --- xen/arch/x86/mm.c.orig +++ xen/arch/x86/mm.c @@@@ -4017,7 +4017,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; @@@@ -4063,16 +4064,27 @@@@ 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); - MEM_LOG("PTE entry %lx for address %"PRIx64" doesn't match frame %lx", - (unsigned long)l1e_get_intpte(ol1e), addr, frame); + MEM_LOG("PTE %"PRIpte" at %"PRIx64" doesn't match grant (%"PRIpte")", + 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)) ) + MEM_LOG("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, @@@@ -4081,7 +4093,7 @@@@ static int destroy_grant_pte_mapping( 0)) ) { page_unlock(page); - MEM_LOG("Cannot delete PTE entry at %p", va); + MEM_LOG("Cannot delete PTE entry at %"PRIx64, addr); rc = GNTST_general_error; goto failed; } @@@@ -4149,7 +4161,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; @@@@ -4185,19 +4198,30 @@@@ 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) ) - { - MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx", - 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)) ) + { + MEM_LOG("PTE %"PRIpte" for %lx doesn't match grant (%"PRIpte")", + 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)) ) + MEM_LOG("PTE flags %x for %"PRIx64" don't match grant (%x)", + l1e_get_flags(ol1e), addr, grant_pte_flags); + /* Delete pagetable entry. */ if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, v, 0)) ) { - MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e); + MEM_LOG("Cannot delete PTE entry for %"PRIx64, addr); rc = GNTST_general_error; goto unlock_and_out; } @@@@ -4211,9 +4235,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, @@@@ -4307,21 +4333,40 @@@@ 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); MEM_LOG("Unsupported grant table operation"); 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 ) @@@@ -4369,7 +4414,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); @ 1.1 log @Update xentools48 and xenkernel48 to 4.8.2, and apply security patches up to XSA244. Keep PKGREVISION to 1 to account for the fact that it's not a stock Xen 4.8.2. Note that, unlike upstream, pv-linear-pt defaults to true, so that NetBSD PV guests (including dom0) will continue to boot without changes to boot.cfg @ text @d1 1 a1 1 $NetBSD: $ @ 1.1.4.1 log @Pullup ticket #5693 - requested by bouyer sysutils/xenkernel48: security fix sysutils/xentools48: security fix Revisions pulled up: - sysutils/xenkernel48/Makefile 1.12 - sysutils/xenkernel48/distinfo 1.6 - sysutils/xenkernel48/patches/patch-XSA231 deleted - sysutils/xenkernel48/patches/patch-XSA232 deleted - sysutils/xenkernel48/patches/patch-XSA234 deleted - sysutils/xenkernel48/patches/patch-XSA237 deleted - sysutils/xenkernel48/patches/patch-XSA238 deleted - sysutils/xenkernel48/patches/patch-XSA239 deleted - sysutils/xenkernel48/patches/patch-XSA240 deleted - sysutils/xenkernel48/patches/patch-XSA241 deleted - sysutils/xenkernel48/patches/patch-XSA242 deleted - sysutils/xenkernel48/patches/patch-XSA243 deleted - sysutils/xenkernel48/patches/patch-XSA244 deleted - sysutils/xenkernel48/patches/patch-XSA246 deleted - sysutils/xenkernel48/patches/patch-XSA247 deleted - sysutils/xenkernel48/patches/patch-XSA248 deleted - sysutils/xenkernel48/patches/patch-XSA249 deleted - sysutils/xenkernel48/patches/patch-XSA250 deleted - sysutils/xenkernel48/patches/patch-XSA251 deleted - sysutils/xenkernel48/patches/patch-XSA254-1 deleted - sysutils/xenkernel48/patches/patch-XSA254-2 deleted - sysutils/xenkernel48/patches/patch-XSA254-3 deleted - sysutils/xenkernel48/patches/patch-XSA254-4 deleted - sysutils/xentools48/Makefile 1.16 - sysutils/xentools48/distinfo 1.7-1.8 - sysutils/xentools48/patches/patch-XSA233 deleted - sysutils/xentools48/patches/patch-XSA240 deleted --- Module Name: pkgsrc Committed By: bouyer Date: Wed Jan 24 23:29:33 UTC 2018 Modified Files: pkgsrc/sysutils/xenkernel48: Makefile distinfo pkgsrc/sysutils/xentools48: Makefile distinfo Removed Files: pkgsrc/sysutils/xenkernel48/patches: patch-XSA231 patch-XSA232 patch-XSA234 patch-XSA237 patch-XSA238 patch-XSA239 patch-XSA240 patch-XSA241 patch-XSA242 patch-XSA243 patch-XSA244 patch-XSA246 patch-XSA247 patch-XSA248 patch-XSA249 patch-XSA250 patch-XSA251 patch-XSA254-1 patch-XSA254-2 patch-XSA254-3 patch-XSA254-4 pkgsrc/sysutils/xentools48/patches: patch-XSA233 patch-XSA240 Log Message: Update xen 4.8 packages to 4.8.3. Changes since 4.8.2: include patches from all security advisory up to and including XSA254. While there pass XEN_VENDORVERSION=nb${PKGREVISION} to make so that 'xl info' shows the NetBSD PKGREVISION. If PKGREVISION is not available, define this as 'nb0'. --- Module Name: pkgsrc Committed By: bouyer Date: Sat Jan 27 16:44:40 UTC 2018 Modified Files: pkgsrc/sysutils/xentools48: distinfo Log Message: Remove entries for patch-XSA233 and patch-XSA240 which have been deleted. @ text @d1 1 a1 1 $NetBSD: patch-XSA234,v 1.1 2017/10/17 08:42:30 bouyer Exp $ @ 1.1.2.1 log @file patch-XSA234 was added on branch pkgsrc-2017Q3 on 2017-10-17 19:02:25 +0000 @ text @d1 187 @ 1.1.2.2 log @Pullup ticket #5579 - requested by bouyer sysutils/xenkernel48, sysutils/xentools48: security fix Revisions pulled up: - sysutils/xenkernel48/MESSAGE 1.2 - sysutils/xenkernel48/Makefile 1.6 - sysutils/xenkernel48/distinfo 1.3 - sysutils/xenkernel48/patches/patch-XSA-212 deleted - sysutils/xenkernel48/patches/patch-XSA231 1.1 - sysutils/xenkernel48/patches/patch-XSA232 1.1 - sysutils/xenkernel48/patches/patch-XSA234 1.1 - sysutils/xenkernel48/patches/patch-XSA237 1.1 - sysutils/xenkernel48/patches/patch-XSA238 1.1 - sysutils/xenkernel48/patches/patch-XSA239 1.1 - sysutils/xenkernel48/patches/patch-XSA240 1.1 - sysutils/xenkernel48/patches/patch-XSA241 1.1 - sysutils/xenkernel48/patches/patch-XSA242 1.1 - sysutils/xenkernel48/patches/patch-XSA243 1.1 - sysutils/xenkernel48/patches/patch-XSA244 1.1 - sysutils/xentools48/Makefile 1.8 - sysutils/xentools48/distinfo 1.4 - sysutils/xentools48/patches/patch-XSA-211-1 deleted - sysutils/xentools48/patches/patch-XSA-211-2 deleted - sysutils/xentools48/patches/patch-XSA233 1.1 - sysutils/xentools48/patches/patch-XSA240 1.1 --- Module Name: pkgsrc Committed By: bouyer Date: Tue Oct 17 08:42:30 UTC 2017 Modified Files: pkgsrc/sysutils/xenkernel48: MESSAGE Makefile distinfo pkgsrc/sysutils/xentools48: Makefile distinfo Added Files: pkgsrc/sysutils/xenkernel48/patches: patch-XSA231 patch-XSA232 patch-XSA234 patch-XSA237 patch-XSA238 patch-XSA239 patch-XSA240 patch-XSA241 patch-XSA242 patch-XSA243 patch-XSA244 pkgsrc/sysutils/xentools48/patches: patch-XSA233 patch-XSA240 Removed Files: pkgsrc/sysutils/xenkernel48/patches: patch-XSA-212 pkgsrc/sysutils/xentools48/patches: patch-XSA-211-1 patch-XSA-211-2 Log Message: Update xentools48 and xenkernel48 to 4.8.2, and apply security patches up to XSA244. Keep PKGREVISION to 1 to account for the fact that it's not a stock Xen 4.8.2. Note that, unlike upstream, pv-linear-pt defaults to true, so that NetBSD PV guests (including dom0) will continue to boot without changes to boot.cfg @ text @a0 187 $NetBSD: patch-XSA234,v 1.1 2017/10/17 08:42:30 bouyer Exp $ 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 --- xen/arch/x86/mm.c.orig +++ xen/arch/x86/mm.c @@@@ -4017,7 +4017,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; @@@@ -4063,16 +4064,27 @@@@ 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); - MEM_LOG("PTE entry %lx for address %"PRIx64" doesn't match frame %lx", - (unsigned long)l1e_get_intpte(ol1e), addr, frame); + MEM_LOG("PTE %"PRIpte" at %"PRIx64" doesn't match grant (%"PRIpte")", + 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)) ) + MEM_LOG("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, @@@@ -4081,7 +4093,7 @@@@ static int destroy_grant_pte_mapping( 0)) ) { page_unlock(page); - MEM_LOG("Cannot delete PTE entry at %p", va); + MEM_LOG("Cannot delete PTE entry at %"PRIx64, addr); rc = GNTST_general_error; goto failed; } @@@@ -4149,7 +4161,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; @@@@ -4185,19 +4198,30 @@@@ 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) ) - { - MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx", - 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)) ) + { + MEM_LOG("PTE %"PRIpte" for %lx doesn't match grant (%"PRIpte")", + 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)) ) + MEM_LOG("PTE flags %x for %"PRIx64" don't match grant (%x)", + l1e_get_flags(ol1e), addr, grant_pte_flags); + /* Delete pagetable entry. */ if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, v, 0)) ) { - MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e); + MEM_LOG("Cannot delete PTE entry for %"PRIx64, addr); rc = GNTST_general_error; goto unlock_and_out; } @@@@ -4211,9 +4235,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, @@@@ -4307,21 +4333,40 @@@@ 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); MEM_LOG("Unsupported grant table operation"); 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 ) @@@@ -4369,7 +4414,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); @