]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Feb 2018 13:00:51 +0000 (05:00 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Feb 2018 13:00:51 +0000 (05:00 -0800)
added patches:
kaiser-allocate-pgd-with-order-0-when-pti-off.patch
kaiser-fix-intel_bts-perf-crashes.patch
x86-pti-make-unpoison-of-pgd-for-trusted-boot-work-for-real.patch

queue-4.9/kaiser-allocate-pgd-with-order-0-when-pti-off.patch [new file with mode: 0644]
queue-4.9/kaiser-fix-intel_bts-perf-crashes.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/x86-pti-make-unpoison-of-pgd-for-trusted-boot-work-for-real.patch [new file with mode: 0644]

diff --git a/queue-4.9/kaiser-allocate-pgd-with-order-0-when-pti-off.patch b/queue-4.9/kaiser-allocate-pgd-with-order-0-when-pti-off.patch
new file mode 100644 (file)
index 0000000..260551e
--- /dev/null
@@ -0,0 +1,68 @@
+From hughd@google.com  Mon Feb  5 05:00:13 2018
+From: Hugh Dickins <hughd@google.com>
+Date: Mon, 29 Jan 2018 18:17:58 -0800
+Subject: kaiser: allocate pgd with order 0 when pti=off
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Hugh Dickins <hughd@google.com>, Pavel Tatashin <pasha.tatashin@oracle.com>, Steven Sistare <steven.sistare@oracle.com>, Jiri Kosina <jkosina@suse.cz>, stable@vger.kernel.org
+Message-ID: <20180130021758.229507-1-hughd@google.com>
+
+From: Hugh Dickins <hughd@google.com>
+
+The 4.9.77 version of "x86/pti/efi: broken conversion from efi to kernel
+page table" looked nicer than the 4.4.112 version, but was suboptimal on
+machines booted with "pti=off" (or on AMD machines): it allocated pgd
+with an order 1 page whatever the setting of kaiser_enabled.
+
+Fix that by moving the definition of PGD_ALLOCATION_ORDER from
+asm/pgalloc.h to asm/pgtable.h, which already defines kaiser_enabled.
+
+Fixes: 1b92c48a2eeb ("x86/pti/efi: broken conversion from efi to kernel page table")
+Cc: Pavel Tatashin <pasha.tatashin@oracle.com>
+Cc: Steven Sistare <steven.sistare@oracle.com>
+Cc: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/pgalloc.h |   11 -----------
+ arch/x86/include/asm/pgtable.h |    6 ++++++
+ 2 files changed, 6 insertions(+), 11 deletions(-)
+
+--- a/arch/x86/include/asm/pgalloc.h
++++ b/arch/x86/include/asm/pgalloc.h
+@@ -27,17 +27,6 @@ static inline void paravirt_release_pud(
+  */
+ extern gfp_t __userpte_alloc_gfp;
+-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+-/*
+- * Instead of one PGD, we acquire two PGDs.  Being order-1, it is
+- * both 8k in size and 8k-aligned.  That lets us just flip bit 12
+- * in a pointer to swap between the two 4k halves.
+- */
+-#define PGD_ALLOCATION_ORDER 1
+-#else
+-#define PGD_ALLOCATION_ORDER 0
+-#endif
+-
+ /*
+  * Allocate and free page tables.
+  */
+--- a/arch/x86/include/asm/pgtable.h
++++ b/arch/x86/include/asm/pgtable.h
+@@ -20,9 +20,15 @@
+ #ifdef CONFIG_PAGE_TABLE_ISOLATION
+ extern int kaiser_enabled;
++/*
++ * Instead of one PGD, we acquire two PGDs.  Being order-1, it is
++ * both 8k in size and 8k-aligned.  That lets us just flip bit 12
++ * in a pointer to swap between the two 4k halves.
++ */
+ #else
+ #define kaiser_enabled 0
+ #endif
++#define PGD_ALLOCATION_ORDER kaiser_enabled
+ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+ void ptdump_walk_pgd_level_checkwx(void);
diff --git a/queue-4.9/kaiser-fix-intel_bts-perf-crashes.patch b/queue-4.9/kaiser-fix-intel_bts-perf-crashes.patch
new file mode 100644 (file)
index 0000000..5ea9a08
--- /dev/null
@@ -0,0 +1,132 @@
+From hughd@google.com  Mon Feb  5 04:59:18 2018
+From: Hugh Dickins <hughd@google.com>
+Date: Mon, 29 Jan 2018 18:16:55 -0800
+Subject: kaiser: fix intel_bts perf crashes
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Hugh Dickins <hughd@google.com>, Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@kernel.org>, Andy Lutomirski <luto@amacapital.net>, Alexander Shishkin <alexander.shishkin@linux.intel.com>, Linus Torvalds <torvalds@linux-foundation.org>, Vince Weaver <vince@deater.net>, stable@vger.kernel.org, Jiri Kosina <jkosina@suse.cz>
+Message-ID: <20180130021655.229155-1-hughd@google.com>
+
+From: Hugh Dickins <hughd@google.com>
+
+Vince reported perf_fuzzer quickly locks up on 4.15-rc7 with PTI;
+Robert reported Bad RIP with KPTI and Intel BTS also on 4.15-rc7:
+honggfuzz -f /tmp/somedirectorywithatleastonefile \
+          --linux_perf_bts_edge -s -- /bin/true
+(honggfuzz from https://github.com/google/honggfuzz) crashed with
+BUG: unable to handle kernel paging request at ffff9d3215100000
+(then narrowed it down to
+perf record --per-thread -e intel_bts//u -- /bin/ls).
+
+The intel_bts driver does not use the 'normal' BTS buffer which is
+exposed through kaiser_add_mapping(), but instead uses the memory
+allocated for the perf AUX buffer.
+
+This obviously comes apart when using PTI, because then the kernel
+mapping, which includes that AUX buffer memory, disappears while
+switched to user page tables.
+
+Easily fixed in old-Kaiser backports, by applying kaiser_add_mapping()
+to those pages; perhaps not so easy for upstream, where 4.15-rc8 commit
+99a9dc98ba52 ("x86,perf: Disable intel_bts when PTI") disables for now.
+
+Slightly reorganized surrounding code in bts_buffer_setup_aux(),
+so it can better match bts_buffer_free_aux(): free_aux with an #ifdef
+to avoid the loop when PTI is off, but setup_aux needs to loop anyway
+(and kaiser_add_mapping() is cheap when PTI config is off or "pti=off").
+
+Reported-by: Vince Weaver <vincent.weaver@maine.edu>
+Reported-by: Robert Święcki <robert@swiecki.net>
+Analyzed-by: Peter Zijlstra <peterz@infradead.org>
+Analyzed-by: Stephane Eranian <eranian@google.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Vince Weaver <vince@deater.net>
+Cc: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/events/intel/bts.c |   44 +++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 33 insertions(+), 11 deletions(-)
+
+--- a/arch/x86/events/intel/bts.c
++++ b/arch/x86/events/intel/bts.c
+@@ -22,6 +22,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/device.h>
+ #include <linux/coredump.h>
++#include <linux/kaiser.h>
+ #include <asm-generic/sizes.h>
+ #include <asm/perf_event.h>
+@@ -77,6 +78,23 @@ static size_t buf_size(struct page *page
+       return 1 << (PAGE_SHIFT + page_private(page));
+ }
++static void bts_buffer_free_aux(void *data)
++{
++#ifdef CONFIG_PAGE_TABLE_ISOLATION
++      struct bts_buffer *buf = data;
++      int nbuf;
++
++      for (nbuf = 0; nbuf < buf->nr_bufs; nbuf++) {
++              struct page *page = buf->buf[nbuf].page;
++              void *kaddr = page_address(page);
++              size_t page_size = buf_size(page);
++
++              kaiser_remove_mapping((unsigned long)kaddr, page_size);
++      }
++#endif
++      kfree(data);
++}
++
+ static void *
+ bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
+ {
+@@ -113,29 +131,33 @@ bts_buffer_setup_aux(int cpu, void **pag
+       buf->real_size = size - size % BTS_RECORD_SIZE;
+       for (pg = 0, nbuf = 0, offset = 0, pad = 0; nbuf < buf->nr_bufs; nbuf++) {
+-              unsigned int __nr_pages;
++              void *kaddr = pages[pg];
++              size_t page_size;
++
++              page = virt_to_page(kaddr);
++              page_size = buf_size(page);
++
++              if (kaiser_add_mapping((unsigned long)kaddr,
++                                      page_size, __PAGE_KERNEL) < 0) {
++                      buf->nr_bufs = nbuf;
++                      bts_buffer_free_aux(buf);
++                      return NULL;
++              }
+-              page = virt_to_page(pages[pg]);
+-              __nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1;
+               buf->buf[nbuf].page = page;
+               buf->buf[nbuf].offset = offset;
+               buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0);
+-              buf->buf[nbuf].size = buf_size(page) - buf->buf[nbuf].displacement;
++              buf->buf[nbuf].size = page_size - buf->buf[nbuf].displacement;
+               pad = buf->buf[nbuf].size % BTS_RECORD_SIZE;
+               buf->buf[nbuf].size -= pad;
+-              pg += __nr_pages;
+-              offset += __nr_pages << PAGE_SHIFT;
++              pg += page_size >> PAGE_SHIFT;
++              offset += page_size;
+       }
+       return buf;
+ }
+-static void bts_buffer_free_aux(void *data)
+-{
+-      kfree(data);
+-}
+-
+ static unsigned long bts_buffer_offset(struct bts_buffer *buf, unsigned int idx)
+ {
+       return buf->buf[idx].offset + buf->buf[idx].displacement;
index c544212b812ad44f6c5699eb6a46f8570d389420..2b5d8cd9897a84ed8a4db16f823df2e0e9d6c44a 100644 (file)
@@ -12,3 +12,6 @@ powerpc-64s-allow-control-of-rfi-flush-via-debugfs.patch
 auxdisplay-img-ascii-lcd-add-missing-module_description-author-license.patch
 pinctrl-pxa-pxa2xx-add-missing-module_description-author-license.patch
 asoc-pcm512x-add-missing-module_description-author-license.patch
+kaiser-fix-intel_bts-perf-crashes.patch
+x86-pti-make-unpoison-of-pgd-for-trusted-boot-work-for-real.patch
+kaiser-allocate-pgd-with-order-0-when-pti-off.patch
diff --git a/queue-4.9/x86-pti-make-unpoison-of-pgd-for-trusted-boot-work-for-real.patch b/queue-4.9/x86-pti-make-unpoison-of-pgd-for-trusted-boot-work-for-real.patch
new file mode 100644 (file)
index 0000000..8f7ec08
--- /dev/null
@@ -0,0 +1,74 @@
+From hughd@google.com  Mon Feb  5 04:59:38 2018
+From: Hugh Dickins <hughd@google.com>
+Date: Mon, 29 Jan 2018 18:17:26 -0800
+Subject: x86/pti: Make unpoison of pgd for trusted boot work for real
+To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>, Thomas Gleixner <tglx@linutronix.de>, Jon Masters <jcm@redhat.com>, Tim Chen <tim.c.chen@linux.intel.com>, gnomes@lxorguk.ukuu.org.uk, peterz@infradead.org, ning.sun@intel.com, tboot-devel@lists.sourceforge.net, andi@firstfloor.org, luto@kernel.org, law@redhat.com, pbonzini@redhat.com, torvalds@linux-foundation.org, gregkh@linux-foundation.org, dwmw@amazon.co.uk, nickc@redhat.com, stable@vger.kernel.org, Jiri Kosina <jkosina@suse.cz>, Hugh Dickins <hughd@google.com>
+Message-ID: <20180130021726.229367-1-hughd@google.com>
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+commit 445b69e3b75e42362a5bdc13c8b8f61599e2228a upstream
+
+The inital fix for trusted boot and PTI potentially misses the pgd clearing
+if pud_alloc() sets a PGD.  It probably works in *practice* because for two
+adjacent calls to map_tboot_page() that share a PGD entry, the first will
+clear NX, *then* allocate and set the PGD (without NX clear).  The second
+call will *not* allocate but will clear the NX bit.
+
+Defer the NX clearing to a point after it is known that all top-level
+allocations have occurred.  Add a comment to clarify why.
+
+[ tglx: Massaged changelog ]
+
+[ hughd notes: I have not tested tboot, but this looks to me as necessary
+and as safe in old-Kaiser backports as it is upstream; I'm not submitting
+the commit-to-be-fixed 262b6b30087, since it was undone by 445b69e3b75e,
+and makes conflict trouble because of 5-level's p4d versus 4-level's pgd.]
+
+Fixes: 262b6b30087 ("x86/tboot: Unbreak tboot with PTI enabled")
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Jon Masters <jcm@redhat.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: peterz@infradead.org
+Cc: ning.sun@intel.com
+Cc: tboot-devel@lists.sourceforge.net
+Cc: andi@firstfloor.org
+Cc: luto@kernel.org
+Cc: law@redhat.com
+Cc: pbonzini@redhat.com
+Cc: torvalds@linux-foundation.org
+Cc: gregkh@linux-foundation.org
+Cc: dwmw@amazon.co.uk
+Cc: nickc@redhat.com
+Link: https://lkml.kernel.org/r/20180110224939.2695CD47@viggo.jf.intel.com
+Cc: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/tboot.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/x86/kernel/tboot.c
++++ b/arch/x86/kernel/tboot.c
+@@ -134,6 +134,16 @@ static int map_tboot_page(unsigned long
+               return -1;
+       set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
+       pte_unmap(pte);
++
++      /*
++       * PTI poisons low addresses in the kernel page tables in the
++       * name of making them unusable for userspace.  To execute
++       * code at such a low address, the poison must be cleared.
++       *
++       * Note: 'pgd' actually gets set in pud_alloc().
++       */
++      pgd->pgd &= ~_PAGE_NX;
++
+       return 0;
+ }