From: Greg Kroah-Hartman Date: Mon, 5 Feb 2018 13:00:51 +0000 (-0800) Subject: 4.9-stable patches X-Git-Tag: v3.18.94~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1807312a184a8b88a12948b55b286f5f861aaccc;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches 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 --- 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 index 00000000000..260551edeb0 --- /dev/null +++ b/queue-4.9/kaiser-allocate-pgd-with-order-0-when-pti-off.patch @@ -0,0 +1,68 @@ +From hughd@google.com Mon Feb 5 05:00:13 2018 +From: Hugh Dickins +Date: Mon, 29 Jan 2018 18:17:58 -0800 +Subject: kaiser: allocate pgd with order 0 when pti=off +To: Greg Kroah-Hartman +Cc: Hugh Dickins , Pavel Tatashin , Steven Sistare , Jiri Kosina , stable@vger.kernel.org +Message-ID: <20180130021758.229507-1-hughd@google.com> + +From: Hugh Dickins + +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 +Cc: Steven Sistare +Cc: Jiri Kosina +Signed-off-by: Hugh Dickins +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..5ea9a08d3f2 --- /dev/null +++ b/queue-4.9/kaiser-fix-intel_bts-perf-crashes.patch @@ -0,0 +1,132 @@ +From hughd@google.com Mon Feb 5 04:59:18 2018 +From: Hugh Dickins +Date: Mon, 29 Jan 2018 18:16:55 -0800 +Subject: kaiser: fix intel_bts perf crashes +To: Greg Kroah-Hartman +Cc: Hugh Dickins , Thomas Gleixner , Ingo Molnar , Andy Lutomirski , Alexander Shishkin , Linus Torvalds , Vince Weaver , stable@vger.kernel.org, Jiri Kosina +Message-ID: <20180130021655.229155-1-hughd@google.com> + +From: Hugh Dickins + +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 +Reported-by: Robert Święcki +Analyzed-by: Peter Zijlstra +Analyzed-by: Stephane Eranian +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: Andy Lutomirski +Cc: Alexander Shishkin +Cc: Linus Torvalds +Cc: Vince Weaver +Cc: Jiri Kosina +Signed-off-by: Hugh Dickins +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + #include + #include +@@ -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; diff --git a/queue-4.9/series b/queue-4.9/series index c544212b812..2b5d8cd9897 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -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 index 00000000000..8f7ec083d48 --- /dev/null +++ b/queue-4.9/x86-pti-make-unpoison-of-pgd-for-trusted-boot-work-for-real.patch @@ -0,0 +1,74 @@ +From hughd@google.com Mon Feb 5 04:59:38 2018 +From: Hugh Dickins +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 +Cc: Dave Hansen , Thomas Gleixner , Jon Masters , Tim Chen , 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 , Hugh Dickins +Message-ID: <20180130021726.229367-1-hughd@google.com> + +From: Dave Hansen + +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 +Signed-off-by: Thomas Gleixner +Reviewed-by: Andrea Arcangeli +Cc: Jon Masters +Cc: Tim Chen +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 +Signed-off-by: Hugh Dickins +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } +