shithub: dav1d

Download patch

ref: 1d16d38d4ee4dccb2a3c9dad2f5be55a2236bd27
parent: b7548376f9c7ebfea04a740ce663570226b6328c
author: Martin Storsjö <martin@martin.st>
date: Tue May 5 10:51:40 EDT 2020

checkasm: arm32: Check for stack overflows

--- a/tests/checkasm/arm/checkasm_32.S
+++ b/tests/checkasm/arm/checkasm_32.S
@@ -48,6 +48,8 @@
         .asciz "failed to preserve register r%d"
 error_message_vfp:
         .asciz "failed to preserve register d%d"
+error_message_stack:
+        .asciz "failed to preserve stack"
 endconst
 
 @ max number of args used by any asm function.
@@ -55,8 +57,9 @@
 
 #define ARG_STACK 4*(MAX_ARGS - 4)
 
-@ align the used stack space to 8 to preserve the stack alignment
-#define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed)
+@ Align the used stack space to 8 to preserve the stack alignment.
+@ +8 for stack canary reference.
+#define ARG_STACK_A (((ARG_STACK + pushed + 7) & ~7) - pushed + 8)
 
 .macro clobbercheck variant
 .equ pushed, 4*9
@@ -83,14 +86,34 @@
 .equ pos, pos + 4
 .endr
 
+        @ 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             r12, [sp]
+        mvn             r12, r12
+        str             r12, [sp, #ARG_STACK_A - 8]
+
         mov             r12, r0
         mov             r0,  r2
         mov             r1,  r3
         ldrd            r2,  r3,  [sp, #ARG_STACK_A + pushed]
+        @ Call the target function
         blx             r12
-        add             sp,  sp,  #ARG_STACK_A
 
+        @ Load the stack canary and its reference
+        ldr             r2,  [sp]
+        ldr             r3,  [sp, #ARG_STACK_A - 8]
+
+        add             sp,  sp,  #ARG_STACK_A
         push            {r0, r1}
+
+        mvn             r3,  r3
+        cmp             r2,  r3
+        bne             5f
+
         movrel          r12, register_init
 .ifc \variant, vfp
 .macro check_reg_vfp, dreg, offset
@@ -144,6 +167,9 @@
 .purgem check_reg
 
         b               0f
+5:
+        movrel          r0, error_message_stack
+        b               1f
 4:
         movrel          r0, error_message_vfp
         b               1f