Index: head/emulators/xen-kernel/Makefile =================================================================== --- head/emulators/xen-kernel/Makefile (revision 447986) +++ head/emulators/xen-kernel/Makefile (revision 447987) @@ -1,90 +1,94 @@ # $FreeBSD$ PORTNAME= xen PORTVERSION= 4.7.2 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= emulators MASTER_SITES= http://downloads.xenproject.org/release/xen/${PORTVERSION}/ PKGNAMESUFFIX= -kernel MAINTAINER= royger@FreeBSD.org COMMENT= Hypervisor using a microkernel design LICENSE= GPLv2 ONLY_FOR_ARCHS= amd64 USES= cpe gmake python:build # We need to use ld from ports because the version in base doesn't # support the '--build-id' switch that's needed for live hypervisor # hot-patching. Once the ld version in base supports this option the # dependency can be removed. # # GNU objcopy is used instead of elftc objcopy because of bug #533: # https://sourceforge.net/p/elftoolchain/tickets/533/ # Once this is solved we should be able to switch to elfcopy. # # And finally we also need to use nm from binutils because the one # from base cannot deal with i386pep binary files which is the format # of the Xen EFI image (note that FreeBSD cannot yet boot as Dom0 from EFI, # but the image is built anyway). This is reported to elftc as bug #534: # https://sourceforge.net/p/elftoolchain/tickets/534/ MAKE_ARGS= clang=y PYTHON=${PYTHON_CMD} LD="${LD}" OBJCOPY="${OBJCOPY}" \ NM="${NM}" USE_BINUTILS= yes NO_MTREE= yes STRIP= # PLIST_FILES= /boot/xen \ /boot/xen.4th EXTRA_PATCHES= ${FILESDIR}/0001-xen-logdirty-prevent-preemption-if-finished.patch:-p1 \ ${FILESDIR}/0002-xen-rework-paging_log_dirty_op-to-work-with-hvm-gues.patch:-p1 \ ${FILESDIR}/kconf_arch.patch:-p1 \ ${FILESDIR}/0001-x86-drop-unneeded-__packed-attributes.patch:-p1 \ ${FILESDIR}/0002-build-clang-fix-XSM-dummy-policy-when-using-clang-4..patch:-p1 \ ${FILESDIR}/xsa212.patch:-p1 \ ${FILESDIR}/xsa213-4.7.patch:-p1 \ ${FILESDIR}/xsa214.patch:-p1 \ ${FILESDIR}/xsa215.patch:-p1 \ ${FILESDIR}/xsa217.patch:-p1 \ ${FILESDIR}/0001-IOMMU-handle-IOMMU-mapping-and-unmapping-failures.patch:-p1 \ ${FILESDIR}/0002-gnttab-fix-unmap-pin-accounting-race.patch:-p1 \ ${FILESDIR}/0003-gnttab-Avoid-potential-double-put-of-maptrack-entry.patch:-p1 \ ${FILESDIR}/0004-gnttab-correct-maptrack-table-accesses.patch:-p1 \ ${FILESDIR}/xsa219-4.8.patch:-p1 \ ${FILESDIR}/xsa220-4.7.patch:-p1 \ ${FILESDIR}/xsa221.patch:-p1 \ ${FILESDIR}/xsa222-1-4.7.patch:-p1 \ ${FILESDIR}/xsa222-2-4.7.patch:-p1 \ ${FILESDIR}/0001-gnttab-Fix-handling-of-dev_bus_addr-during-unmap.patch:-p1 \ ${FILESDIR}/0002-gnttab-never-create-host-mapping-unless-asked-to.patch:-p1 \ ${FILESDIR}/0003-gnttab-correct-logic-to-get-page-references-during-m.patch:-p1 \ - ${FILESDIR}/0004-gnttab-__gnttab_unmap_common_complete-is-all-or-noth.patch:-p1 + ${FILESDIR}/0004-gnttab-__gnttab_unmap_common_complete-is-all-or-noth.patch:-p1 \ + ${FILESDIR}/xsa226-4.7.patch:-p1 \ + ${FILESDIR}/xsa227.patch:-p1 \ + ${FILESDIR}/xsa228-4.8.patch:-p1 \ + ${FILESDIR}/xsa230.patch:-p1 .include .if ${OPSYS} != FreeBSD IGNORE= only supported on FreeBSD .endif .if ${OSVERSION} < 1100055 IGNORE= only supported on recent FreeBSD 11 .endif pre-build: ${MAKE_CMD} -C ${WRKSRC}/xen defconfig ${MAKE_ARGS} # Enable hypervisor hot-patching. echo 'CONFIG_XSPLICE=y' >> ${WRKSRC}/xen/.config echo 'CONFIG_FAST_SYMBOL_LOOKUP=y' >> ${WRKSRC}/xen/.config # The ports native 'build' target cannot be used because it sets # CFLAGS, and that breaks the Xen build system. do-build: ${MAKE_CMD} -j${MAKE_JOBS_NUMBER} -C ${WRKSRC}/xen build ${MAKE_ARGS} do-install: ${MKDIR} ${STAGEDIR}/boot ${INSTALL_PROGRAM} ${WRKSRC}/xen/xen ${STAGEDIR}/boot ${INSTALL_DATA} ${FILESDIR}/xen.4th ${STAGEDIR}/boot .include Index: head/emulators/xen-kernel/files/xsa226-4.7.patch =================================================================== --- head/emulators/xen-kernel/files/xsa226-4.7.patch (nonexistent) +++ head/emulators/xen-kernel/files/xsa226-4.7.patch (revision 447987) @@ -0,0 +1,133 @@ +From: Andrew Cooper +Subject: grant_table: Default to v1, and disallow transitive grants + +The reference counting and locking discipline for transitive grants is broken. +Their use is therefore declared out of security support. + +This is XSA-226. + +Transitive grants are expected to be unconditionally available with grant +table v2. Hiding transitive grants alone is an ABI breakage for the guest. +Modern versions of Linux and the Windows PV drivers use grant table v1, but +older versions did use v2. + +In principle, disabling gnttab v2 entirely is the safer way to cause guests to +avoid using transitive grants. However, some older guests which defaulted to +using gnttab v2 don't tolerate falling back from v2 to v1 over migrate. + +This patch introduces a new command line option to control grant table +behaviour. One suboption allows a choice of the maximum grant table version +Xen will allow the guest to use, and defaults to v2. A different suboption +independently controls whether transitive grants can be used. + +The default case is: + + gnttab=max_ver:2 + +To disable gnttab v2 entirely, use: + + gnttab=max_ver:1 + +To allow gnttab v2 and transitive grants, use: + + gnttab=max_ver:2,transitive + +Reported-by: Jan Beulich +Signed-off-by: Andrew Cooper +diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown +index 73f5265..b792abf 100644 +--- a/docs/misc/xen-command-line.markdown ++++ b/docs/misc/xen-command-line.markdown +@@ -758,6 +758,22 @@ Controls EPT related features. + + Specify which console gdbstub should use. See **console**. + ++### gnttab ++> `= List of [ max_ver:, transitive ]` ++ ++> Default: `gnttab=max_ver:2,no-transitive` ++ ++Control various aspects of the grant table behaviour available to guests. ++ ++* `max_ver` Select the maximum grant table version to offer to guests. Valid ++version are 1 and 2. ++* `transitive` Permit or disallow the use of transitive grants. Note that the ++use of grant table v2 without transitive grants is an ABI breakage from the ++guests point of view. ++ ++*Warning:* ++Due to XSA-226, the use of transitive grants is outside of security support. ++ + ### gnttab\_max\_frames + > `= ` + +diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c +index f06b664..109c552 100644 +--- a/xen/common/grant_table.c ++++ b/xen/common/grant_table.c +@@ -50,6 +50,42 @@ integer_param("gnttab_max_nr_frames", max_nr_grant_frames); + unsigned int __read_mostly max_grant_frames; + integer_param("gnttab_max_frames", max_grant_frames); + ++static unsigned int __read_mostly opt_gnttab_max_version = 2; ++static bool_t __read_mostly opt_transitive_grants; ++ ++static void __init parse_gnttab(char *s) ++{ ++ char *ss; ++ ++ do { ++ ss = strchr(s, ','); ++ if ( ss ) ++ *ss = '\0'; ++ ++ if ( !strncmp(s, "max_ver:", 8) ) ++ { ++ long ver = simple_strtol(s + 8, NULL, 10); ++ ++ if ( ver >= 1 && ver <= 2 ) ++ opt_gnttab_max_version = ver; ++ } ++ else ++ { ++ bool_t val = !!strncmp(s, "no-", 3); ++ ++ if ( !val ) ++ s += 3; ++ ++ if ( !strcmp(s, "transitive") ) ++ opt_transitive_grants = val; ++ } ++ ++ s = ss + 1; ++ } while ( ss ); ++} ++ ++custom_param("gnttab", parse_gnttab); ++ + /* The maximum number of grant mappings is defined as a multiplier of the + * maximum number of grant table entries. This defines the multiplier used. + * Pretty arbitrary. [POLICY] +@@ -2188,6 +2224,10 @@ __acquire_grant_for_copy( + } + else if ( (shah->flags & GTF_type_mask) == GTF_transitive ) + { ++ if ( !opt_transitive_grants ) ++ PIN_FAIL(unlock_out_clear, GNTST_general_error, ++ "transitive grant disallowed by policy\n"); ++ + if ( !allow_transitive ) + PIN_FAIL(unlock_out_clear, GNTST_general_error, + "transitive grant when transitivity not allowed\n"); +@@ -3156,7 +3196,10 @@ do_grant_table_op( + } + case GNTTABOP_set_version: + { +- rc = gnttab_set_version(guest_handle_cast(uop, gnttab_set_version_t)); ++ if ( opt_gnttab_max_version == 1 ) ++ rc = -ENOSYS; /* Behave as before set_version was introduced. */ ++ else ++ rc = gnttab_set_version(guest_handle_cast(uop, gnttab_set_version_t)); + break; + } + case GNTTABOP_get_status_frames: Property changes on: head/emulators/xen-kernel/files/xsa226-4.7.patch ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/emulators/xen-kernel/files/xsa227.patch =================================================================== --- head/emulators/xen-kernel/files/xsa227.patch (nonexistent) +++ head/emulators/xen-kernel/files/xsa227.patch (revision 447987) @@ -0,0 +1,52 @@ +From fa7268b94f8a0a7792ee12d5b8e23a60e52a3a84 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper +Date: Tue, 20 Jun 2017 19:18:54 +0100 +Subject: [PATCH] x86/grant: Disallow misaligned PTEs + +Pagetable entries must be aligned to function correctly. Disallow attempts +from the guest to have a grant PTE created at a misaligned address, which +would result in corruption of the L1 table with largely-guest-controlled +values. + +This is XSA-227 + +Signed-off-by: Andrew Cooper +Reviewed-by: Jan Beulich +--- + xen/arch/x86/mm.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c +index 97b3b4b..00f517a 100644 +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c +@@ -3763,6 +3763,9 @@ static int create_grant_pte_mapping( + l1_pgentry_t ol1e; + struct domain *d = v->domain; + ++ if ( !IS_ALIGNED(pte_addr, sizeof(nl1e)) ) ++ return GNTST_general_error; ++ + adjust_guest_l1e(nl1e, d); + + gmfn = pte_addr >> PAGE_SHIFT; +@@ -3819,6 +3822,16 @@ static int destroy_grant_pte_mapping( + struct page_info *page; + l1_pgentry_t ol1e; + ++ /* ++ * addr comes from Xen's active_entry tracking so isn't guest controlled, ++ * but it had still better be PTE-aligned. ++ */ ++ if ( !IS_ALIGNED(addr, sizeof(ol1e)) ) ++ { ++ ASSERT_UNREACHABLE(); ++ return GNTST_general_error; ++ } ++ + gmfn = addr >> PAGE_SHIFT; + page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC); + +-- +2.1.4 + Property changes on: head/emulators/xen-kernel/files/xsa227.patch ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/emulators/xen-kernel/files/xsa228-4.8.patch =================================================================== --- head/emulators/xen-kernel/files/xsa228-4.8.patch (nonexistent) +++ head/emulators/xen-kernel/files/xsa228-4.8.patch (revision 447987) @@ -0,0 +1,198 @@ +From cb91f4c43bd4158daa6561c73921a6455176f278 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Mon, 31 Jul 2017 15:17:56 +0100 +Subject: [PATCH] gnttab: split maptrack lock to make it fulfill its purpose + again + +The way the lock is currently being used in get_maptrack_handle(), it +protects only the maptrack limit: The function acts on current's list +only, so races on list accesses are impossible even without the lock. + +Otoh list access races are possible between __get_maptrack_handle() and +put_maptrack_handle(), due to the invocation of the former for other +than current from steal_maptrack_handle(). Introduce a per-vCPU lock +for list accesses to become race free again. This lock will be +uncontended except when it becomes necessary to take the steal path, +i.e. in the common case there should be no meaningful performance +impact. + +When in get_maptrack_handle adds a stolen entry to a fresh, empty, +freelist, we think that there is probably no concurrency. However, +this is not a fast path and adding the locking there makes the code +clearly correct. + +Also, while we are here: the stolen maptrack_entry's tail pointer was +not properly set. Set it. + +This is XSA-228. + +Reported-by: Ian Jackson +Signed-off-by: Jan Beulich +Signed-off-by: Ian Jackson +--- + docs/misc/grant-tables.txt | 7 ++++++- + xen/common/grant_table.c | 30 ++++++++++++++++++++++++------ + xen/include/xen/grant_table.h | 2 +- + xen/include/xen/sched.h | 1 + + 4 files changed, 32 insertions(+), 8 deletions(-) + +diff --git a/docs/misc/grant-tables.txt b/docs/misc/grant-tables.txt +index 417ce2d..64da5cf 100644 +--- a/docs/misc/grant-tables.txt ++++ b/docs/misc/grant-tables.txt +@@ -87,7 +87,8 @@ is complete. + inconsistent grant table state such as current + version, partially initialized active table pages, + etc. +- grant_table->maptrack_lock : spinlock used to protect the maptrack free list ++ grant_table->maptrack_lock : spinlock used to protect the maptrack limit ++ v->maptrack_freelist_lock : spinlock used to protect the maptrack free list + active_grant_entry->lock : spinlock used to serialize modifications to + active entries + +@@ -102,6 +103,10 @@ is complete. + The maptrack free list is protected by its own spinlock. The maptrack + lock may be locked while holding the grant table lock. + ++ The maptrack_freelist_lock is an innermost lock. It may be locked ++ while holding other locks, but no other locks may be acquired within ++ it. ++ + Active entries are obtained by calling active_entry_acquire(gt, ref). + This function returns a pointer to the active entry after locking its + spinlock. The caller must hold the grant table read lock before +diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c +index f9654f1..593121c 100644 +--- a/xen/common/grant_table.c ++++ b/xen/common/grant_table.c +@@ -304,11 +304,16 @@ __get_maptrack_handle( + { + unsigned int head, next, prev_head; + ++ spin_lock(&v->maptrack_freelist_lock); ++ + do { + /* No maptrack pages allocated for this VCPU yet? */ + head = read_atomic(&v->maptrack_head); + if ( unlikely(head == MAPTRACK_TAIL) ) ++ { ++ spin_unlock(&v->maptrack_freelist_lock); + return -1; ++ } + + /* + * Always keep one entry in the free list to make it easier to +@@ -316,12 +321,17 @@ __get_maptrack_handle( + */ + next = read_atomic(&maptrack_entry(t, head).ref); + if ( unlikely(next == MAPTRACK_TAIL) ) ++ { ++ spin_unlock(&v->maptrack_freelist_lock); + return -1; ++ } + + prev_head = head; + head = cmpxchg(&v->maptrack_head, prev_head, next); + } while ( head != prev_head ); + ++ spin_unlock(&v->maptrack_freelist_lock); ++ + return head; + } + +@@ -380,6 +390,8 @@ put_maptrack_handle( + /* 2. Add entry to the tail of the list on the original VCPU. */ + v = currd->vcpu[maptrack_entry(t, handle).vcpu]; + ++ spin_lock(&v->maptrack_freelist_lock); ++ + cur_tail = read_atomic(&v->maptrack_tail); + do { + prev_tail = cur_tail; +@@ -388,6 +400,8 @@ put_maptrack_handle( + + /* 3. Update the old tail entry to point to the new entry. */ + write_atomic(&maptrack_entry(t, prev_tail).ref, handle); ++ ++ spin_unlock(&v->maptrack_freelist_lock); + } + + static inline int +@@ -411,10 +425,6 @@ get_maptrack_handle( + */ + if ( nr_maptrack_frames(lgt) >= max_maptrack_frames ) + { +- /* +- * Can drop the lock since no other VCPU can be adding a new +- * frame once they've run out. +- */ + spin_unlock(&lgt->maptrack_lock); + + /* +@@ -426,8 +436,12 @@ get_maptrack_handle( + handle = steal_maptrack_handle(lgt, curr); + if ( handle == -1 ) + return -1; ++ spin_lock(&curr->maptrack_freelist_lock); ++ maptrack_entry(lgt, handle).ref = MAPTRACK_TAIL; + curr->maptrack_tail = handle; +- write_atomic(&curr->maptrack_head, handle); ++ if ( curr->maptrack_head == MAPTRACK_TAIL ) ++ write_atomic(&curr->maptrack_head, handle); ++ spin_unlock(&curr->maptrack_freelist_lock); + } + return steal_maptrack_handle(lgt, curr); + } +@@ -460,12 +474,15 @@ get_maptrack_handle( + smp_wmb(); + lgt->maptrack_limit += MAPTRACK_PER_PAGE; + ++ spin_unlock(&lgt->maptrack_lock); ++ spin_lock(&curr->maptrack_freelist_lock); ++ + do { + new_mt[i - 1].ref = read_atomic(&curr->maptrack_head); + head = cmpxchg(&curr->maptrack_head, new_mt[i - 1].ref, handle + 1); + } while ( head != new_mt[i - 1].ref ); + +- spin_unlock(&lgt->maptrack_lock); ++ spin_unlock(&curr->maptrack_freelist_lock); + + return handle; + } +@@ -3474,6 +3491,7 @@ grant_table_destroy( + + void grant_table_init_vcpu(struct vcpu *v) + { ++ spin_lock_init(&v->maptrack_freelist_lock); + v->maptrack_head = MAPTRACK_TAIL; + v->maptrack_tail = MAPTRACK_TAIL; + } +diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h +index 4e77899..100f2b3 100644 +--- a/xen/include/xen/grant_table.h ++++ b/xen/include/xen/grant_table.h +@@ -78,7 +78,7 @@ struct grant_table { + /* Mapping tracking table per vcpu. */ + struct grant_mapping **maptrack; + unsigned int maptrack_limit; +- /* Lock protecting the maptrack page list, head, and limit */ ++ /* Lock protecting the maptrack limit */ + spinlock_t maptrack_lock; + /* The defined versions are 1 and 2. Set to 0 if we don't know + what version to use yet. */ +diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h +index 1fbda87..ff0f38f 100644 +--- a/xen/include/xen/sched.h ++++ b/xen/include/xen/sched.h +@@ -223,6 +223,7 @@ struct vcpu + int controller_pause_count; + + /* Maptrack */ ++ spinlock_t maptrack_freelist_lock; + unsigned int maptrack_head; + unsigned int maptrack_tail; + +-- +2.1.4 + Property changes on: head/emulators/xen-kernel/files/xsa228-4.8.patch ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/emulators/xen-kernel/files/xsa230.patch =================================================================== --- head/emulators/xen-kernel/files/xsa230.patch (nonexistent) +++ head/emulators/xen-kernel/files/xsa230.patch (revision 447987) @@ -0,0 +1,38 @@ +From: Jan Beulich +Subject: gnttab: correct pin status fixup for copy + +Regardless of copy operations only setting GNTPIN_hst*, GNTPIN_dev* +also need to be taken into account when deciding whether to clear +_GTF_{read,writ}ing. At least for consistency with code elsewhere the +read part better doesn't use any mask at all. + +This is XSA-230. + +Signed-off-by: Jan Beulich +Reviewed-by: Andrew Cooper +diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c +index ae34547..9c9d33c 100644 +--- a/xen/common/grant_table.c ++++ b/xen/common/grant_table.c +@@ -2107,10 +2107,10 @@ __release_grant_for_copy( + static void __fixup_status_for_copy_pin(const struct active_grant_entry *act, + uint16_t *status) + { +- if ( !(act->pin & GNTPIN_hstw_mask) ) ++ if ( !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) ) + gnttab_clear_flag(_GTF_writing, status); + +- if ( !(act->pin & GNTPIN_hstr_mask) ) ++ if ( !act->pin ) + gnttab_clear_flag(_GTF_reading, status); + } + +@@ -2318,7 +2318,7 @@ __acquire_grant_for_copy( + + unlock_out_clear: + if ( !(readonly) && +- !(act->pin & GNTPIN_hstw_mask) ) ++ !(act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) ) + gnttab_clear_flag(_GTF_writing, status); + + if ( !act->pin ) Property changes on: head/emulators/xen-kernel/files/xsa230.patch ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property