Thread (107 messages) 107 messages, 7 authors, 2020-04-08

Re: [RFC PATCH v9 07/27] Add guard pages around a Shadow Stack.

From: Kees Cook <hidden>
Date: 2020-02-25 20:11:15
Also in: linux-arch, linux-doc, linux-mm, lkml

On Wed, Feb 05, 2020 at 10:19:15AM -0800, Yu-cheng Yu wrote:
INCSSPD/INCSSPQ instruction is used to unwind a Shadow Stack (SHSTK).  It
performs 'pop and discard' of the first and last element from SHSTK in the
range specified in the operand.  The maximum value of the operand is 255,
and the maximum moving distance of the SHSTK pointer is 255 * 4 for
INCSSPD, 255 * 8 for INCSSPQ.

Since SHSTK has a fixed size, creating a guard page above prevents
INCSSP/RET from moving beyond.  Likewise, creating a guard page below
prevents CALL from underflowing the SHSTK.
This commit log doesn't really explain why the code changes below are
needed? stack_guard_gap is configurable at boot, etc. This appears to be
limiting it? I don't follow this change...

-Kees
quoted hunk ↗ jump to hunk
Signed-off-by: Yu-cheng Yu <redacted>
---
 include/linux/mm.h | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b5145fbe102e..75de07674649 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2464,9 +2464,15 @@ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * m
 static inline unsigned long vm_start_gap(struct vm_area_struct *vma)
 {
 	unsigned long vm_start = vma->vm_start;
+	unsigned long gap = 0;
 
-	if (vma->vm_flags & VM_GROWSDOWN) {
-		vm_start -= stack_guard_gap;
+	if (vma->vm_flags & VM_GROWSDOWN)
+		gap = stack_guard_gap;
+	else if (vma->vm_flags & VM_SHSTK)
+		gap = PAGE_SIZE;
+
+	if (gap != 0) {
+		vm_start -= gap;
 		if (vm_start > vma->vm_start)
 			vm_start = 0;
 	}
@@ -2476,9 +2482,15 @@ static inline unsigned long vm_start_gap(struct vm_area_struct *vma)
 static inline unsigned long vm_end_gap(struct vm_area_struct *vma)
 {
 	unsigned long vm_end = vma->vm_end;
+	unsigned long gap = 0;
+
+	if (vma->vm_flags & VM_GROWSUP)
+		gap = stack_guard_gap;
+	else if (vma->vm_flags & VM_SHSTK)
+		gap = PAGE_SIZE;
 
-	if (vma->vm_flags & VM_GROWSUP) {
-		vm_end += stack_guard_gap;
+	if (gap != 0) {
+		vm_end += gap;
 		if (vm_end < vma->vm_end)
 			vm_end = -PAGE_SIZE;
 	}
-- 
2.21.0
-- 
Kees Cook
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help