ref: b878d75dc2e5915eedfb79c4721481ff28251523
parent: 55cf967bdf6f94d963080f57c34271ef0623f68f
author: Martin Storsjö <[email protected]>
date: Wed May 13 18:11:04 EDT 2020
checkasm: arm32: Take the number of stack arguments into account when checking for stack clobbering
--- a/tests/checkasm/arm/checkasm_32.S
+++ b/tests/checkasm/arm/checkasm_32.S
@@ -86,13 +86,15 @@
.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]
+ @ For stack overflows, the callee is free to overwrite the parameters
+ @ that were passed on the stack (if any), so we can only check after
+ @ that point. First figure out how many parameters the function
+ @ really took on the stack:
+ ldr r12, [sp, #ARG_STACK_A + pushed + 8 + 4*(MAX_ARGS-4)]
+ @ Load the first non-parameter value from the stack, that should be
+ @ left untouched by the function. Store a copy of it inverted, so that
+ @ e.g. overwriting everything with zero would be noticed.
+ ldr r12, [sp, r12, lsl #2]
mvn r12, r12
str r12, [sp, #ARG_STACK_A - 8]
@@ -103,8 +105,9 @@
@ Call the target function
blx r12
- @ Load the stack canary and its reference
- ldr r2, [sp]
+ @ Load the number of stack parameters, stack canary and its reference
+ ldr r12, [sp, #ARG_STACK_A + pushed + 8 + 4*(MAX_ARGS-4)]
+ ldr r2, [sp, r12, lsl #2]
ldr r3, [sp, #ARG_STACK_A - 8]
add sp, sp, #ARG_STACK_A
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -225,11 +225,13 @@
* the same even when the extra parameters have been removed. */
void checkasm_checked_call_vfp(void *func, int dummy, ...);
#define declare_new(ret, ...)\
- ret (*checked_call)(void *, int dummy, __VA_ARGS__) =\
+ ret (*checked_call)(void *, int dummy, __VA_ARGS__,\
+ int, int, int, int, int, int, int, int,\
+ int, int, int, int, int, int, int) =\
(void *)checkasm_checked_call_vfp;
#define call_new(...)\
(checkasm_set_signal_handler_state(1),\
- checked_call(func_new, 0, __VA_ARGS__));\
+ checked_call(func_new, 0, __VA_ARGS__, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0));\
checkasm_set_signal_handler_state(0)
#elif ARCH_AARCH64 && !defined(__APPLE__)
void checkasm_stack_clobber(uint64_t clobber, ...);