All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] x86, mm: PTI Global page fixes for 4.17
@ 2018-04-20 22:20 ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, aaro.koskinen, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, fengguang.wu, gregkh, hughd, mingo,
	jpoimboe, jgross, keescook, torvalds, mceier, namit, peterz,
	tglx, vbabka

There have been a number of reports about issues with the patches that
restore the Global PTE bit when using KPIT.  This set resolves all of
the issues that have been reported.

These have been pushed out to a git tree where 0day should be chewing
on them.  Considering the troubles thus far, we should probably wait
for 0day to spend _some_ time on these fixes before these get merged.

Cc: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Fengguang Wu <fengguang.wu@intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mariusz Ceier <mceier@gmail.com>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: linux-mm@kvack.org

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 0/5] x86, mm: PTI Global page fixes for 4.17
@ 2018-04-20 22:20 ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, aaro.koskinen, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, fengguang.wu, gregkh, hughd, mingo,
	jpoimboe, jgross, keescook, torvalds, mceier, namit, peterz,
	tglx, vbabka

There have been a number of reports about issues with the patches that
restore the Global PTE bit when using KPIT.  This set resolves all of
the issues that have been reported.

These have been pushed out to a git tree where 0day should be chewing
on them.  Considering the troubles thus far, we should probably wait
for 0day to spend _some_ time on these fixes before these get merged.

Cc: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Fengguang Wu <fengguang.wu@intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mariusz Ceier <mceier@gmail.com>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: linux-mm@kvack.org

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/5] x86, pti: fix boot problems from Global-bit setting
  2018-04-20 22:20 ` Dave Hansen
@ 2018-04-20 22:20   ` Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, mceier, aaro.koskinen, aarcange, luto,
	arjan, bp, dan.j.williams, dwmw2, gregkh, hughd, jpoimboe,
	jgross, keescook, torvalds, namit, peterz, tglx


From: Dave Hansen <dave.hansen@linux.intel.com>

Part of the global bit _setting_ patches also includes clearing the
Global bit when we do not want it.  That is done with
set_memory_nonglobal(), which uses change_page_attr_clear() in
pageattr.c under the covers.

The TLB flushing code inside pageattr.c has has checks like
BUG_ON(irqs_disabled()), looking for interrupt disabling that might
cause deadlocks.  But, these also trip in early boot on certain
preempt configurations.  Just copy the existing BUG_ON() sequence from
cpa_flush_range() to the other two sites and check for early boot.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
Reported-by: Mariusz Ceier <mceier@gmail.com>
Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
---

 b/arch/x86/mm/pageattr.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff -puN arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix arch/x86/mm/pageattr.c
--- a/arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix	2018-04-20 14:10:01.086749169 -0700
+++ b/arch/x86/mm/pageattr.c	2018-04-20 14:10:01.090749169 -0700
@@ -172,7 +172,7 @@ static void __cpa_flush_all(void *arg)
 
 static void cpa_flush_all(unsigned long cache)
 {
-	BUG_ON(irqs_disabled());
+	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
 	on_each_cpu(__cpa_flush_all, (void *) cache, 1);
 }
@@ -236,7 +236,7 @@ static void cpa_flush_array(unsigned lon
 	unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
 #endif
 
-	BUG_ON(irqs_disabled());
+	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
 	on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
 
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/5] x86, pti: fix boot problems from Global-bit setting
@ 2018-04-20 22:20   ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, mceier, aaro.koskinen, aarcange, luto,
	arjan, bp, dan.j.williams, dwmw2, gregkh, hughd, jpoimboe,
	jgross, keescook, torvalds, namit, peterz, tglx


From: Dave Hansen <dave.hansen@linux.intel.com>

Part of the global bit _setting_ patches also includes clearing the
Global bit when we do not want it.  That is done with
set_memory_nonglobal(), which uses change_page_attr_clear() in
pageattr.c under the covers.

The TLB flushing code inside pageattr.c has has checks like
BUG_ON(irqs_disabled()), looking for interrupt disabling that might
cause deadlocks.  But, these also trip in early boot on certain
preempt configurations.  Just copy the existing BUG_ON() sequence from
cpa_flush_range() to the other two sites and check for early boot.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
Reported-by: Mariusz Ceier <mceier@gmail.com>
Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
---

 b/arch/x86/mm/pageattr.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff -puN arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix arch/x86/mm/pageattr.c
--- a/arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix	2018-04-20 14:10:01.086749169 -0700
+++ b/arch/x86/mm/pageattr.c	2018-04-20 14:10:01.090749169 -0700
@@ -172,7 +172,7 @@ static void __cpa_flush_all(void *arg)
 
 static void cpa_flush_all(unsigned long cache)
 {
-	BUG_ON(irqs_disabled());
+	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
 	on_each_cpu(__cpa_flush_all, (void *) cache, 1);
 }
@@ -236,7 +236,7 @@ static void cpa_flush_array(unsigned lon
 	unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
 #endif
 
-	BUG_ON(irqs_disabled());
+	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
 	on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
 
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 2/5] x86, pti: fix boot warning from Global-bit setting
  2018-04-20 22:20 ` Dave Hansen
@ 2018-04-20 22:20   ` Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, mceier, aaro.koskinen, aarcange, luto,
	arjan, bp, dan.j.williams, dwmw2, gregkh, hughd, jpoimboe,
	jgross, keescook, torvalds, namit, peterz, tglx


From: Dave Hansen <dave.hansen@linux.intel.com>

The pageattr.c code attempts to process "faults" when it goes looking
for PTEs to change and finds non-present entries.  It allows these
faults in the linear map which is "expected to have holes", but
WARN()s about them elsewhere, like when called on the kernel image.

However, we are now calling change_page_attr_clear() on the kernel
image in the process of trying to clear the Global bit.

This trips the warning in __cpa_process_fault() if a non-present PTE is
encountered in the kernel image.  The "holes" in the kernel image
result from free_init_pages()'s use of set_memory_np().  These holes
are totally fine, and result from normal operation, just as they would
be in the kernel linear map.

Just silence the warning when holes in the kernel image are encountered.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
Reported-by: Mariusz Ceier <mceier@gmail.com>
Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
---

 b/arch/x86/mm/pageattr.c |   41 +++++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 10 deletions(-)

diff -puN arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr arch/x86/mm/pageattr.c
--- a/arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr	2018-04-20 14:10:01.619749168 -0700
+++ b/arch/x86/mm/pageattr.c	2018-04-20 14:10:01.623749168 -0700
@@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file
 static inline void split_page_count(int level) { }
 #endif
 
+static inline int
+within(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr < end;
+}
+
+static inline int
+within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr <= end;
+}
+
 #ifdef CONFIG_X86_64
 
 static inline unsigned long highmap_start_pfn(void)
@@ -106,20 +118,26 @@ static inline unsigned long highmap_end_
 	return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
 }
 
-#endif
-
-static inline int
-within(unsigned long addr, unsigned long start, unsigned long end)
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-	return addr >= start && addr < end;
+	/*
+	 * Kernel text has an alias mapping at a high address, known
+	 * here as "highmap".
+	 */
+	return within_inclusive(pfn, highmap_start_pfn(),
+			highmap_end_pfn());
 }
 
-static inline int
-within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+#else
+
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-	return addr >= start && addr <= end;
+	/* There is no highmap on 32-bit */
+	return false;
 }
 
+#endif
+
 /*
  * Flushing functions
  */
@@ -1183,6 +1201,10 @@ static int __cpa_process_fault(struct cp
 		cpa->numpages = 1;
 		cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
 		return 0;
+
+	} else if (__cpa_pfn_in_highmap(cpa->pfn)) {
+		/* Faults in the highmap are OK, so do not warn: */
+		return -EFAULT;
 	} else {
 		WARN(1, KERN_WARNING "CPA: called for zero pte. "
 			"vaddr = %lx cpa->vaddr = %lx\n", vaddr,
@@ -1335,8 +1357,7 @@ static int cpa_process_alias(struct cpa_
 	 * to touch the high mapped kernel as well:
 	 */
 	if (!within(vaddr, (unsigned long)_text, _brk_end) &&
-	    within_inclusive(cpa->pfn, highmap_start_pfn(),
-			     highmap_end_pfn())) {
+	    __cpa_pfn_in_highmap(cpa->pfn)) {
 		unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
 					       __START_KERNEL_map - phys_base;
 		alias_cpa = *cpa;
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 2/5] x86, pti: fix boot warning from Global-bit setting
@ 2018-04-20 22:20   ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, mceier, aaro.koskinen, aarcange, luto,
	arjan, bp, dan.j.williams, dwmw2, gregkh, hughd, jpoimboe,
	jgross, keescook, torvalds, namit, peterz, tglx


From: Dave Hansen <dave.hansen@linux.intel.com>

The pageattr.c code attempts to process "faults" when it goes looking
for PTEs to change and finds non-present entries.  It allows these
faults in the linear map which is "expected to have holes", but
WARN()s about them elsewhere, like when called on the kernel image.

However, we are now calling change_page_attr_clear() on the kernel
image in the process of trying to clear the Global bit.

This trips the warning in __cpa_process_fault() if a non-present PTE is
encountered in the kernel image.  The "holes" in the kernel image
result from free_init_pages()'s use of set_memory_np().  These holes
are totally fine, and result from normal operation, just as they would
be in the kernel linear map.

Just silence the warning when holes in the kernel image are encountered.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
Reported-by: Mariusz Ceier <mceier@gmail.com>
Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
---

 b/arch/x86/mm/pageattr.c |   41 +++++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 10 deletions(-)

diff -puN arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr arch/x86/mm/pageattr.c
--- a/arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr	2018-04-20 14:10:01.619749168 -0700
+++ b/arch/x86/mm/pageattr.c	2018-04-20 14:10:01.623749168 -0700
@@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file
 static inline void split_page_count(int level) { }
 #endif
 
+static inline int
+within(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr < end;
+}
+
+static inline int
+within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr <= end;
+}
+
 #ifdef CONFIG_X86_64
 
 static inline unsigned long highmap_start_pfn(void)
@@ -106,20 +118,26 @@ static inline unsigned long highmap_end_
 	return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
 }
 
-#endif
-
-static inline int
-within(unsigned long addr, unsigned long start, unsigned long end)
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-	return addr >= start && addr < end;
+	/*
+	 * Kernel text has an alias mapping at a high address, known
+	 * here as "highmap".
+	 */
+	return within_inclusive(pfn, highmap_start_pfn(),
+			highmap_end_pfn());
 }
 
-static inline int
-within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+#else
+
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-	return addr >= start && addr <= end;
+	/* There is no highmap on 32-bit */
+	return false;
 }
 
+#endif
+
 /*
  * Flushing functions
  */
@@ -1183,6 +1201,10 @@ static int __cpa_process_fault(struct cp
 		cpa->numpages = 1;
 		cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
 		return 0;
+
+	} else if (__cpa_pfn_in_highmap(cpa->pfn)) {
+		/* Faults in the highmap are OK, so do not warn: */
+		return -EFAULT;
 	} else {
 		WARN(1, KERN_WARNING "CPA: called for zero pte. "
 			"vaddr = %lx cpa->vaddr = %lx\n", vaddr,
@@ -1335,8 +1357,7 @@ static int cpa_process_alias(struct cpa_
 	 * to touch the high mapped kernel as well:
 	 */
 	if (!within(vaddr, (unsigned long)_text, _brk_end) &&
-	    within_inclusive(cpa->pfn, highmap_start_pfn(),
-			     highmap_end_pfn())) {
+	    __cpa_pfn_in_highmap(cpa->pfn)) {
 		unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
 					       __START_KERNEL_map - phys_base;
 		alias_cpa = *cpa;
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 3/5] x86, pti: reduce amount of kernel text allowed to be Global
  2018-04-20 22:20 ` Dave Hansen
@ 2018-04-20 22:20   ` Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, keescook, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, torvalds,
	namit, peterz, tglx


Kees reported to me that I made too much of the kernel image global.
It was far more than just text:

	I think this is too much set global: _end is after data,
	bss, and brk, and all kinds of other stuff that could
	hold secrets. I think this should match what
	mark_rodata_ro() is doing.

This does exactly that.  We use __end_rodata_hpage_align as our
marker both because it is huge-page-aligned and it does not contain
any sections we expect to hold secrets.

Kees's logic was that r/o data is in the kernel image anyway and,
in the case of traditional distributions, can be freely downloaded
from the web, so there's no reason to hide it.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reported-by: Kees Cook <keescook@google.com>
Fixes: 8c06c7740 (x86/pti: Leave kernel text global for !PCID)
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
---

 b/arch/x86/mm/pti.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff -puN arch/x86/mm/pti.c~pti-glb-too-much-mapped arch/x86/mm/pti.c
--- a/arch/x86/mm/pti.c~pti-glb-too-much-mapped	2018-04-20 14:10:02.164749166 -0700
+++ b/arch/x86/mm/pti.c	2018-04-20 14:10:02.168749166 -0700
@@ -430,12 +430,24 @@ static inline bool pti_kernel_image_glob
  */
 void pti_clone_kernel_text(void)
 {
+	/*
+	 * rodata is part of the kernel image and is normally
+	 * readable on the filesystem or on the web.  But, do not
+	 * clone the areas past rodata, they might contain secrets.
+	 */
 	unsigned long start = PFN_ALIGN(_text);
-	unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE);
+	unsigned long end = (unsigned long)__end_rodata_hpage_align;
 
 	if (!pti_kernel_image_global_ok())
 		return;
 
+	pr_debug("mapping partial kernel image into user address space\n");
+
+	/*
+	 * Note that this will undo _some_ of the work that
+	 * pti_set_kernel_image_nonglobal() did to clear the
+	 * global bit.
+	 */
 	pti_clone_pmds(start, end, _PAGE_RW);
 }
 
@@ -458,8 +470,6 @@ void pti_set_kernel_image_nonglobal(void
 	if (pti_kernel_image_global_ok())
 		return;
 
-	pr_debug("set kernel image non-global\n");
-
 	set_memory_nonglobal(start, (end - start) >> PAGE_SHIFT);
 }
 
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 3/5] x86, pti: reduce amount of kernel text allowed to be Global
@ 2018-04-20 22:20   ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, keescook, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, torvalds,
	namit, peterz, tglx


Kees reported to me that I made too much of the kernel image global.
It was far more than just text:

	I think this is too much set global: _end is after data,
	bss, and brk, and all kinds of other stuff that could
	hold secrets. I think this should match what
	mark_rodata_ro() is doing.

This does exactly that.  We use __end_rodata_hpage_align as our
marker both because it is huge-page-aligned and it does not contain
any sections we expect to hold secrets.

Kees's logic was that r/o data is in the kernel image anyway and,
in the case of traditional distributions, can be freely downloaded
from the web, so there's no reason to hide it.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reported-by: Kees Cook <keescook@google.com>
Fixes: 8c06c7740 (x86/pti: Leave kernel text global for !PCID)
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
---

 b/arch/x86/mm/pti.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff -puN arch/x86/mm/pti.c~pti-glb-too-much-mapped arch/x86/mm/pti.c
--- a/arch/x86/mm/pti.c~pti-glb-too-much-mapped	2018-04-20 14:10:02.164749166 -0700
+++ b/arch/x86/mm/pti.c	2018-04-20 14:10:02.168749166 -0700
@@ -430,12 +430,24 @@ static inline bool pti_kernel_image_glob
  */
 void pti_clone_kernel_text(void)
 {
+	/*
+	 * rodata is part of the kernel image and is normally
+	 * readable on the filesystem or on the web.  But, do not
+	 * clone the areas past rodata, they might contain secrets.
+	 */
 	unsigned long start = PFN_ALIGN(_text);
-	unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE);
+	unsigned long end = (unsigned long)__end_rodata_hpage_align;
 
 	if (!pti_kernel_image_global_ok())
 		return;
 
+	pr_debug("mapping partial kernel image into user address space\n");
+
+	/*
+	 * Note that this will undo _some_ of the work that
+	 * pti_set_kernel_image_nonglobal() did to clear the
+	 * global bit.
+	 */
 	pti_clone_pmds(start, end, _PAGE_RW);
 }
 
@@ -458,8 +470,6 @@ void pti_set_kernel_image_nonglobal(void
 	if (pti_kernel_image_global_ok())
 		return;
 
-	pr_debug("set kernel image non-global\n");
-
 	set_memory_nonglobal(start, (end - start) >> PAGE_SHIFT);
 }
 
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 4/5] x86, pti: disallow global kernel text with RANDSTRUCT
  2018-04-20 22:20 ` Dave Hansen
@ 2018-04-20 22:20   ` Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, keescook, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, torvalds,
	namit, peterz, tglx, vbabka


I believe this was originally reported by the grsecurity team who
tweeted about it (link below).

RANDSTRUCT derives its hardening benefits from the attacker's lack of
knowledge about the layout of kernel data structures.  Keep the kernel
image non-global in cases where RANDSTRUCT is in use to help keep the
layout a secret.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reported-by: Kees Cook <keescook@google.com>
Link: https://twitter.com/grsecurity/status/985678720630476800
Fixes: 8c06c7740 (x86/pti: Leave kernel text global for !PCID)
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: linux-mm@kvack.org
---

 b/arch/x86/mm/pti.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff -puN arch/x86/mm/pti.c~pti-glb-disable-with-compile-options arch/x86/mm/pti.c
--- a/arch/x86/mm/pti.c~pti-glb-disable-with-compile-options	2018-04-20 14:10:02.702749165 -0700
+++ b/arch/x86/mm/pti.c	2018-04-20 14:10:02.706749165 -0700
@@ -421,6 +421,16 @@ static inline bool pti_kernel_image_glob
 	if (boot_cpu_has(X86_FEATURE_K8))
 		return false;
 
+	/*
+	 * RANDSTRUCT derives its hardening benefits from the
+	 * attacker's lack of knowledge about the layout of kernel
+	 * data structures.  Keep the kernel image non-global in
+	 * cases where RANDSTRUCT is in use to help keep the layout a
+	 * secret.
+	 */
+	if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT))
+		return false;
+
 	return true;
 }
 
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 4/5] x86, pti: disallow global kernel text with RANDSTRUCT
@ 2018-04-20 22:20   ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, keescook, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, torvalds,
	namit, peterz, tglx, vbabka


I believe this was originally reported by the grsecurity team who
tweeted about it (link below).

RANDSTRUCT derives its hardening benefits from the attacker's lack of
knowledge about the layout of kernel data structures.  Keep the kernel
image non-global in cases where RANDSTRUCT is in use to help keep the
layout a secret.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reported-by: Kees Cook <keescook@google.com>
Link: https://twitter.com/grsecurity/status/985678720630476800
Fixes: 8c06c7740 (x86/pti: Leave kernel text global for !PCID)
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: linux-mm@kvack.org
---

 b/arch/x86/mm/pti.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff -puN arch/x86/mm/pti.c~pti-glb-disable-with-compile-options arch/x86/mm/pti.c
--- a/arch/x86/mm/pti.c~pti-glb-disable-with-compile-options	2018-04-20 14:10:02.702749165 -0700
+++ b/arch/x86/mm/pti.c	2018-04-20 14:10:02.706749165 -0700
@@ -421,6 +421,16 @@ static inline bool pti_kernel_image_glob
 	if (boot_cpu_has(X86_FEATURE_K8))
 		return false;
 
+	/*
+	 * RANDSTRUCT derives its hardening benefits from the
+	 * attacker's lack of knowledge about the layout of kernel
+	 * data structures.  Keep the kernel image non-global in
+	 * cases where RANDSTRUCT is in use to help keep the layout a
+	 * secret.
+	 */
+	if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT))
+		return false;
+
 	return true;
 }
 
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 5/5] x86, pti: filter at vma->vm_page_prot population
  2018-04-20 22:20 ` Dave Hansen
@ 2018-04-20 22:20   ` Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, fengguang.wu, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, keescook,
	torvalds, namit, peterz, tglx, mingo


From: Dave Hansen <dave.hansen@linux.intel.com>

0day reported warnings at boot on 32-bit systems without NX support:

 [   12.349193] attempted to set unsupported pgprot: 8000000000000025 bits: 8000000000000000 supported: 7fffffffffffffff
 [   12.350792] WARNING: CPU: 0 PID: 1 at arch/x86/include/asm/pgtable.h:540 handle_mm_fault+0xfc1/0xfe0:
 						check_pgprot at arch/x86/include/asm/pgtable.h:535
 						 (inlined by) pfn_pte at arch/x86/include/asm/pgtable.h:549
 						 (inlined by) do_anonymous_page at mm/memory.c:3169
 						 (inlined by) handle_pte_fault at mm/memory.c:3961
 						 (inlined by) __handle_mm_fault at mm/memory.c:4087
 						 (inlined by) handle_mm_fault at mm/memory.c:4124

The problem was that we stopped massaging page permissions at PTE creation
time, so vma->vm_page_prot was passed unfiltered to PTE creation.

To fix it, filter the page protections before they are installed in
vma->vm_page_prot.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Fixes: fb43d6cb91 ("x86/mm: Do not auto-massage page protections")
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
Cc: Ingo Molnar <mingo@kernel.org>
---

 b/arch/x86/Kconfig               |    4 ++++
 b/arch/x86/include/asm/pgtable.h |    5 +++++
 b/mm/mmap.c                      |   11 ++++++++++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff -puN arch/x86/include/asm/pgtable.h~pti-glb-protection_map arch/x86/include/asm/pgtable.h
--- a/arch/x86/include/asm/pgtable.h~pti-glb-protection_map	2018-04-20 14:10:08.251749151 -0700
+++ b/arch/x86/include/asm/pgtable.h	2018-04-20 14:10:08.260749151 -0700
@@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgp
 
 #define canon_pgprot(p) __pgprot(massage_pgprot(p))
 
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+	return canon_pgprot(prot);
+}
+
 static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
 					 enum page_cache_mode pcm,
 					 enum page_cache_mode new_pcm)
diff -puN arch/x86/Kconfig~pti-glb-protection_map arch/x86/Kconfig
--- a/arch/x86/Kconfig~pti-glb-protection_map	2018-04-20 14:10:08.253749151 -0700
+++ b/arch/x86/Kconfig	2018-04-20 14:10:08.260749151 -0700
@@ -52,6 +52,7 @@ config X86
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FAST_MULTIPLIER
+	select ARCH_HAS_FILTER_PGPROT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV			if X86_64
@@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX
 config ARCH_HAS_CACHE_LINE_SIZE
 	def_bool y
 
+config ARCH_HAS_FILTER_PGPROT
+	def_bool y
+
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
diff -puN mm/mmap.c~pti-glb-protection_map mm/mmap.c
--- a/mm/mmap.c~pti-glb-protection_map	2018-04-20 14:10:08.256749151 -0700
+++ b/mm/mmap.c	2018-04-20 14:10:08.261749151 -0700
@@ -100,11 +100,20 @@ pgprot_t protection_map[16] __ro_after_i
 	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
 };
 
+#ifndef CONFIG_ARCH_HAS_FILTER_PGPROT
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+	return prot;
+}
+#endif
+
 pgprot_t vm_get_page_prot(unsigned long vm_flags)
 {
-	return __pgprot(pgprot_val(protection_map[vm_flags &
+	pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
 				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
 			pgprot_val(arch_vm_get_page_prot(vm_flags)));
+
+	return arch_filter_pgprot(ret);
 }
 EXPORT_SYMBOL(vm_get_page_prot);
 
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 5/5] x86, pti: filter at vma->vm_page_prot population
@ 2018-04-20 22:20   ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-20 22:20 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-mm, Dave Hansen, fengguang.wu, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, keescook,
	torvalds, namit, peterz, tglx, mingo


From: Dave Hansen <dave.hansen@linux.intel.com>

0day reported warnings at boot on 32-bit systems without NX support:

 [   12.349193] attempted to set unsupported pgprot: 8000000000000025 bits: 8000000000000000 supported: 7fffffffffffffff
 [   12.350792] WARNING: CPU: 0 PID: 1 at arch/x86/include/asm/pgtable.h:540 handle_mm_fault+0xfc1/0xfe0:
 						check_pgprot at arch/x86/include/asm/pgtable.h:535
 						 (inlined by) pfn_pte at arch/x86/include/asm/pgtable.h:549
 						 (inlined by) do_anonymous_page at mm/memory.c:3169
 						 (inlined by) handle_pte_fault at mm/memory.c:3961
 						 (inlined by) __handle_mm_fault at mm/memory.c:4087
 						 (inlined by) handle_mm_fault at mm/memory.c:4124

The problem was that we stopped massaging page permissions at PTE creation
time, so vma->vm_page_prot was passed unfiltered to PTE creation.

To fix it, filter the page protections before they are installed in
vma->vm_page_prot.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Fixes: fb43d6cb91 ("x86/mm: Do not auto-massage page protections")
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
Cc: Ingo Molnar <mingo@kernel.org>
---

 b/arch/x86/Kconfig               |    4 ++++
 b/arch/x86/include/asm/pgtable.h |    5 +++++
 b/mm/mmap.c                      |   11 ++++++++++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff -puN arch/x86/include/asm/pgtable.h~pti-glb-protection_map arch/x86/include/asm/pgtable.h
--- a/arch/x86/include/asm/pgtable.h~pti-glb-protection_map	2018-04-20 14:10:08.251749151 -0700
+++ b/arch/x86/include/asm/pgtable.h	2018-04-20 14:10:08.260749151 -0700
@@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgp
 
 #define canon_pgprot(p) __pgprot(massage_pgprot(p))
 
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+	return canon_pgprot(prot);
+}
+
 static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
 					 enum page_cache_mode pcm,
 					 enum page_cache_mode new_pcm)
diff -puN arch/x86/Kconfig~pti-glb-protection_map arch/x86/Kconfig
--- a/arch/x86/Kconfig~pti-glb-protection_map	2018-04-20 14:10:08.253749151 -0700
+++ b/arch/x86/Kconfig	2018-04-20 14:10:08.260749151 -0700
@@ -52,6 +52,7 @@ config X86
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FAST_MULTIPLIER
+	select ARCH_HAS_FILTER_PGPROT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV			if X86_64
@@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX
 config ARCH_HAS_CACHE_LINE_SIZE
 	def_bool y
 
+config ARCH_HAS_FILTER_PGPROT
+	def_bool y
+
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
diff -puN mm/mmap.c~pti-glb-protection_map mm/mmap.c
--- a/mm/mmap.c~pti-glb-protection_map	2018-04-20 14:10:08.256749151 -0700
+++ b/mm/mmap.c	2018-04-20 14:10:08.261749151 -0700
@@ -100,11 +100,20 @@ pgprot_t protection_map[16] __ro_after_i
 	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
 };
 
+#ifndef CONFIG_ARCH_HAS_FILTER_PGPROT
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+	return prot;
+}
+#endif
+
 pgprot_t vm_get_page_prot(unsigned long vm_flags)
 {
-	return __pgprot(pgprot_val(protection_map[vm_flags &
+	pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
 				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
 			pgprot_val(arch_vm_get_page_prot(vm_flags)));
+
+	return arch_filter_pgprot(ret);
 }
 EXPORT_SYMBOL(vm_get_page_prot);
 
_

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 5/5] x86, pti: filter at vma->vm_page_prot population
  2018-04-20 22:20   ` Dave Hansen
  (?)
@ 2018-04-21  1:21   ` Nadav Amit
  2018-04-23 11:37       ` Dave Hansen
  -1 siblings, 1 reply; 29+ messages in thread
From: Nadav Amit @ 2018-04-21  1:21 UTC (permalink / raw)
  To: Dave Hansen
  Cc: LKML, open list:MEMORY MANAGEMENT, Fengguang Wu,
	Andrea Arcangeli, Andy Lutomirski, Arjan van de Ven,
	Borislav Petkov, Dan Williams, David Woodhouse,
	Greg Kroah-Hartman, hughd, jpoimboe, jgross, keescook, torvalds,
	peterz, tglx, mingo

Dave Hansen <dave.hansen@linux.intel.com> wrote:

> 
> From: Dave Hansen <dave.hansen@linux.intel.com>
> 
> 0day reported warnings at boot on 32-bit systems without NX support:
> 
> [   12.349193] attempted to set unsupported pgprot: 8000000000000025 bits: 8000000000000000 supported: 7fffffffffffffff
> [   12.350792] WARNING: CPU: 0 PID: 1 at arch/x86/include/asm/pgtable.h:540 handle_mm_fault+0xfc1/0xfe0:
> 						check_pgprot at arch/x86/include/asm/pgtable.h:535
> 						 (inlined by) pfn_pte at arch/x86/include/asm/pgtable.h:549
> 						 (inlined by) do_anonymous_page at mm/memory.c:3169
> 						 (inlined by) handle_pte_fault at mm/memory.c:3961
> 						 (inlined by) __handle_mm_fault at mm/memory.c:4087
> 						 (inlined by) handle_mm_fault at mm/memory.c:4124
> 
> The problem was that we stopped massaging page permissions at PTE creation
> time, so vma->vm_page_prot was passed unfiltered to PTE creation.
> 
> To fix it, filter the page protections before they are installed in
> vma->vm_page_prot.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> Reported-by: Fengguang Wu <fengguang.wu@intel.com>
> Fixes: fb43d6cb91 ("x86/mm: Do not auto-massage page protections")
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Arjan van de Ven <arjan@linux.intel.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> Cc: Juergen Gross <jgross@suse.com>
> Cc: Kees Cook <keescook@google.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Nadav Amit <namit@vmware.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mm@kvack.org
> Cc: Ingo Molnar <mingo@kernel.org>
> ---
> 
> b/arch/x86/Kconfig               |    4 ++++
> b/arch/x86/include/asm/pgtable.h |    5 +++++
> b/mm/mmap.c                      |   11 ++++++++++-
> 3 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff -puN arch/x86/include/asm/pgtable.h~pti-glb-protection_map arch/x86/include/asm/pgtable.h
> --- a/arch/x86/include/asm/pgtable.h~pti-glb-protection_map	2018-04-20 14:10:08.251749151 -0700
> +++ b/arch/x86/include/asm/pgtable.h	2018-04-20 14:10:08.260749151 -0700
> @@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgp
> 
> #define canon_pgprot(p) __pgprot(massage_pgprot(p))
> 
> +static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
> +{
> +	return canon_pgprot(prot);
> +}
> +
> static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
> 					 enum page_cache_mode pcm,
> 					 enum page_cache_mode new_pcm)
> diff -puN arch/x86/Kconfig~pti-glb-protection_map arch/x86/Kconfig
> --- a/arch/x86/Kconfig~pti-glb-protection_map	2018-04-20 14:10:08.253749151 -0700
> +++ b/arch/x86/Kconfig	2018-04-20 14:10:08.260749151 -0700
> @@ -52,6 +52,7 @@ config X86
> 	select ARCH_HAS_DEVMEM_IS_ALLOWED
> 	select ARCH_HAS_ELF_RANDOMIZE
> 	select ARCH_HAS_FAST_MULTIPLIER
> +	select ARCH_HAS_FILTER_PGPROT
> 	select ARCH_HAS_FORTIFY_SOURCE
> 	select ARCH_HAS_GCOV_PROFILE_ALL
> 	select ARCH_HAS_KCOV			if X86_64
> @@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX
> config ARCH_HAS_CACHE_LINE_SIZE
> 	def_bool y
> 
> +config ARCH_HAS_FILTER_PGPROT
> +	def_bool y
> +
> config HAVE_SETUP_PER_CPU_AREA
> 	def_bool y
> 
> diff -puN mm/mmap.c~pti-glb-protection_map mm/mmap.c
> --- a/mm/mmap.c~pti-glb-protection_map	2018-04-20 14:10:08.256749151 -0700
> +++ b/mm/mmap.c	2018-04-20 14:10:08.261749151 -0700
> @@ -100,11 +100,20 @@ pgprot_t protection_map[16] __ro_after_i
> 	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
> };
> 
> +#ifndef CONFIG_ARCH_HAS_FILTER_PGPROT
> +static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
> +{
> +	return prot;
> +}
> +#endif
> +
> pgprot_t vm_get_page_prot(unsigned long vm_flags)
> {
> -	return __pgprot(pgprot_val(protection_map[vm_flags &
> +	pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
> 				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
> 			pgprot_val(arch_vm_get_page_prot(vm_flags)));
> +
> +	return arch_filter_pgprot(ret);
> }
> EXPORT_SYMBOL(vm_get_page_prot);

Wouldn’t it be simpler or at least cleaner to change the protection map if
NX is not supported? I presume it can be done paging_init() similarly to the
way other archs (e.g., arm, mips) do.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] x86, pti: fix boot problems from Global-bit setting
  2018-04-20 22:20   ` Dave Hansen
@ 2018-04-23 10:50     ` Aaro Koskinen
  -1 siblings, 0 replies; 29+ messages in thread
From: Aaro Koskinen @ 2018-04-23 10:50 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, linux-mm, mceier, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, keescook,
	torvalds, namit, peterz, tglx

Hi,

On Fri, Apr 20, 2018 at 03:20:19PM -0700, Dave Hansen wrote:
> Part of the global bit _setting_ patches also includes clearing the
> Global bit when we do not want it.  That is done with
> set_memory_nonglobal(), which uses change_page_attr_clear() in
> pageattr.c under the covers.
> 
> The TLB flushing code inside pageattr.c has has checks like
> BUG_ON(irqs_disabled()), looking for interrupt disabling that might
> cause deadlocks.  But, these also trip in early boot on certain
> preempt configurations.  Just copy the existing BUG_ON() sequence from
> cpa_flush_range() to the other two sites and check for early boot.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
> Reported-by: Mariusz Ceier <mceier@gmail.com>
> Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>

Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>

A.

> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Arjan van de Ven <arjan@linux.intel.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> Cc: Juergen Gross <jgross@suse.com>
> Cc: Kees Cook <keescook@google.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Nadav Amit <namit@vmware.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mm@kvack.org
> ---
> 
>  b/arch/x86/mm/pageattr.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff -puN arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix arch/x86/mm/pageattr.c
> --- a/arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix	2018-04-20 14:10:01.086749169 -0700
> +++ b/arch/x86/mm/pageattr.c	2018-04-20 14:10:01.090749169 -0700
> @@ -172,7 +172,7 @@ static void __cpa_flush_all(void *arg)
>  
>  static void cpa_flush_all(unsigned long cache)
>  {
> -	BUG_ON(irqs_disabled());
> +	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
>  
>  	on_each_cpu(__cpa_flush_all, (void *) cache, 1);
>  }
> @@ -236,7 +236,7 @@ static void cpa_flush_array(unsigned lon
>  	unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
>  #endif
>  
> -	BUG_ON(irqs_disabled());
> +	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
>  
>  	on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
>  
> _

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] x86, pti: fix boot problems from Global-bit setting
@ 2018-04-23 10:50     ` Aaro Koskinen
  0 siblings, 0 replies; 29+ messages in thread
From: Aaro Koskinen @ 2018-04-23 10:50 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, linux-mm, mceier, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, keescook,
	torvalds, namit, peterz, tglx

Hi,

On Fri, Apr 20, 2018 at 03:20:19PM -0700, Dave Hansen wrote:
> Part of the global bit _setting_ patches also includes clearing the
> Global bit when we do not want it.  That is done with
> set_memory_nonglobal(), which uses change_page_attr_clear() in
> pageattr.c under the covers.
> 
> The TLB flushing code inside pageattr.c has has checks like
> BUG_ON(irqs_disabled()), looking for interrupt disabling that might
> cause deadlocks.  But, these also trip in early boot on certain
> preempt configurations.  Just copy the existing BUG_ON() sequence from
> cpa_flush_range() to the other two sites and check for early boot.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
> Reported-by: Mariusz Ceier <mceier@gmail.com>
> Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>

Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>

A.

> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Arjan van de Ven <arjan@linux.intel.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> Cc: Juergen Gross <jgross@suse.com>
> Cc: Kees Cook <keescook@google.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Nadav Amit <namit@vmware.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mm@kvack.org
> ---
> 
>  b/arch/x86/mm/pageattr.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff -puN arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix arch/x86/mm/pageattr.c
> --- a/arch/x86/mm/pageattr.c~pti-glb-boot-problem-fix	2018-04-20 14:10:01.086749169 -0700
> +++ b/arch/x86/mm/pageattr.c	2018-04-20 14:10:01.090749169 -0700
> @@ -172,7 +172,7 @@ static void __cpa_flush_all(void *arg)
>  
>  static void cpa_flush_all(unsigned long cache)
>  {
> -	BUG_ON(irqs_disabled());
> +	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
>  
>  	on_each_cpu(__cpa_flush_all, (void *) cache, 1);
>  }
> @@ -236,7 +236,7 @@ static void cpa_flush_array(unsigned lon
>  	unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
>  #endif
>  
> -	BUG_ON(irqs_disabled());
> +	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
>  
>  	on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
>  
> _

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] x86, pti: fix boot warning from Global-bit setting
  2018-04-20 22:20   ` Dave Hansen
@ 2018-04-23 10:51     ` Aaro Koskinen
  -1 siblings, 0 replies; 29+ messages in thread
From: Aaro Koskinen @ 2018-04-23 10:51 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, linux-mm, mceier, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, keescook,
	torvalds, namit, peterz, tglx

Hi,

On Fri, Apr 20, 2018 at 03:20:21PM -0700, Dave Hansen wrote:
> The pageattr.c code attempts to process "faults" when it goes looking
> for PTEs to change and finds non-present entries.  It allows these
> faults in the linear map which is "expected to have holes", but
> WARN()s about them elsewhere, like when called on the kernel image.
> 
> However, we are now calling change_page_attr_clear() on the kernel
> image in the process of trying to clear the Global bit.
> 
> This trips the warning in __cpa_process_fault() if a non-present PTE is
> encountered in the kernel image.  The "holes" in the kernel image
> result from free_init_pages()'s use of set_memory_np().  These holes
> are totally fine, and result from normal operation, just as they would
> be in the kernel linear map.
> 
> Just silence the warning when holes in the kernel image are encountered.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
> Reported-by: Mariusz Ceier <mceier@gmail.com>
> Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>

Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>

A.

> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Arjan van de Ven <arjan@linux.intel.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> Cc: Juergen Gross <jgross@suse.com>
> Cc: Kees Cook <keescook@google.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Nadav Amit <namit@vmware.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mm@kvack.org
> ---
> 
>  b/arch/x86/mm/pageattr.c |   41 +++++++++++++++++++++++++++++++----------
>  1 file changed, 31 insertions(+), 10 deletions(-)
> 
> diff -puN arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr arch/x86/mm/pageattr.c
> --- a/arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr	2018-04-20 14:10:01.619749168 -0700
> +++ b/arch/x86/mm/pageattr.c	2018-04-20 14:10:01.623749168 -0700
> @@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file
>  static inline void split_page_count(int level) { }
>  #endif
>  
> +static inline int
> +within(unsigned long addr, unsigned long start, unsigned long end)
> +{
> +	return addr >= start && addr < end;
> +}
> +
> +static inline int
> +within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
> +{
> +	return addr >= start && addr <= end;
> +}
> +
>  #ifdef CONFIG_X86_64
>  
>  static inline unsigned long highmap_start_pfn(void)
> @@ -106,20 +118,26 @@ static inline unsigned long highmap_end_
>  	return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
>  }
>  
> -#endif
> -
> -static inline int
> -within(unsigned long addr, unsigned long start, unsigned long end)
> +static bool __cpa_pfn_in_highmap(unsigned long pfn)
>  {
> -	return addr >= start && addr < end;
> +	/*
> +	 * Kernel text has an alias mapping at a high address, known
> +	 * here as "highmap".
> +	 */
> +	return within_inclusive(pfn, highmap_start_pfn(),
> +			highmap_end_pfn());
>  }
>  
> -static inline int
> -within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
> +#else
> +
> +static bool __cpa_pfn_in_highmap(unsigned long pfn)
>  {
> -	return addr >= start && addr <= end;
> +	/* There is no highmap on 32-bit */
> +	return false;
>  }
>  
> +#endif
> +
>  /*
>   * Flushing functions
>   */
> @@ -1183,6 +1201,10 @@ static int __cpa_process_fault(struct cp
>  		cpa->numpages = 1;
>  		cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
>  		return 0;
> +
> +	} else if (__cpa_pfn_in_highmap(cpa->pfn)) {
> +		/* Faults in the highmap are OK, so do not warn: */
> +		return -EFAULT;
>  	} else {
>  		WARN(1, KERN_WARNING "CPA: called for zero pte. "
>  			"vaddr = %lx cpa->vaddr = %lx\n", vaddr,
> @@ -1335,8 +1357,7 @@ static int cpa_process_alias(struct cpa_
>  	 * to touch the high mapped kernel as well:
>  	 */
>  	if (!within(vaddr, (unsigned long)_text, _brk_end) &&
> -	    within_inclusive(cpa->pfn, highmap_start_pfn(),
> -			     highmap_end_pfn())) {
> +	    __cpa_pfn_in_highmap(cpa->pfn)) {
>  		unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
>  					       __START_KERNEL_map - phys_base;
>  		alias_cpa = *cpa;
> _

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] x86, pti: fix boot warning from Global-bit setting
@ 2018-04-23 10:51     ` Aaro Koskinen
  0 siblings, 0 replies; 29+ messages in thread
From: Aaro Koskinen @ 2018-04-23 10:51 UTC (permalink / raw)
  To: Dave Hansen
  Cc: linux-kernel, linux-mm, mceier, aarcange, luto, arjan, bp,
	dan.j.williams, dwmw2, gregkh, hughd, jpoimboe, jgross, keescook,
	torvalds, namit, peterz, tglx

Hi,

On Fri, Apr 20, 2018 at 03:20:21PM -0700, Dave Hansen wrote:
> The pageattr.c code attempts to process "faults" when it goes looking
> for PTEs to change and finds non-present entries.  It allows these
> faults in the linear map which is "expected to have holes", but
> WARN()s about them elsewhere, like when called on the kernel image.
> 
> However, we are now calling change_page_attr_clear() on the kernel
> image in the process of trying to clear the Global bit.
> 
> This trips the warning in __cpa_process_fault() if a non-present PTE is
> encountered in the kernel image.  The "holes" in the kernel image
> result from free_init_pages()'s use of set_memory_np().  These holes
> are totally fine, and result from normal operation, just as they would
> be in the kernel linear map.
> 
> Just silence the warning when holes in the kernel image are encountered.
> 
> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
> Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
> Reported-by: Mariusz Ceier <mceier@gmail.com>
> Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>

Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>

A.

> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Arjan van de Ven <arjan@linux.intel.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> Cc: Juergen Gross <jgross@suse.com>
> Cc: Kees Cook <keescook@google.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Nadav Amit <namit@vmware.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: linux-mm@kvack.org
> ---
> 
>  b/arch/x86/mm/pageattr.c |   41 +++++++++++++++++++++++++++++++----------
>  1 file changed, 31 insertions(+), 10 deletions(-)
> 
> diff -puN arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr arch/x86/mm/pageattr.c
> --- a/arch/x86/mm/pageattr.c~pti-glb-warning-inpageattr	2018-04-20 14:10:01.619749168 -0700
> +++ b/arch/x86/mm/pageattr.c	2018-04-20 14:10:01.623749168 -0700
> @@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file
>  static inline void split_page_count(int level) { }
>  #endif
>  
> +static inline int
> +within(unsigned long addr, unsigned long start, unsigned long end)
> +{
> +	return addr >= start && addr < end;
> +}
> +
> +static inline int
> +within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
> +{
> +	return addr >= start && addr <= end;
> +}
> +
>  #ifdef CONFIG_X86_64
>  
>  static inline unsigned long highmap_start_pfn(void)
> @@ -106,20 +118,26 @@ static inline unsigned long highmap_end_
>  	return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
>  }
>  
> -#endif
> -
> -static inline int
> -within(unsigned long addr, unsigned long start, unsigned long end)
> +static bool __cpa_pfn_in_highmap(unsigned long pfn)
>  {
> -	return addr >= start && addr < end;
> +	/*
> +	 * Kernel text has an alias mapping at a high address, known
> +	 * here as "highmap".
> +	 */
> +	return within_inclusive(pfn, highmap_start_pfn(),
> +			highmap_end_pfn());
>  }
>  
> -static inline int
> -within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
> +#else
> +
> +static bool __cpa_pfn_in_highmap(unsigned long pfn)
>  {
> -	return addr >= start && addr <= end;
> +	/* There is no highmap on 32-bit */
> +	return false;
>  }
>  
> +#endif
> +
>  /*
>   * Flushing functions
>   */
> @@ -1183,6 +1201,10 @@ static int __cpa_process_fault(struct cp
>  		cpa->numpages = 1;
>  		cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
>  		return 0;
> +
> +	} else if (__cpa_pfn_in_highmap(cpa->pfn)) {
> +		/* Faults in the highmap are OK, so do not warn: */
> +		return -EFAULT;
>  	} else {
>  		WARN(1, KERN_WARNING "CPA: called for zero pte. "
>  			"vaddr = %lx cpa->vaddr = %lx\n", vaddr,
> @@ -1335,8 +1357,7 @@ static int cpa_process_alias(struct cpa_
>  	 * to touch the high mapped kernel as well:
>  	 */
>  	if (!within(vaddr, (unsigned long)_text, _brk_end) &&
> -	    within_inclusive(cpa->pfn, highmap_start_pfn(),
> -			     highmap_end_pfn())) {
> +	    __cpa_pfn_in_highmap(cpa->pfn)) {
>  		unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
>  					       __START_KERNEL_map - phys_base;
>  		alias_cpa = *cpa;
> _

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 5/5] x86, pti: filter at vma->vm_page_prot population
  2018-04-21  1:21   ` Nadav Amit
@ 2018-04-23 11:37       ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-23 11:37 UTC (permalink / raw)
  To: Nadav Amit
  Cc: LKML, open list:MEMORY MANAGEMENT, Fengguang Wu,
	Andrea Arcangeli, Andy Lutomirski, Arjan van de Ven,
	Borislav Petkov, Dan Williams, David Woodhouse,
	Greg Kroah-Hartman, hughd, jpoimboe, jgross, keescook, torvalds,
	peterz, tglx, mingo

On 04/20/2018 06:21 PM, Nadav Amit wrote:
>> pgprot_t vm_get_page_prot(unsigned long vm_flags)
>> {
>> -	return __pgprot(pgprot_val(protection_map[vm_flags &
>> +	pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
>> 				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
>> 			pgprot_val(arch_vm_get_page_prot(vm_flags)));
>> +
>> +	return arch_filter_pgprot(ret);
>> }
>> EXPORT_SYMBOL(vm_get_page_prot);
> Wouldn’t it be simpler or at least cleaner to change the protection map if
> NX is not supported? I presume it can be done paging_init() similarly to the
> way other archs (e.g., arm, mips) do.

I thought about it, but doing it there requires getting the _timing_
right.  You have to do it before the protection map gets used but after
__supported_pte_mask is totally initialized.  This seemed more
straightforward, especially as a bug fix.

What you are talking about might be a good cleanup, though.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 5/5] x86, pti: filter at vma->vm_page_prot population
@ 2018-04-23 11:37       ` Dave Hansen
  0 siblings, 0 replies; 29+ messages in thread
From: Dave Hansen @ 2018-04-23 11:37 UTC (permalink / raw)
  To: Nadav Amit
  Cc: LKML, open list:MEMORY MANAGEMENT, Fengguang Wu,
	Andrea Arcangeli, Andy Lutomirski, Arjan van de Ven,
	Borislav Petkov, Dan Williams, David Woodhouse,
	Greg Kroah-Hartman, hughd, jpoimboe, jgross, keescook, torvalds,
	peterz, tglx, mingo

On 04/20/2018 06:21 PM, Nadav Amit wrote:
>> pgprot_t vm_get_page_prot(unsigned long vm_flags)
>> {
>> -	return __pgprot(pgprot_val(protection_map[vm_flags &
>> +	pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
>> 				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
>> 			pgprot_val(arch_vm_get_page_prot(vm_flags)));
>> +
>> +	return arch_filter_pgprot(ret);
>> }
>> EXPORT_SYMBOL(vm_get_page_prot);
> Wouldna??t it be simpler or at least cleaner to change the protection map if
> NX is not supported? I presume it can be done paging_init() similarly to the
> way other archs (e.g., arm, mips) do.

I thought about it, but doing it there requires getting the _timing_
right.  You have to do it before the protection map gets used but after
__supported_pte_mask is totally initialized.  This seemed more
straightforward, especially as a bug fix.

What you are talking about might be a good cleanup, though.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86/pti: Fix boot problems from Global-bit setting
  2018-04-20 22:20   ` Dave Hansen
  (?)
  (?)
@ 2018-04-24  8:06   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-24  8:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: luto, keescook, dan.j.williams, namit, jpoimboe, arjan, tglx,
	dave.hansen, linux-kernel, aarcange, bp, aaro.koskinen, hpa,
	mingo, peterz, dwmw2, jgross, mceier, gregkh, torvalds, hughd

Commit-ID:  16dce603adc9de4237b7bf2ff5c5290f34373e7b
Gitweb:     https://git.kernel.org/tip/16dce603adc9de4237b7bf2ff5c5290f34373e7b
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:19 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 24 Apr 2018 09:50:53 +0200

x86/pti: Fix boot problems from Global-bit setting

Part of the global bit _setting_ patches also includes clearing the
Global bit when it should not be enabled.  That is done with
set_memory_nonglobal(), which uses change_page_attr_clear() in
pageattr.c under the covers.

The TLB flushing code inside pageattr.c has has checks like
BUG_ON(irqs_disabled()), looking for interrupt disabling that might
cause deadlocks.  But, these also trip in early boot on certain
preempt configurations.  Just copy the existing BUG_ON() sequence from
cpa_flush_range() to the other two sites and check for early boot.

Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
Reported-by: Mariusz Ceier <mceier@gmail.com>
Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Nadav Amit <namit@vmware.com>
Cc: Kees Cook <keescook@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: https://lkml.kernel.org/r/20180420222019.20C4A410@viggo.jf.intel.com

---
 arch/x86/mm/pageattr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 0f3d50f4c48c..4fadfd2b7017 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -172,7 +172,7 @@ static void __cpa_flush_all(void *arg)
 
 static void cpa_flush_all(unsigned long cache)
 {
-	BUG_ON(irqs_disabled());
+	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
 	on_each_cpu(__cpa_flush_all, (void *) cache, 1);
 }
@@ -236,7 +236,7 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache,
 	unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
 #endif
 
-	BUG_ON(irqs_disabled());
+	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
 	on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86/pti: Fix boot warning from Global-bit setting
  2018-04-20 22:20   ` Dave Hansen
  (?)
  (?)
@ 2018-04-24  8:07   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-24  8:07 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jgross, dave.hansen, namit, linux-kernel, gregkh, hpa,
	aaro.koskinen, mingo, jpoimboe, torvalds, mceier, dan.j.williams,
	dwmw2, hughd, bp, tglx, aarcange, luto, keescook, peterz, arjan

Commit-ID:  231df823c4f04176f607afc4576c989895cff40e
Gitweb:     https://git.kernel.org/tip/231df823c4f04176f607afc4576c989895cff40e
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:21 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 24 Apr 2018 09:50:53 +0200

x86/pti: Fix boot warning from Global-bit setting

The pageattr.c code attempts to process "faults" when it goes looking
for PTEs to change and finds non-present entries.  It allows these
faults in the linear map which is "expected to have holes", but
WARN()s about them elsewhere, like when called on the kernel image.

However, change_page_attr_clear() is now called on the kernel image in the
process of trying to clear the Global bit.

This trips the warning in __cpa_process_fault() if a non-present PTE is
encountered in the kernel image.  The "holes" in the kernel image result
from free_init_pages()'s use of set_memory_np().  These holes are totally
fine, and result from normal operation, just as they would be in the kernel
linear map.

Just silence the warning when holes in the kernel image are encountered.

Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
Reported-by: Mariusz Ceier <mceier@gmail.com>
Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Nadav Amit <namit@vmware.com>
Cc: Kees Cook <keescook@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: https://lkml.kernel.org/r/20180420222021.1C7D2B3F@viggo.jf.intel.com

---
 arch/x86/mm/pageattr.c | 40 ++++++++++++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 4fadfd2b7017..3bded76e8d5c 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file *m)
 static inline void split_page_count(int level) { }
 #endif
 
+static inline int
+within(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr < end;
+}
+
+static inline int
+within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr <= end;
+}
+
 #ifdef CONFIG_X86_64
 
 static inline unsigned long highmap_start_pfn(void)
@@ -106,20 +118,25 @@ static inline unsigned long highmap_end_pfn(void)
 	return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
 }
 
-#endif
-
-static inline int
-within(unsigned long addr, unsigned long start, unsigned long end)
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-	return addr >= start && addr < end;
+	/*
+	 * Kernel text has an alias mapping at a high address, known
+	 * here as "highmap".
+	 */
+	return within_inclusive(pfn, highmap_start_pfn(), highmap_end_pfn());
 }
 
-static inline int
-within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+#else
+
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-	return addr >= start && addr <= end;
+	/* There is no highmap on 32-bit */
+	return false;
 }
 
+#endif
+
 /*
  * Flushing functions
  */
@@ -1183,6 +1200,10 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
 		cpa->numpages = 1;
 		cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
 		return 0;
+
+	} else if (__cpa_pfn_in_highmap(cpa->pfn)) {
+		/* Faults in the highmap are OK, so do not warn: */
+		return -EFAULT;
 	} else {
 		WARN(1, KERN_WARNING "CPA: called for zero pte. "
 			"vaddr = %lx cpa->vaddr = %lx\n", vaddr,
@@ -1335,8 +1356,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
 	 * to touch the high mapped kernel as well:
 	 */
 	if (!within(vaddr, (unsigned long)_text, _brk_end) &&
-	    within_inclusive(cpa->pfn, highmap_start_pfn(),
-			     highmap_end_pfn())) {
+	    __cpa_pfn_in_highmap(cpa->pfn)) {
 		unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
 					       __START_KERNEL_map - phys_base;
 		alias_cpa = *cpa;

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86, pti: Reduce amount of kernel text allowed to be Global
  2018-04-20 22:20   ` Dave Hansen
  (?)
@ 2018-04-24  8:08   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-24  8:08 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: arjan, tglx, linux-kernel, dave.hansen, hughd, mingo, aarcange,
	hpa, dan.j.williams, luto, gregkh, bp, namit, jpoimboe, peterz,
	jgross, dwmw2, torvalds, keescook

Commit-ID:  abb67605203687c8b7943d760638d0301787f8d9
Gitweb:     https://git.kernel.org/tip/abb67605203687c8b7943d760638d0301787f8d9
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:23 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 24 Apr 2018 09:50:54 +0200

x86, pti: Reduce amount of kernel text allowed to be Global

Kees reported to me that I made too much of the kernel image global.
It was far more than just text:

	I think this is too much set global: _end is after data,
	bss, and brk, and all kinds of other stuff that could
	hold secrets. I think this should match what
	mark_rodata_ro() is doing.

This does exactly that.  We use __end_rodata_hpage_align as our
marker both because it is huge-page-aligned and it does not contain
any sections we expect to hold secrets.

Kees's logic was that r/o data is in the kernel image anyway and,
in the case of traditional distributions, can be freely downloaded
from the web, so there's no reason to hide it.

Fixes: 8c06c7740 (x86/pti: Leave kernel text global for !PCID)
Reported-by: Kees Cook <keescook@google.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: https://lkml.kernel.org/r/20180420222023.1C8B2B20@viggo.jf.intel.com

---
 arch/x86/mm/pti.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
index f1fd52f449e0..ae3eb4f5d53b 100644
--- a/arch/x86/mm/pti.c
+++ b/arch/x86/mm/pti.c
@@ -430,12 +430,24 @@ static inline bool pti_kernel_image_global_ok(void)
  */
 void pti_clone_kernel_text(void)
 {
+	/*
+	 * rodata is part of the kernel image and is normally
+	 * readable on the filesystem or on the web.  But, do not
+	 * clone the areas past rodata, they might contain secrets.
+	 */
 	unsigned long start = PFN_ALIGN(_text);
-	unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE);
+	unsigned long end = (unsigned long)__end_rodata_hpage_align;
 
 	if (!pti_kernel_image_global_ok())
 		return;
 
+	pr_debug("mapping partial kernel image into user address space\n");
+
+	/*
+	 * Note that this will undo _some_ of the work that
+	 * pti_set_kernel_image_nonglobal() did to clear the
+	 * global bit.
+	 */
 	pti_clone_pmds(start, end, _PAGE_RW);
 }
 
@@ -458,8 +470,6 @@ void pti_set_kernel_image_nonglobal(void)
 	if (pti_kernel_image_global_ok())
 		return;
 
-	pr_debug("set kernel image non-global\n");
-
 	set_memory_nonglobal(start, (end - start) >> PAGE_SHIFT);
 }
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86/pti: Disallow global kernel text with RANDSTRUCT
  2018-04-20 22:20   ` Dave Hansen
  (?)
@ 2018-04-24  8:08   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-24  8:08 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: vbabka, torvalds, jgross, tglx, peterz, hughd, aarcange,
	dan.j.williams, jpoimboe, namit, gregkh, dwmw2, arjan,
	linux-kernel, luto, dave.hansen, mingo, keescook, bp, hpa

Commit-ID:  26d35ca6c3776784f8156e1d6f80cc60d9a2a915
Gitweb:     https://git.kernel.org/tip/26d35ca6c3776784f8156e1d6f80cc60d9a2a915
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:26 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 24 Apr 2018 09:50:54 +0200

x86/pti: Disallow global kernel text with RANDSTRUCT

RANDSTRUCT derives its hardening benefits from the attacker's lack of
knowledge about the layout of kernel data structures.  Keep the kernel
image non-global in cases where RANDSTRUCT is in use to help keep the
layout a secret.

Fixes: 8c06c7740 (x86/pti: Leave kernel text global for !PCID)
Reported-by: Kees Cook <keescook@google.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Link: https://lkml.kernel.org/r/20180420222026.D0B4AAC9@viggo.jf.intel.com

---
 arch/x86/mm/pti.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
index ae3eb4f5d53b..4d418e705878 100644
--- a/arch/x86/mm/pti.c
+++ b/arch/x86/mm/pti.c
@@ -421,6 +421,16 @@ static inline bool pti_kernel_image_global_ok(void)
 	if (boot_cpu_has(X86_FEATURE_K8))
 		return false;
 
+	/*
+	 * RANDSTRUCT derives its hardening benefits from the
+	 * attacker's lack of knowledge about the layout of kernel
+	 * data structures.  Keep the kernel image non-global in
+	 * cases where RANDSTRUCT is in use to help keep the layout a
+	 * secret.
+	 */
+	if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT))
+		return false;
+
 	return true;
 }
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86, pti: Filter at vma->vm_page_prot population
  2018-04-20 22:20   ` Dave Hansen
  (?)
  (?)
@ 2018-04-24  8:09   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-24  8:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: torvalds, dan.j.williams, hughd, dwmw2, jpoimboe, bp, jgross,
	gregkh, aarcange, linux-kernel, dave.hansen, tglx, mingo, namit,
	hpa, luto, fengguang.wu, keescook, peterz, arjan

Commit-ID:  ce9962bf7e22bb3891655c349faff618922d4a73
Gitweb:     https://git.kernel.org/tip/ce9962bf7e22bb3891655c349faff618922d4a73
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:28 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Tue, 24 Apr 2018 09:50:54 +0200

x86, pti: Filter at vma->vm_page_prot population

0day reported warnings at boot on 32-bit systems without NX support:

attempted to set unsupported pgprot: 8000000000000025 bits: 8000000000000000 supported: 7fffffffffffffff
WARNING: CPU: 0 PID: 1 at
arch/x86/include/asm/pgtable.h:540 handle_mm_fault+0xfc1/0xfe0:
 check_pgprot at arch/x86/include/asm/pgtable.h:535
 (inlined by) pfn_pte at arch/x86/include/asm/pgtable.h:549
 (inlined by) do_anonymous_page at mm/memory.c:3169
 (inlined by) handle_pte_fault at mm/memory.c:3961
 (inlined by) __handle_mm_fault at mm/memory.c:4087
 (inlined by) handle_mm_fault at mm/memory.c:4124

The problem is that due to the recent commit which removed auto-massaging
of page protections, filtering page permissions at PTE creation time is not
longer done, so vma->vm_page_prot is passed unfiltered to PTE creation.

Filter the page protections before they are installed in vma->vm_page_prot.

Fixes: fb43d6cb91 ("x86/mm: Do not auto-massage page protections")
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: https://lkml.kernel.org/r/20180420222028.99D72858@viggo.jf.intel.com

---
 arch/x86/Kconfig               |  4 ++++
 arch/x86/include/asm/pgtable.h |  5 +++++
 mm/mmap.c                      | 11 ++++++++++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 00fcf81f2c56..c07f492b871a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -52,6 +52,7 @@ config X86
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FAST_MULTIPLIER
+	select ARCH_HAS_FILTER_PGPROT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV			if X86_64
@@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX
 config ARCH_HAS_CACHE_LINE_SIZE
 	def_bool y
 
+config ARCH_HAS_FILTER_PGPROT
+	def_bool y
+
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 5f49b4ff0c24..f1633de5a675 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
 
 #define canon_pgprot(p) __pgprot(massage_pgprot(p))
 
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+	return canon_pgprot(prot);
+}
+
 static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
 					 enum page_cache_mode pcm,
 					 enum page_cache_mode new_pcm)
diff --git a/mm/mmap.c b/mm/mmap.c
index 188f195883b9..9d5968d1e8e3 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -100,11 +100,20 @@ pgprot_t protection_map[16] __ro_after_init = {
 	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
 };
 
+#ifndef CONFIG_ARCH_HAS_FILTER_PGPROT
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+	return prot;
+}
+#endif
+
 pgprot_t vm_get_page_prot(unsigned long vm_flags)
 {
-	return __pgprot(pgprot_val(protection_map[vm_flags &
+	pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
 				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
 			pgprot_val(arch_vm_get_page_prot(vm_flags)));
+
+	return arch_filter_pgprot(ret);
 }
 EXPORT_SYMBOL(vm_get_page_prot);
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86/pti: Fix boot problems from Global-bit setting
  2018-04-20 22:20   ` Dave Hansen
                     ` (2 preceding siblings ...)
  (?)
@ 2018-04-25  9:06   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-25  9:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: gregkh, dave.hansen, aaro.koskinen, mceier, dan.j.williams,
	hughd, jpoimboe, bp, namit, hpa, luto, peterz, keescook, arjan,
	mingo, tglx, jgross, aarcange, dwmw2, torvalds, linux-kernel

Commit-ID:  d2479a30499d93377d3ab10b7822bc5f10ed7f22
Gitweb:     https://git.kernel.org/tip/d2479a30499d93377d3ab10b7822bc5f10ed7f22
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:19 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 25 Apr 2018 11:02:50 +0200

x86/pti: Fix boot problems from Global-bit setting

commit 16dce603adc9de4237b7bf2ff5c5290f34373e7b

Part of the global bit _setting_ patches also includes clearing the
Global bit when it should not be enabled.  That is done with
set_memory_nonglobal(), which uses change_page_attr_clear() in
pageattr.c under the covers.

The TLB flushing code inside pageattr.c has has checks like
BUG_ON(irqs_disabled()), looking for interrupt disabling that might
cause deadlocks.  But, these also trip in early boot on certain
preempt configurations.  Just copy the existing BUG_ON() sequence from
cpa_flush_range() to the other two sites and check for early boot.

Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
Reported-by: Mariusz Ceier <mceier@gmail.com>
Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Nadav Amit <namit@vmware.com>
Cc: Kees Cook <keescook@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: https://lkml.kernel.org/r/20180420222019.20C4A410@viggo.jf.intel.com


---
 arch/x86/mm/pageattr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 0f3d50f4c48c..4fadfd2b7017 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -172,7 +172,7 @@ static void __cpa_flush_all(void *arg)
 
 static void cpa_flush_all(unsigned long cache)
 {
-	BUG_ON(irqs_disabled());
+	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
 	on_each_cpu(__cpa_flush_all, (void *) cache, 1);
 }
@@ -236,7 +236,7 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache,
 	unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
 #endif
 
-	BUG_ON(irqs_disabled());
+	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
 	on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86/pti: Fix boot warning from Global-bit setting
  2018-04-20 22:20   ` Dave Hansen
                     ` (2 preceding siblings ...)
  (?)
@ 2018-04-25  9:07   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-25  9:07 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, jgross, dwmw2, arjan, jpoimboe, dan.j.williams, namit,
	hughd, gregkh, hpa, aaro.koskinen, bp, peterz, aarcange, mingo,
	keescook, dave.hansen, linux-kernel, mceier, luto, torvalds

Commit-ID:  58e65b51e6f9b9dd94a25ff2b2772222e0358099
Gitweb:     https://git.kernel.org/tip/58e65b51e6f9b9dd94a25ff2b2772222e0358099
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:21 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 25 Apr 2018 11:02:50 +0200

x86/pti: Fix boot warning from Global-bit setting

commit 231df823c4f04176f607afc4576c989895cff40e

The pageattr.c code attempts to process "faults" when it goes looking
for PTEs to change and finds non-present entries.  It allows these
faults in the linear map which is "expected to have holes", but
WARN()s about them elsewhere, like when called on the kernel image.

However, change_page_attr_clear() is now called on the kernel image in the
process of trying to clear the Global bit.

This trips the warning in __cpa_process_fault() if a non-present PTE is
encountered in the kernel image.  The "holes" in the kernel image result
from free_init_pages()'s use of set_memory_np().  These holes are totally
fine, and result from normal operation, just as they would be in the kernel
linear map.

Just silence the warning when holes in the kernel image are encountered.

Fixes: 39114b7a7 (x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image)
Reported-by: Mariusz Ceier <mceier@gmail.com>
Reported-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Nadav Amit <namit@vmware.com>
Cc: Kees Cook <keescook@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: https://lkml.kernel.org/r/20180420222021.1C7D2B3F@viggo.jf.intel.com


---
 arch/x86/mm/pageattr.c | 40 ++++++++++++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 4fadfd2b7017..3bded76e8d5c 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file *m)
 static inline void split_page_count(int level) { }
 #endif
 
+static inline int
+within(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr < end;
+}
+
+static inline int
+within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+{
+	return addr >= start && addr <= end;
+}
+
 #ifdef CONFIG_X86_64
 
 static inline unsigned long highmap_start_pfn(void)
@@ -106,20 +118,25 @@ static inline unsigned long highmap_end_pfn(void)
 	return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
 }
 
-#endif
-
-static inline int
-within(unsigned long addr, unsigned long start, unsigned long end)
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-	return addr >= start && addr < end;
+	/*
+	 * Kernel text has an alias mapping at a high address, known
+	 * here as "highmap".
+	 */
+	return within_inclusive(pfn, highmap_start_pfn(), highmap_end_pfn());
 }
 
-static inline int
-within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+#else
+
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-	return addr >= start && addr <= end;
+	/* There is no highmap on 32-bit */
+	return false;
 }
 
+#endif
+
 /*
  * Flushing functions
  */
@@ -1183,6 +1200,10 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
 		cpa->numpages = 1;
 		cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
 		return 0;
+
+	} else if (__cpa_pfn_in_highmap(cpa->pfn)) {
+		/* Faults in the highmap are OK, so do not warn: */
+		return -EFAULT;
 	} else {
 		WARN(1, KERN_WARNING "CPA: called for zero pte. "
 			"vaddr = %lx cpa->vaddr = %lx\n", vaddr,
@@ -1335,8 +1356,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
 	 * to touch the high mapped kernel as well:
 	 */
 	if (!within(vaddr, (unsigned long)_text, _brk_end) &&
-	    within_inclusive(cpa->pfn, highmap_start_pfn(),
-			     highmap_end_pfn())) {
+	    __cpa_pfn_in_highmap(cpa->pfn)) {
 		unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
 					       __START_KERNEL_map - phys_base;
 		alias_cpa = *cpa;

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86/pti: Reduce amount of kernel text allowed to be Global
  2018-04-20 22:20   ` Dave Hansen
  (?)
  (?)
@ 2018-04-25  9:08   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-25  9:08 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jpoimboe, gregkh, torvalds, hughd, bp, arjan, luto, aarcange,
	tglx, jgross, keescook, dave.hansen, hpa, linux-kernel, dwmw2,
	namit, peterz, dan.j.williams, mingo

Commit-ID:  a44ca8f5a30c008b54d07b00eed4eae7f169fcd0
Gitweb:     https://git.kernel.org/tip/a44ca8f5a30c008b54d07b00eed4eae7f169fcd0
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:23 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 25 Apr 2018 11:02:50 +0200

x86/pti: Reduce amount of kernel text allowed to be Global

commit abb67605203687c8b7943d760638d0301787f8d9

Kees reported to me that I made too much of the kernel image global.
It was far more than just text:

	I think this is too much set global: _end is after data,
	bss, and brk, and all kinds of other stuff that could
	hold secrets. I think this should match what
	mark_rodata_ro() is doing.

This does exactly that.  We use __end_rodata_hpage_align as our
marker both because it is huge-page-aligned and it does not contain
any sections we expect to hold secrets.

Kees's logic was that r/o data is in the kernel image anyway and,
in the case of traditional distributions, can be freely downloaded
from the web, so there's no reason to hide it.

Fixes: 8c06c7740 (x86/pti: Leave kernel text global for !PCID)
Reported-by: Kees Cook <keescook@google.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: https://lkml.kernel.org/r/20180420222023.1C8B2B20@viggo.jf.intel.com


---
 arch/x86/mm/pti.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
index f1fd52f449e0..ae3eb4f5d53b 100644
--- a/arch/x86/mm/pti.c
+++ b/arch/x86/mm/pti.c
@@ -430,12 +430,24 @@ static inline bool pti_kernel_image_global_ok(void)
  */
 void pti_clone_kernel_text(void)
 {
+	/*
+	 * rodata is part of the kernel image and is normally
+	 * readable on the filesystem or on the web.  But, do not
+	 * clone the areas past rodata, they might contain secrets.
+	 */
 	unsigned long start = PFN_ALIGN(_text);
-	unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE);
+	unsigned long end = (unsigned long)__end_rodata_hpage_align;
 
 	if (!pti_kernel_image_global_ok())
 		return;
 
+	pr_debug("mapping partial kernel image into user address space\n");
+
+	/*
+	 * Note that this will undo _some_ of the work that
+	 * pti_set_kernel_image_nonglobal() did to clear the
+	 * global bit.
+	 */
 	pti_clone_pmds(start, end, _PAGE_RW);
 }
 
@@ -458,8 +470,6 @@ void pti_set_kernel_image_nonglobal(void)
 	if (pti_kernel_image_global_ok())
 		return;
 
-	pr_debug("set kernel image non-global\n");
-
 	set_memory_nonglobal(start, (end - start) >> PAGE_SHIFT);
 }
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86/pti: Disallow global kernel text with RANDSTRUCT
  2018-04-20 22:20   ` Dave Hansen
  (?)
  (?)
@ 2018-04-25  9:08   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-25  9:08 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jgross, mingo, arjan, peterz, keescook, namit, aarcange, gregkh,
	tglx, jpoimboe, luto, hughd, bp, vbabka, dave.hansen, dwmw2,
	linux-kernel, torvalds, hpa, dan.j.williams

Commit-ID:  b7c21bc56fbedf4a61b628c6b11e0d7048746cc1
Gitweb:     https://git.kernel.org/tip/b7c21bc56fbedf4a61b628c6b11e0d7048746cc1
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:26 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 25 Apr 2018 11:02:51 +0200

x86/pti: Disallow global kernel text with RANDSTRUCT

commit 26d35ca6c3776784f8156e1d6f80cc60d9a2a915

RANDSTRUCT derives its hardening benefits from the attacker's lack of
knowledge about the layout of kernel data structures.  Keep the kernel
image non-global in cases where RANDSTRUCT is in use to help keep the
layout a secret.

Fixes: 8c06c7740 (x86/pti: Leave kernel text global for !PCID)
Reported-by: Kees Cook <keescook@google.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Link: https://lkml.kernel.org/r/20180420222026.D0B4AAC9@viggo.jf.intel.com


---
 arch/x86/mm/pti.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
index ae3eb4f5d53b..4d418e705878 100644
--- a/arch/x86/mm/pti.c
+++ b/arch/x86/mm/pti.c
@@ -421,6 +421,16 @@ static inline bool pti_kernel_image_global_ok(void)
 	if (boot_cpu_has(X86_FEATURE_K8))
 		return false;
 
+	/*
+	 * RANDSTRUCT derives its hardening benefits from the
+	 * attacker's lack of knowledge about the layout of kernel
+	 * data structures.  Keep the kernel image non-global in
+	 * cases where RANDSTRUCT is in use to help keep the layout a
+	 * secret.
+	 */
+	if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT))
+		return false;
+
 	return true;
 }
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [tip:x86/pti] x86/pti: Filter at vma->vm_page_prot population
  2018-04-20 22:20   ` Dave Hansen
                     ` (2 preceding siblings ...)
  (?)
@ 2018-04-25  9:09   ` tip-bot for Dave Hansen
  -1 siblings, 0 replies; 29+ messages in thread
From: tip-bot for Dave Hansen @ 2018-04-25  9:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: torvalds, keescook, mingo, namit, dave.hansen, bp, gregkh,
	dan.j.williams, hpa, peterz, dwmw2, aarcange, jpoimboe, luto,
	jgross, arjan, tglx, linux-kernel, fengguang.wu, hughd

Commit-ID:  316d097c4cd4e7f2ef50c40cff2db266593c4ec4
Gitweb:     https://git.kernel.org/tip/316d097c4cd4e7f2ef50c40cff2db266593c4ec4
Author:     Dave Hansen <dave.hansen@linux.intel.com>
AuthorDate: Fri, 20 Apr 2018 15:20:28 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Wed, 25 Apr 2018 11:02:51 +0200

x86/pti: Filter at vma->vm_page_prot population

commit ce9962bf7e22bb3891655c349faff618922d4a73

0day reported warnings at boot on 32-bit systems without NX support:

attempted to set unsupported pgprot: 8000000000000025 bits: 8000000000000000 supported: 7fffffffffffffff
WARNING: CPU: 0 PID: 1 at
arch/x86/include/asm/pgtable.h:540 handle_mm_fault+0xfc1/0xfe0:
 check_pgprot at arch/x86/include/asm/pgtable.h:535
 (inlined by) pfn_pte at arch/x86/include/asm/pgtable.h:549
 (inlined by) do_anonymous_page at mm/memory.c:3169
 (inlined by) handle_pte_fault at mm/memory.c:3961
 (inlined by) __handle_mm_fault at mm/memory.c:4087
 (inlined by) handle_mm_fault at mm/memory.c:4124

The problem is that due to the recent commit which removed auto-massaging
of page protections, filtering page permissions at PTE creation time is not
longer done, so vma->vm_page_prot is passed unfiltered to PTE creation.

Filter the page protections before they are installed in vma->vm_page_prot.

Fixes: fb43d6cb91 ("x86/mm: Do not auto-massage page protections")
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kees Cook <keescook@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Nadav Amit <namit@vmware.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Link: https://lkml.kernel.org/r/20180420222028.99D72858@viggo.jf.intel.com


---
 arch/x86/Kconfig               |  4 ++++
 arch/x86/include/asm/pgtable.h |  5 +++++
 mm/mmap.c                      | 11 ++++++++++-
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 00fcf81f2c56..c07f492b871a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -52,6 +52,7 @@ config X86
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FAST_MULTIPLIER
+	select ARCH_HAS_FILTER_PGPROT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV			if X86_64
@@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX
 config ARCH_HAS_CACHE_LINE_SIZE
 	def_bool y
 
+config ARCH_HAS_FILTER_PGPROT
+	def_bool y
+
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 5f49b4ff0c24..f1633de5a675 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
 
 #define canon_pgprot(p) __pgprot(massage_pgprot(p))
 
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+	return canon_pgprot(prot);
+}
+
 static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
 					 enum page_cache_mode pcm,
 					 enum page_cache_mode new_pcm)
diff --git a/mm/mmap.c b/mm/mmap.c
index 188f195883b9..9d5968d1e8e3 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -100,11 +100,20 @@ pgprot_t protection_map[16] __ro_after_init = {
 	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
 };
 
+#ifndef CONFIG_ARCH_HAS_FILTER_PGPROT
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+	return prot;
+}
+#endif
+
 pgprot_t vm_get_page_prot(unsigned long vm_flags)
 {
-	return __pgprot(pgprot_val(protection_map[vm_flags &
+	pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
 				(VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
 			pgprot_val(arch_vm_get_page_prot(vm_flags)));
+
+	return arch_filter_pgprot(ret);
 }
 EXPORT_SYMBOL(vm_get_page_prot);
 

^ permalink raw reply related	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2018-04-25  9:10 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-20 22:20 [PATCH 0/5] x86, mm: PTI Global page fixes for 4.17 Dave Hansen
2018-04-20 22:20 ` Dave Hansen
2018-04-20 22:20 ` [PATCH 1/5] x86, pti: fix boot problems from Global-bit setting Dave Hansen
2018-04-20 22:20   ` Dave Hansen
2018-04-23 10:50   ` Aaro Koskinen
2018-04-23 10:50     ` Aaro Koskinen
2018-04-24  8:06   ` [tip:x86/pti] x86/pti: Fix " tip-bot for Dave Hansen
2018-04-25  9:06   ` tip-bot for Dave Hansen
2018-04-20 22:20 ` [PATCH 2/5] x86, pti: fix boot warning " Dave Hansen
2018-04-20 22:20   ` Dave Hansen
2018-04-23 10:51   ` Aaro Koskinen
2018-04-23 10:51     ` Aaro Koskinen
2018-04-24  8:07   ` [tip:x86/pti] x86/pti: Fix " tip-bot for Dave Hansen
2018-04-25  9:07   ` tip-bot for Dave Hansen
2018-04-20 22:20 ` [PATCH 3/5] x86, pti: reduce amount of kernel text allowed to be Global Dave Hansen
2018-04-20 22:20   ` Dave Hansen
2018-04-24  8:08   ` [tip:x86/pti] x86, pti: Reduce " tip-bot for Dave Hansen
2018-04-25  9:08   ` [tip:x86/pti] x86/pti: " tip-bot for Dave Hansen
2018-04-20 22:20 ` [PATCH 4/5] x86, pti: disallow global kernel text with RANDSTRUCT Dave Hansen
2018-04-20 22:20   ` Dave Hansen
2018-04-24  8:08   ` [tip:x86/pti] x86/pti: Disallow " tip-bot for Dave Hansen
2018-04-25  9:08   ` tip-bot for Dave Hansen
2018-04-20 22:20 ` [PATCH 5/5] x86, pti: filter at vma->vm_page_prot population Dave Hansen
2018-04-20 22:20   ` Dave Hansen
2018-04-21  1:21   ` Nadav Amit
2018-04-23 11:37     ` Dave Hansen
2018-04-23 11:37       ` Dave Hansen
2018-04-24  8:09   ` [tip:x86/pti] x86, pti: Filter " tip-bot for Dave Hansen
2018-04-25  9:09   ` [tip:x86/pti] x86/pti: " tip-bot for Dave Hansen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.