From 4c1955491483f1e2818a9d51e51286d63f67dce5 Mon Sep 17 00:00:00 2001 From: chao an Date: Wed, 29 Nov 2023 16:58:15 +0800 Subject: [PATCH] libc/arm: add support of PACBTI Reference: https://developer.arm.com/documentation/100748/0617/Security-features-supported-in-Arm-Compiler-for-Embedded/PACBTI-M-extension-mitigations-against-ROP-and-JOP-style-attacks https://developer.arm.com/documentation/101754/0619/armclang-Reference/armclang-Command-line-Options/-mbranch-protection Signed-off-by: chao an --- .../machine/arm/armv8-m/gnu/arch_memchr.S | 40 +++++++++++++++++++ .../machine/arm/armv8-m/gnu/arch_memcpy.S | 24 +++++++++++ .../machine/arm/armv8-m/gnu/arch_memmove.S | 21 ++++++++++ .../machine/arm/armv8-m/gnu/arch_memset.S | 24 +++++++++++ .../machine/arm/armv8-m/gnu/arch_strcmp.S | 27 +++++++++++++ .../machine/arm/armv8-m/gnu/arch_strcpy.S | 18 +++++++++ .../machine/arm/armv8-m/gnu/arch_strlen.S | 18 +++++++++ 7 files changed, 172 insertions(+) diff --git a/libs/libc/machine/arm/armv8-m/gnu/arch_memchr.S b/libs/libc/machine/arm/armv8-m/gnu/arch_memchr.S index a77770e328392..f27821c0954f1 100644 --- a/libs/libc/machine/arm/armv8-m/gnu/arch_memchr.S +++ b/libs/libc/machine/arm/armv8-m/gnu/arch_memchr.S @@ -70,6 +70,14 @@ #ifdef LIBC_BUILD_MEMCHR +#ifndef __ARM_FEATURE_BTI_DEFAULT +# define __ARM_FEATURE_BTI_DEFAULT 0 +#endif + +#ifndef __ARM_FEATURE_PAC_DEFAULT +# define __ARM_FEATURE_PAC_DEFAULT 0 +#endif + @ 2011-02-07 david.gilbert@linaro.org @ Extracted from local git a5b438d861 @ 2011-07-14 david.gilbert@linaro.org @@ -145,6 +153,13 @@ memchr: .cfi_sections .debug_frame .cfi_startproc +#if __ARM_FEATURE_PAC_DEFAULT +# if __ARM_FEATURE_BTI_DEFAULT + pacbti ip, lr, sp +# else + pac ip, lr, sp +# endif /* __ARM_FEATURE_BTI_DEFAULT */ +#endif /* __ARM_FEATURE_PAC_DEFAULT */ /* Use a simple loop if there are less than 8 bytes to search. */ cmp cntin, #7 bhi .Llargestr @@ -158,6 +173,9 @@ memchr: bne .Lsmallstr /* Loop again if not found. */ /* Otherwise fixup address and return. */ sub result, result, #1 +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr @@ -262,12 +280,18 @@ memchr: clz synd, synd /* Compute the potential result and return */ add result, src, synd +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr .Lnotfound: /* Set result to NULL if not found and return */ mov result, #0 +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr .cfi_endproc @@ -301,6 +325,13 @@ memchr: @ r1 = character to look for @ r2 = length @ returns r0 = pointer to character or NULL if not found +#if __ARM_FEATURE_PAC_DEFAULT +# if __ARM_FEATURE_BTI_DEFAULT + pacbti ip, lr, sp +# else + pac ip, lr, sp +# endif /* __ARM_FEATURE_BTI_DEFAULT */ +#endif /* __ARM_FEATURE_PAC_DEFAULT */ and r1,r1,#0xff @ Don't trust the caller to pass a char cmp r2,#16 @ If short don't bother with anything clever @@ -359,10 +390,16 @@ memchr: 40: movs r0,#0 @ not found +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr 50: subs r0,r0,#1 @ found +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr 60: @ We're here because the fast path found a hit @@ -389,6 +426,9 @@ memchr: 61: pop {r4,r5,r6,r7} subs r0,r0,#1 +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr #else /* Defined in memchr-stub.c. */ diff --git a/libs/libc/machine/arm/armv8-m/gnu/arch_memcpy.S b/libs/libc/machine/arm/armv8-m/gnu/arch_memcpy.S index bc84088a8d599..5b708e53b8785 100644 --- a/libs/libc/machine/arm/armv8-m/gnu/arch_memcpy.S +++ b/libs/libc/machine/arm/armv8-m/gnu/arch_memcpy.S @@ -33,6 +33,14 @@ #ifdef LIBC_BUILD_MEMCPY +#ifndef __ARM_FEATURE_BTI_DEFAULT +# define __ARM_FEATURE_BTI_DEFAULT 0 +#endif + +#ifndef __ARM_FEATURE_PAC_DEFAULT +# define __ARM_FEATURE_PAC_DEFAULT 0 +#endif + #ifndef __ARM_FEATURE_MVE /* This memcpy routine is optimised for Cortex-M3/M4 cores with/without unaligned access. @@ -105,6 +113,13 @@ memcpy: @ r0: dst @ r1: src @ r2: len +#if __ARM_FEATURE_PAC_DEFAULT +# if __ARM_FEATURE_BTI_DEFAULT + pacbti ip, lr, sp +# else + pac ip, lr, sp +# endif /* __ARM_FEATURE_BTI_DEFAULT */ +#endif /* __ARM_FEATURE_PAC_DEFAULT */ #ifdef __ARM_FEATURE_MVE mov r3, lr wlstp.8 lr, r2, 2f @@ -114,6 +129,9 @@ memcpy: vstrb.8 q0, [r2], #16 letp lr, 1b 2: +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx r3 #else #ifdef __ARM_FEATURE_UNALIGNED @@ -224,6 +242,9 @@ memcpy: #else pop {r0} #endif +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr .align 2 @@ -365,6 +386,9 @@ memcpy: #else pop {r0} #endif +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr #endif .size memcpy, .-memcpy diff --git a/libs/libc/machine/arm/armv8-m/gnu/arch_memmove.S b/libs/libc/machine/arm/armv8-m/gnu/arch_memmove.S index 4789b0bd32b9a..26b8ccfb8ca5b 100644 --- a/libs/libc/machine/arm/armv8-m/gnu/arch_memmove.S +++ b/libs/libc/machine/arm/armv8-m/gnu/arch_memmove.S @@ -33,11 +33,26 @@ #ifdef LIBC_BUILD_MEMMOVE +#ifndef __ARM_FEATURE_BTI_DEFAULT +# define __ARM_FEATURE_BTI_DEFAULT 0 +#endif + +#ifndef __ARM_FEATURE_PAC_DEFAULT +# define __ARM_FEATURE_PAC_DEFAULT 0 +#endif + .thumb .syntax unified .global memmove .type memmove, %function memmove: +#if __ARM_FEATURE_PAC_DEFAULT +# if __ARM_FEATURE_BTI_DEFAULT + pacbti ip, lr, sp +# else + pac ip, lr, sp +# endif /* __ARM_FEATURE_BTI_DEFAULT */ +#endif /* __ARM_FEATURE_PAC_DEFAULT */ cmp r0, r1 push {r4} bls 3f @@ -54,6 +69,9 @@ memmove: bne 1b 2: pop {r4} +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr 3: cmp r2, #0 @@ -66,6 +84,9 @@ memmove: strb r4, [r3, #1]! bne 4b pop {r4} +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr .size memmove, . - memmove diff --git a/libs/libc/machine/arm/armv8-m/gnu/arch_memset.S b/libs/libc/machine/arm/armv8-m/gnu/arch_memset.S index 350c2897a35d4..722cd35be8e36 100644 --- a/libs/libc/machine/arm/armv8-m/gnu/arch_memset.S +++ b/libs/libc/machine/arm/armv8-m/gnu/arch_memset.S @@ -59,11 +59,26 @@ #ifdef LIBC_BUILD_MEMSET +#ifndef __ARM_FEATURE_BTI_DEFAULT +# define __ARM_FEATURE_BTI_DEFAULT 0 +#endif + +#ifndef __ARM_FEATURE_PAC_DEFAULT +# define __ARM_FEATURE_PAC_DEFAULT 0 +#endif + .thumb .syntax unified .global memset .type memset, %function memset: +#if __ARM_FEATURE_PAC_DEFAULT +# if __ARM_FEATURE_BTI_DEFAULT + pacbti ip, lr, sp +# else + pac ip, lr, sp +# endif /* __ARM_FEATURE_BTI_DEFAULT */ +#endif /* __ARM_FEATURE_PAC_DEFAULT */ #ifdef __ARM_FEATURE_MVE vdup.8 q0, r1 mov r3, lr @@ -73,6 +88,9 @@ memset: vstrb.8 q0, [r1], #16 letp lr, 1b 2: +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx r3 #else stmfd sp!, {r0, r4-r7, lr} @@ -140,7 +158,13 @@ memset: strhmi r1, [r0], #2 movs r2, r2, lsl #2 strbcs r1, [r0] +# if __ARM_FEATURE_PAC_DEFAULT + ldmfd sp!, {r0, r4-r7, lr} + aut ip, lr, sp + bx lr +# else ldmfd sp!, {r0, r4-r7, pc} +# endif /* __ARM_FEATURE_PAC_DEFAULT */ #endif .size memset, . - memset diff --git a/libs/libc/machine/arm/armv8-m/gnu/arch_strcmp.S b/libs/libc/machine/arm/armv8-m/gnu/arch_strcmp.S index 07fb3f63961c0..a96a4c66d01b6 100644 --- a/libs/libc/machine/arm/armv8-m/gnu/arch_strcmp.S +++ b/libs/libc/machine/arm/armv8-m/gnu/arch_strcmp.S @@ -33,6 +33,14 @@ #ifdef LIBC_BUILD_STRCMP +#ifndef __ARM_FEATURE_BTI_DEFAULT +# define __ARM_FEATURE_BTI_DEFAULT 0 +#endif + +#ifndef __ARM_FEATURE_PAC_DEFAULT +# define __ARM_FEATURE_PAC_DEFAULT 0 +#endif + #ifdef __ARM_BIG_ENDIAN #define S2LO lsl #define S2LOEQ lsleq @@ -83,6 +91,13 @@ def_fn strcmp .cfi_sections .debug_frame .cfi_startproc +#if __ARM_FEATURE_PAC_DEFAULT +# if __ARM_FEATURE_BTI_DEFAULT + pacbti ip, lr, sp +# else + pac ip, lr, sp +# endif /* __ARM_FEATURE_BTI_DEFAULT */ +#endif /* __ARM_FEATURE_PAC_DEFAULT */ eor tmp1, src1, src2 tst tmp1, #3 /* Strings not at same byte offset from a word boundary. */ @@ -143,6 +158,9 @@ def_fn strcmp lsrs result, result, #24 subs result, result, data2 #endif +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr @@ -251,6 +269,9 @@ def_fn strcmp cmpcs data1, data2 beq .Lstrcmp_unaligned sub result, data1, data2 +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr 2: @@ -393,6 +414,9 @@ def_fn strcmp ldmfd sp!, {r5} .cfi_restore 5 .cfi_def_cfa_offset 0 +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr .Lstrcmp_tail: @@ -410,6 +434,9 @@ def_fn strcmp ldmfd sp!, {r5} .cfi_restore 5 .cfi_def_cfa_offset 0 +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr .cfi_endproc .size strcmp, . - strcmp diff --git a/libs/libc/machine/arm/armv8-m/gnu/arch_strcpy.S b/libs/libc/machine/arm/armv8-m/gnu/arch_strcpy.S index 72b44e949ffc1..6ab7480098c97 100644 --- a/libs/libc/machine/arm/armv8-m/gnu/arch_strcpy.S +++ b/libs/libc/machine/arm/armv8-m/gnu/arch_strcpy.S @@ -22,6 +22,14 @@ #ifdef LIBC_BUILD_STRCPY +#ifndef __ARM_FEATURE_BTI_DEFAULT +# define __ARM_FEATURE_BTI_DEFAULT 0 +#endif + +#ifndef __ARM_FEATURE_PAC_DEFAULT +# define __ARM_FEATURE_PAC_DEFAULT 0 +#endif + /* This strcpy borrowed some ideas from arch_strcmp.S(). */ /* Parameters and result. */ @@ -63,6 +71,13 @@ .type strcpy, %function strcpy: +#if __ARM_FEATURE_PAC_DEFAULT +# if __ARM_FEATURE_BTI_DEFAULT + pacbti ip, lr, sp +# else + pac ip, lr, sp +# endif /* __ARM_FEATURE_BTI_DEFAULT */ +#endif /* __ARM_FEATURE_PAC_DEFAULT */ push {result, tmp1, tmp2, tmp3, src_offset} eor tmp1, dst, src tst tmp1, #3 @@ -209,6 +224,9 @@ strcpy: mov tmp3, #0 strb tmp3, [dst] pop {result, tmp1, tmp2, tmp3, src_offset} +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr #if 0 diff --git a/libs/libc/machine/arm/armv8-m/gnu/arch_strlen.S b/libs/libc/machine/arm/armv8-m/gnu/arch_strlen.S index ca90c151ca2bb..d6c385b34cd00 100644 --- a/libs/libc/machine/arm/armv8-m/gnu/arch_strlen.S +++ b/libs/libc/machine/arm/armv8-m/gnu/arch_strlen.S @@ -68,6 +68,14 @@ #include "acle-compat.h" +#ifndef __ARM_FEATURE_BTI_DEFAULT +# define __ARM_FEATURE_BTI_DEFAULT 0 +#endif + +#ifndef __ARM_FEATURE_PAC_DEFAULT +# define __ARM_FEATURE_PAC_DEFAULT 0 +#endif + .macro def_fn f p2align=0 .text .p2align \p2align @@ -108,6 +116,13 @@ #define tmp2 r5 def_fn strlen p2align=6 +#if __ARM_FEATURE_PAC_DEFAULT +# if __ARM_FEATURE_BTI_DEFAULT + pacbti ip, lr, sp +# else + pac ip, lr, sp +# endif /* __ARM_FEATURE_BTI_DEFAULT */ +#endif /* __ARM_FEATURE_PAC_DEFAULT */ pld [srcin, #0] strd r4, r5, [sp, #-8]! bic src, srcin, #7 @@ -169,6 +184,9 @@ def_fn strlen p2align=6 clz data1a, data1a ldrd r4, r5, [sp], #8 add result, result, data1a, lsr #3 /* Bits -> Bytes. */ +#if __ARM_FEATURE_PAC_DEFAULT + aut ip, lr, sp +#endif /* __ARM_FEATURE_PAC_DEFAULT */ bx lr .Lmisaligned8: