diff options
author | Martin Storsjö <martin@martin.st> | 2020-05-13 22:11:04 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2020-05-14 12:21:58 +0300 |
commit | b878d75dc2e5915eedfb79c4721481ff28251523 (patch) | |
tree | 869cf3cac256f37d07976a2c061ad495c1eab934 | |
parent | 55cf967bdf6f94d963080f57c34271ef0623f68f (diff) |
checkasm: arm32: Take the number of stack arguments into account when checking for stack clobbering
-rw-r--r-- | tests/checkasm/arm/checkasm_32.S | 21 | ||||
-rw-r--r-- | tests/checkasm/checkasm.h | 6 |
2 files changed, 16 insertions, 11 deletions
diff --git a/tests/checkasm/arm/checkasm_32.S b/tests/checkasm/arm/checkasm_32.S index 916a2e2..2d1c0ae 100644 --- a/tests/checkasm/arm/checkasm_32.S +++ b/tests/checkasm/arm/checkasm_32.S @@ -86,13 +86,15 @@ function checked_call_\variant, export=1 .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 @@ function checked_call_\variant, export=1 @ 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 diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h index f19f09e..835e998 100644 --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h @@ -225,11 +225,13 @@ void checkasm_simd_warmup(void); * 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, ...); |