From d3166fa73ad1ef10c5c4a5e5e2403cc9d753bda4 Mon Sep 17 00:00:00 2001 From: Victor Do Nascimento Date: Tue, 23 Aug 2022 10:07:27 +0100 Subject: string: arm: Fix CFI auto-alignment issues. The use of the PAC_CFI_ADJ macro for calculating the effect of pushing the IP register onto the stack assumes that pushing the register is always optional and is always supressed when PAC_LEAF_PUSH_IP is set to 0. This leads to CFI alignment issues for functions where the IP register is clobbered and thus where IP is always pushed to the stack in the function prologue. This patch introduces a new macro PAC_CFI_ADJ_DEFAULT whose value is never zeroed when PAC signing is requested, irrespective of the PAC_LEAF_PUSH_IP settings. Example: * HAVE_PAC_LEAF == 1 && PAC_LEAF_PUSH_IP == 1: PAC_CFI_ADJ = 4 PAC_CFI_ADJ_DEFAULT = 4 * HAVE_PAC_LEAF == 1 && PAC_LEAF_PUSH_IP == 0: PAC_CFI_ADJ = 0 PAC_CFI_ADJ_DEFAULT = 4 Built w/ arm-none-linux-gnueabihf, ran make check-string w/ qemu-arm-static. --- string/arm/strcmp.S | 4 ++-- string/pacbti.h | 39 ++++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 15 deletions(-) (limited to 'string') diff --git a/string/arm/strcmp.S b/string/arm/strcmp.S index a408f3f..eafb9f6 100644 --- a/string/arm/strcmp.S +++ b/string/arm/strcmp.S @@ -158,8 +158,8 @@ __strcmp_arm: #endif strd r4, r5, [sp, #-16]! .cfi_adjust_cfa_offset 16 - .cfi_offset 5, -(12+PAC_CFI_ADJ) - .cfi_offset 4, -(16+PAC_CFI_ADJ) + .cfi_offset 5, -(12+PAC_CFI_ADJ_DEFAULT) + .cfi_offset 4, -(16+PAC_CFI_ADJ_DEFAULT) orr tmp1, src1, src2 strd r6, r7, [sp, #8] #if HAVE_PAC_LEAF diff --git a/string/pacbti.h b/string/pacbti.h index 0745233..4e8a600 100644 --- a/string/pacbti.h +++ b/string/pacbti.h @@ -21,9 +21,21 @@ # define PAC_LEAF_PUSH_IP 1 #endif +/* Two distinct PAC_CFI adjustment values are needed at any given time. + If PAC-signing is requested for leaf functions but pushing the pac + code to the stack is not, PAC_CFI_ADJ defaults to 0, as most + functions will not overwrite the register holding pac (ip). This is not + appropriate for functions that clobber the ip register, where pushing + to the stack is non-optional. Wherever a generated pac code must be + unconditionally pushed to the stack, a CFI adjustment of + PAC_CFI_ADJ_DEFAULT is used instead. */ +#if HAVE_PAC_LEAF +# define PAC_CFI_ADJ_DEFAULT 4 +#endif + #if HAVE_PAC_LEAF # if PAC_LEAF_PUSH_IP -# define PAC_CFI_ADJ 4 +# define PAC_CFI_ADJ 4 # else # define PAC_CFI_ADJ 0 # endif /* PAC_LEAF_PUSH_IP*/ @@ -31,6 +43,7 @@ # undef PAC_LEAF_PUSH_IP # define PAC_LEAF_PUSH_IP 0 # define PAC_CFI_ADJ 0 +# define PAC_CFI_ADJ_DEFAULT PAC_CFI_ADJ #endif /* HAVE_PAC_LEAF */ /* Emit .cfi_restore directives for a consecutive sequence of registers. */ @@ -43,7 +56,7 @@ /* Emit .cfi_offset directives for a consecutive sequence of registers. */ .macro cfisavelist first, last, index=1 - .cfi_offset \last, -4*(\index) - PAC_CFI_ADJ + .cfi_offset \last, -4 * (\index) .if \last-\first cfisavelist \first, \last-1, \index+1 .endif @@ -68,31 +81,31 @@ .if \last != -1 .if \savepac push {r\first-r\last, ip} - .cfi_adjust_cfa_offset ((\last-\first)+1)*4 + PAC_CFI_ADJ - .cfi_offset 143, -PAC_CFI_ADJ - cfisavelist \first, \last + .cfi_adjust_cfa_offset ((\last-\first)+2)*4 + .cfi_offset 143, -4 + cfisavelist \first, \last, 2 .else push {r\first-r\last} .cfi_adjust_cfa_offset ((\last-\first)+1)*4 - cfisavelist \first, \last + cfisavelist \first, \last, 1 .endif .else .if \savepac push {r\first, ip} - .cfi_adjust_cfa_offset 4 + PAC_CFI_ADJ - .cfi_offset 143, -PAC_CFI_ADJ - cfisavelist \first, \first + .cfi_adjust_cfa_offset 8 + .cfi_offset 143, -4 + cfisavelist \first, \first, 2 .else // !\savepac push {r\first} - .cfi_adjust_cfa_offset PAC_CFI_ADJ - cfisavelist \first, \first + .cfi_adjust_cfa_offset 4 + cfisavelist \first, \first, 1 .endif .endif .else // \first == -1 .if \savepac push {ip} - .cfi_adjust_cfa_offset PAC_CFI_ADJ - .cfi_offset 143, -PAC_CFI_ADJ + .cfi_adjust_cfa_offset 4 + .cfi_offset 143, -4 .endif .endif .endm -- cgit v1.2.3