shithub: dav1d

Download patch

ref: b7548376f9c7ebfea04a740ce663570226b6328c
parent: 114e8f0ee53ba34d22452dc4bdc0e9ec263189c8
author: Martin Storsjö <martin@martin.st>
date: Tue May 5 09:48:59 EDT 2020

checkasm: arm64: Check for stack overflows

Also fill x8-x17 with garbage before calling the function.

--- a/tests/checkasm/arm/checkasm_64.S
+++ b/tests/checkasm/arm/checkasm_64.S
@@ -53,8 +53,10 @@
 endconst
 
 
-const error_message
+const error_message_register
         .asciz "failed to preserve register"
+error_message_stack:
+        .asciz "stack clobbered"
 endconst
 
 
@@ -74,7 +76,8 @@
         ret
 endfunc
 
-#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15)
+// + 16 for stack canary reference
+#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15 + 16)
 
 function checked_call, export=1
         stp             x29, x30, [sp, #-16]!
@@ -109,14 +112,45 @@
 .equ pos, pos + 8
 .endr
 
+        // Fill x8-x17 with garbage. This doesn't have to be preserved,
+        // but avoids relying on them having any particular value.
+        movrel          x9, register_init
+        ldp             x10, x11, [x9], #32
+        ldp             x12, x13, [x9], #32
+        ldp             x14, x15, [x9], #32
+        ldp             x16, x17, [x9], #32
+        ldp             x8,  x9,  [x9]
+
+        // For stack overflows, we want to check the values immediately
+        // on the stack, which (may) come from arguments - so we can't
+        // place custom values there. Instead just check them as-is
+        // against a reference that is stored inverted (so that a stack
+        // overflow that overwrites everything with the same value will
+        // be noticed).
+        ldr             x2,  [sp]
+        mvn             x2,  x2
+        str             x2,  [sp, #ARG_STACK-16]
+
+        // Load the in-register arguments
         mov             x12, x0
         ldp             x0,  x1,  [x29, #16]
         ldp             x2,  x3,  [x29, #32]
         ldp             x4,  x5,  [x29, #48]
         ldp             x6,  x7,  [x29, #64]
+        // Call the target function
         blr             x12
+
+        // Load the stack canary and its reference
+        ldr             x2,  [sp]
+        ldr             x3,  [sp, #ARG_STACK-16]
+
         add             sp,  sp,  #ARG_STACK
         stp             x0,  x1,  [sp, #-16]!
+
+        mvn             x3,  x3
+        cmp             x2,  x3
+        b.ne            2f
+
         movrel          x9, register_init
         movi            v3.8h,  #0
 
@@ -148,7 +182,11 @@
 
         cbz             x3,  0f
 
-        movrel          x0, error_message
+        movrel          x0, error_message_register
+        b               1f
+2:
+        movrel          x0, error_message_stack
+1:
 #ifdef PREFIX
         bl              _checkasm_fail_func
 #else