Skip to contentSkip to conversation

x86/pti: Make unpoison of pgd for trusted boot work for real

PATCH Applied Hugh Dickins 2 participants 2 messages Jan 30, 2018 – Feb 5, 2018

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86/pti: Make unpoison of pgd for trusted boot work for real

From: Dave Hansen <[email protected]>

commit 445b69e3b75e42362a5bdc13c8b8f61599e2228a upstream

The inital fix for trusted boot and PTI potentially misses the pgd clearing if pud_alloc() sets a PGD. It probably works in *practice* because for two adjacent calls to map_tboot_page() that share a PGD entry, the first will clear NX, *then* allocate and set the PGD (without NX clear). The second call will *not* allocate but will clear the NX bit.

Defer the NX clearing to a point after it is known that all top-level allocations have occurred. Add a comment to clarify why.

[ tglx: Massaged changelog ]

hughd notes: I have not tested tboot, but this looks to me as necessary and as safe in old-Kaiser backports as it is upstream; I'm not submitting the commit-to-be-fixed 262b6b30087, since it was undone by 445b69e3b75e, and makes conflict trouble because of 5-level's p4d versus 4-level's pgd.

---
 arch/x86/kernel/tboot.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
arch/x86/kernel/tboot.c +10 -0
index 8402907825b0..21454e254a4c 100644
@@ -134,6 +134,16 @@ static int map_tboot_page(unsigned long vaddr, unsigned long pfn,
 		return -1;
 	set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
 	pte_unmap(pte);
+
+	/*
+	 * PTI poisons low addresses in the kernel page tables in the
+	 * name of making them unusable for userspace.  To execute
+	 * code at such a low address, the poison must be cleared.
+	 *
+	 * Note: 'pgd' actually gets set in pud_alloc().
+	 */
+	pgd->pgd &= ~_PAGE_NX;
+
 	return 0;
 }
 
Signature · 1 line
2.16.0.rc1.238.g530d649a79-goog
maintainer Applied
#1 lore raw

Patch "x86/pti: Make unpoison of pgd for trusted boot work for real" has been added to the 4.9-stable tree

This is a note to let you know that I've just added the patch titled

x86/pti: Make unpoison of pgd for trusted boot work for real

to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
x86-pti-make-unpoison-of-pgd-for-trusted-boot-work-for-real.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From [email protected] Mon Feb 5 04:59:38 2018

From: Hugh Dickins <[email protected]>
Date: Mon, 29 Jan 2018 18:17:26 -0800
Subject: x86/pti: Make unpoison of pgd for trusted boot work for real
To: Greg Kroah-Hartman <[email protected]>
Cc: Dave Hansen <[email protected]>, Thomas Gleixner <[email protected]>, Jon Masters <[email protected]>, Tim Chen <[email protected]>, [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], Jiri Kosina <[email protected]>, Hugh Dickins <[email protected]>
Message-ID: <[email protected]>

From: Dave Hansen <[email protected]>

commit 445b69e3b75e42362a5bdc13c8b8f61599e2228a upstream

The inital fix for trusted boot and PTI potentially misses the pgd clearing if pud_alloc() sets a PGD. It probably works in *practice* because for two adjacent calls to map_tboot_page() that share a PGD entry, the first will clear NX, *then* allocate and set the PGD (without NX clear). The second call will *not* allocate but will clear the NX bit.

Defer the NX clearing to a point after it is known that all top-level allocations have occurred. Add a comment to clarify why.

[ tglx: Massaged changelog ]

[ hughd notes: I have not tested tboot, but this looks to me as necessary and as safe in old-Kaiser backports as it is upstream; I'm not submitting the commit-to-be-fixed 262b6b30087, since it was undone by 445b69e3b75e, and makes conflict trouble because of 5-level's p4d versus 4-level's pgd.]

---
 arch/x86/kernel/tboot.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
arch/x86/kernel/tboot.c +10 -0
@@ -134,6 +134,16 @@ static int map_tboot_page(unsigned long
 		return -1;
 	set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
 	pte_unmap(pte);
+
+	/*
+	 * PTI poisons low addresses in the kernel page tables in the
+	 * name of making them unusable for userspace.  To execute
+	 * code at such a low address, the poison must be cleared.
+	 *
+	 * Note: 'pgd' actually gets set in pud_alloc().
+	 */
+	pgd->pgd &= ~_PAGE_NX;
+
 	return 0;
 }
 

Patches currently in stable-queue which might be from [email protected] are

queue-4.9/kaiser-allocate-pgd-with-order-0-when-pti-off.patch queue-4.9/x86-pti-make-unpoison-of-pgd-for-trusted-boot-work-for-real.patch queue-4.9/kaiser-fix-intel_bts-perf-crashes.patch