pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/sysutils/xenkernel411 Apply patch fixing XSA299.



details:   https://anonhg.NetBSD.org/pkgsrc/rev/938fba45f2db
branches:  trunk
changeset: 417575:938fba45f2db
user:      bouyer <bouyer%pkgsrc.org@localhost>
date:      Wed Nov 13 15:00:06 2019 +0000

description:
Apply patch fixing XSA299.
Bump PKGREVISION

diffstat:

 sysutils/xenkernel411/Makefile             |     4 +-
 sysutils/xenkernel411/distinfo             |     3 +-
 sysutils/xenkernel411/patches/patch-XSA298 |     2 +-
 sysutils/xenkernel411/patches/patch-XSA299 |  2413 ++++++++++++++++++++++++++++
 sysutils/xenkernel411/patches/patch-XSA302 |     2 +-
 sysutils/xenkernel411/patches/patch-XSA304 |     2 +-
 sysutils/xenkernel411/patches/patch-XSA305 |     2 +-
 7 files changed, 2421 insertions(+), 7 deletions(-)

diffs (truncated from 2483 to 300 lines):

diff -r bc7d762dae3b -r 938fba45f2db sysutils/xenkernel411/Makefile
--- a/sysutils/xenkernel411/Makefile    Wed Nov 13 14:56:20 2019 +0000
+++ b/sysutils/xenkernel411/Makefile    Wed Nov 13 15:00:06 2019 +0000
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.9 2019/11/13 13:36:11 bouyer Exp $
+# $NetBSD: Makefile,v 1.10 2019/11/13 15:00:06 bouyer Exp $
 
 VERSION=       4.11.2
-PKGREVISION=   1
+PKGREVISION=   2
 DISTNAME=      xen-${VERSION}
 PKGNAME=       xenkernel411-${VERSION}
 CATEGORIES=    sysutils
diff -r bc7d762dae3b -r 938fba45f2db sysutils/xenkernel411/distinfo
--- a/sysutils/xenkernel411/distinfo    Wed Nov 13 14:56:20 2019 +0000
+++ b/sysutils/xenkernel411/distinfo    Wed Nov 13 15:00:06 2019 +0000
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.6 2019/11/13 13:36:11 bouyer Exp $
+$NetBSD: distinfo,v 1.7 2019/11/13 15:00:06 bouyer Exp $
 
 SHA1 (xen411/xen-4.11.2.tar.gz) = 82766db0eca7ce65962732af8a31bb5cce1eb7ce
 RMD160 (xen411/xen-4.11.2.tar.gz) = 6dcb1ac3e72381474912607b30b59fa55d87d38b
@@ -6,6 +6,7 @@
 Size (xen411/xen-4.11.2.tar.gz) = 25164925 bytes
 SHA1 (patch-Config.mk) = 9372a09efd05c9fbdbc06f8121e411fcb7c7ba65
 SHA1 (patch-XSA298) = 63e0f96ce3b945b16b98b51b423bafec14cf2be6
+SHA1 (patch-XSA299) = beb7ba1a8f9e0adda161c0da725ff053e674067e
 SHA1 (patch-XSA302) = 12fbb7dfea27f53c70c8115487a2e30595549c2b
 SHA1 (patch-XSA304) = f2c22732227e11a3e77c630f0264a689eed53399
 SHA1 (patch-XSA305) = eb5e0096cbf501fcbd7a5c5f9d1f932b557636b6
diff -r bc7d762dae3b -r 938fba45f2db sysutils/xenkernel411/patches/patch-XSA298
--- a/sysutils/xenkernel411/patches/patch-XSA298        Wed Nov 13 14:56:20 2019 +0000
+++ b/sysutils/xenkernel411/patches/patch-XSA298        Wed Nov 13 15:00:06 2019 +0000
@@ -1,4 +1,4 @@
-$NetBSD: patch-XSA298,v 1.1 2019/11/13 13:36:11 bouyer Exp $
+$NetBSD: patch-XSA298,v 1.2 2019/11/13 15:00:06 bouyer Exp $
 
 From: Jan Beulich <jbeulich%suse.com@localhost>
 Subject: x86/PV: check GDT/LDT limits during emulation
diff -r bc7d762dae3b -r 938fba45f2db sysutils/xenkernel411/patches/patch-XSA299
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sysutils/xenkernel411/patches/patch-XSA299        Wed Nov 13 15:00:06 2019 +0000
@@ -0,0 +1,2413 @@
+$NetBSD: patch-XSA299,v 1.1 2019/11/13 15:00:06 bouyer Exp $
+
+From 852df269d247e177d5f2e9b8f3a4301a6fdd76bd Mon Sep 17 00:00:00 2001
+From: George Dunlap <george.dunlap%citrix.com@localhost>
+Date: Thu, 10 Oct 2019 17:57:49 +0100
+Subject: [PATCH 01/11] x86/mm: L1TF checks don't leave a partial entry
+
+On detection of a potential L1TF issue, most validation code returns
+-ERESTART to allow the switch to shadow mode to happen and cause the
+original operation to be restarted.
+
+However, in the validation code, the return value -ERESTART has been
+repurposed to indicate 1) the function has partially completed
+something which needs to be undone, and 2) calling put_page_type()
+should cleanly undo it.  This causes problems in several places.
+
+For L1 tables, on receiving an -ERESTART return from alloc_l1_table(),
+alloc_page_type() will set PGT_partial on the page.  If for some
+reason the original operation never restarts, then on domain
+destruction, relinquish_memory() will call free_page_type() on the
+page.
+
+Unfortunately, alloc_ and free_l1_table() aren't set up to deal with
+PGT_partial.  When returning a failure, alloc_l1_table() always
+de-validates whatever it's validated so far, and free_l1_table()
+always devalidates the whole page.  This means that if
+relinquish_memory() calls free_page_type() on an L1 that didn't
+complete due to an L1TF, it will call put_page_from_l1e() on "page
+entries" that have never been validated.
+
+For L2+ tables, setting rc to ERESTART causes the rest of the
+alloc_lN_table() function to *think* that the entry in question will
+have PGT_partial set.  This will cause it to set partial_pte = 1.  If
+relinqush_memory() then calls free_page_type() on one of those pages,
+then free_lN_table() will call put_page_from_lNe() on the entry when
+it shouldn't.
+
+Rather than indicating -ERESTART, indicate -EINTR.  This is the code
+to indicate that nothing has changed from when you started the call
+(which is effectively how alloc_l1_table() handles errors).
+
+mod_lN_entry() shouldn't have any of these types of problems, so leave
+potential changes there for a clean-up patch later.
+
+This is part of XSA-299.
+
+Reported-by: George Dunlap <george.dunlap%citrix.com@localhost>
+Signed-off-by: George Dunlap <george.dunlap%citrix.com@localhost>
+Reviewed-by: Jan Beulich <jbeulich%suse.com@localhost>
+---
+ xen/arch/x86/mm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
+index e6a4cb28f8..8ced185b49 100644
+--- xen/arch/x86/mm.c.orig
++++ xen/arch/x86/mm.c
+@@ -1110,7 +1110,7 @@ get_page_from_l2e(
+     int rc;
+ 
+     if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+-        return pv_l1tf_check_l2e(d, l2e) ? -ERESTART : 1;
++        return pv_l1tf_check_l2e(d, l2e) ? -EINTR : 1;
+ 
+     if ( unlikely((l2e_get_flags(l2e) & L2_DISALLOW_MASK)) )
+     {
+@@ -1142,7 +1142,7 @@ get_page_from_l3e(
+     int rc;
+ 
+     if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+-        return pv_l1tf_check_l3e(d, l3e) ? -ERESTART : 1;
++        return pv_l1tf_check_l3e(d, l3e) ? -EINTR : 1;
+ 
+     if ( unlikely((l3e_get_flags(l3e) & l3_disallow_mask(d))) )
+     {
+@@ -1175,7 +1175,7 @@ get_page_from_l4e(
+     int rc;
+ 
+     if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )
+-        return pv_l1tf_check_l4e(d, l4e) ? -ERESTART : 1;
++        return pv_l1tf_check_l4e(d, l4e) ? -EINTR : 1;
+ 
+     if ( unlikely((l4e_get_flags(l4e) & L4_DISALLOW_MASK)) )
+     {
+@@ -1404,7 +1404,7 @@ static int alloc_l1_table(struct page_info *page)
+     {
+         if ( !(l1e_get_flags(pl1e[i]) & _PAGE_PRESENT) )
+         {
+-            ret = pv_l1tf_check_l1e(d, pl1e[i]) ? -ERESTART : 0;
++            ret = pv_l1tf_check_l1e(d, pl1e[i]) ? -EINTR : 0;
+             if ( ret )
+                 goto out;
+         }
+-- 
+2.23.0
+
+From 6bdddd7980eac0cc883945d823986f24682ca47a Mon Sep 17 00:00:00 2001
+From: George Dunlap <george.dunlap%citrix.com@localhost>
+Date: Thu, 10 Oct 2019 17:57:49 +0100
+Subject: [PATCH 02/11] x86/mm: Don't re-set PGT_pinned on a partially
+ de-validated page
+
+When unpinning pagetables, if an operation is interrupted,
+relinquish_memory() re-sets PGT_pinned so that the un-pin will
+pickedup again when the hypercall restarts.
+
+This is appropriate when put_page_and_type_preemptible() returns
+-EINTR, which indicates that the page is back in its initial state
+(i.e., completely validated).  However, for -ERESTART, this leads to a
+state where a page has both PGT_pinned and PGT_partial set.
+
+This happens to work at the moment, although it's not really a
+"canonical" state; but in subsequent patches, where we need to make a
+distinction in handling between PGT_validated and PGT_partial pages,
+this causes issues.
+
+Move to a "canonical" state by:
+- Only re-setting PGT_pinned on -EINTR
+- Re-dropping the refcount held by PGT_pinned on -ERESTART
+
+In the latter case, the PGT_partial bit will be cleared further down
+with the rest of the other PGT_partial pages.
+
+While here, clean up some trainling whitespace.
+
+This is part of XSA-299.
+
+Reported-by: George Dunlap <george.dunlap%citrix.com@localhost>
+Signed-off-by: George Dunlap <george.dunlap%citrix.com@localhost>
+Reviewed-by: Jan Beulich <jbeulich%suse.com@localhost>
+---
+ xen/arch/x86/domain.c | 31 ++++++++++++++++++++++++++++---
+ 1 file changed, 28 insertions(+), 3 deletions(-)
+
+diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
+index 29f892c04c..8fbecbb169 100644
+--- xen/arch/x86/domain.c.orig
++++ xen/arch/x86/domain.c
+@@ -112,7 +112,7 @@ static void play_dead(void)
+      * this case, heap corruption or #PF can occur (when heap debugging is
+      * enabled). For example, even printk() can involve tasklet scheduling,
+      * which touches per-cpu vars.
+-     * 
++     *
+      * Consider very carefully when adding code to *dead_idle. Most hypervisor
+      * subsystems are unsafe to call.
+      */
+@@ -1838,9 +1838,34 @@ static int relinquish_memory(
+             break;
+         case -ERESTART:
+         case -EINTR:
++            /*
++             * -EINTR means PGT_validated has been re-set; re-set
++             * PGT_pinned again so that it gets picked up next time
++             * around.
++             *
++             * -ERESTART, OTOH, means PGT_partial is set instead.  Put
++             * it back on the list, but don't set PGT_pinned; the
++             * section below will finish off de-validation.  But we do
++             * need to drop the general ref associated with
++             * PGT_pinned, since put_page_and_type_preemptible()
++             * didn't do it.
++             *
++             * NB we can do an ASSERT for PGT_validated, since we
++             * "own" the type ref; but theoretically, the PGT_partial
++             * could be cleared by someone else.
++             */
++            if ( ret == -EINTR )
++            {
++                ASSERT(page->u.inuse.type_info & PGT_validated);
++                set_bit(_PGT_pinned, &page->u.inuse.type_info);
++            }
++            else
++                put_page(page);
++
+             ret = -ERESTART;
++
++            /* Put the page back on the list and drop the ref we grabbed above */
+             page_list_add(page, list);
+-            set_bit(_PGT_pinned, &page->u.inuse.type_info);
+             put_page(page);
+             goto out;
+         default:
+@@ -2062,7 +2087,7 @@ void vcpu_kick(struct vcpu *v)
+      * pending flag. These values may fluctuate (after all, we hold no
+      * locks) but the key insight is that each change will cause
+      * evtchn_upcall_pending to be polled.
+-     * 
++     *
+      * NB2. We save the running flag across the unblock to avoid a needless
+      * IPI for domains that we IPI'd to unblock.
+      */
+-- 
+2.23.0
+
+From 7c0a37005f52d10903ce22851b52ae9b6f4f0ee2 Mon Sep 17 00:00:00 2001
+From: George Dunlap <george.dunlap%citrix.com@localhost>
+Date: Thu, 10 Oct 2019 17:57:49 +0100
+Subject: [PATCH 03/11] x86/mm: Separate out partial_pte tristate into
+ individual flags
+
+At the moment, partial_pte is a tri-state that contains two distinct bits
+of information:
+
+1. If zero, the pte at index [nr_validated_ptes] is un-validated.  If
+   non-zero, the pte was last seen with PGT_partial set.
+
+2. If positive, the pte at index [nr_validated_ptes] does not hold a
+   general reference count.  If negative, it does.
+
+To make future patches more clear, separate out this functionality
+into two distinct, named bits: PTF_partial_set (for #1) and
+PTF_partial_general_ref (for #2).
+
+Additionally, a number of functions which need this information also
+take other flags to control behavior (such as `preemptible` and
+`defer`).  These are hard to read in the caller (since you only see
+'true' or 'false'), and ugly when many are added together.  In
+preparation for adding yet another flag in a future patch, collapse
+all of these into a single `flag` variable.
+
+NB that this does mean checking for what was previously the '-1'
+condition a bit more ugly in the put_page_from_lNe functions (since
+you have to check for both partial_set and general ref); but this
+clause will go away in a future patch.
+
+Also note that the original comment had an off-by-one error:
+partial_flags (like partial_pte before it) concerns
+plNe[nr_validated_ptes], not plNe[nr_validated_ptes+1].
+
+No functional change intended.
+
+This is part of XSA-299.
+
+Reported-by: George Dunlap <george.dunlap%citrix.com@localhost>
+Signed-off-by: George Dunlap <george.dunlap%citrix.com@localhost>
+Reviewed-by: Jan Beulich <jbeulich%suse.com@localhost>
+---
+ xen/arch/x86/mm.c        | 164 +++++++++++++++++++++++----------------
+ xen/include/asm-x86/mm.h |  41 ++++++----
+ 2 files changed, 127 insertions(+), 78 deletions(-)
+
+diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
+index 8ced185b49..1c4f54e328 100644
+--- xen/arch/x86/mm.c.orig
++++ xen/arch/x86/mm.c
+@@ -610,20 +610,34 @@ static int alloc_segdesc_page(struct page_info *page)
+ static int _get_page_type(struct page_info *page, unsigned long type,
+                           bool preemptible);
+ 
++/*
++ * The following flags are used to specify behavior of various get and
++ * put commands.  The first two are also stored in page->partial_flags
++ * to indicate the state of the page pointed to by
++ * page->pte[page->nr_validated_entries].  See the comment in mm.h for
++ * more information.
++ */



Home | Main Index | Thread Index | Old Index