From 60bfded20973316e69e2a45d98ac676fd82d20d4 Mon Sep 17 00:00:00 2001 From: Bill Roberts Date: Mon, 19 Aug 2024 12:47:12 -0500 Subject: [PATCH] aarch64: enable PAC/BTI Enable Pointer Authentication Codes (PAC) and Branch Target Identification (BTI) support for ARM 64 targets. PAC works by signing the LR with either an A key or B key and verifying the return address. Since the assembly code does not push and pop the link register to the stack, and it remains in the register file, their is no need to sign the LR, so PAC is essentially just adding it to the GNU notes section for auditing purposes. BTI works by marking all call and jump positions with bti c and bti j instructions. If execution control transfers via an indirect branch or call to an instruction other than a BTI instruction, the execution is killed via SIGILL. For BTI to work, all object files linked for a unit of execution, whether an executable or a library must have the GNU Notes section of the ELF file marked to indicate BTI support. This is so loader/linkers can apply the proper permission bits (PROT_BRI) on the memory region. PAC can also be annotated in the GNU ELF notes section, but it's not required for enablement, as interleaved PAC and non-pac code works as expected since it's the callee that performs all the checking. Becuase the aarch64 assembly code does not make use of pushing the LR to the stack, only BTI targets were needed to be instrumented and the GNU notes section indicating support for BTU. Thus for PAC the only requirement was to mark the GNU notes section as supporting PAC. Testing was done under the following CFLAGS: 1. -mbranch-protection=none 2. -mbranch-protection=standard 3. -mbranch-protection=pac-ret 4. -mbranch-protection=pac-ret+b-key 5. -mbranch-protection=bti Signed-off-by: Bill Roberts --- src/libmpg123/aarch64_defs.h | 54 ++++++++++++++++++++ src/libmpg123/check_neon.S | 2 + src/libmpg123/dct36_neon64.S | 2 + src/libmpg123/dct64_neon64_float.S | 2 + src/libmpg123/synth_neon64_accurate.S | 2 + src/libmpg123/synth_neon64_float.S | 2 + src/libmpg123/synth_neon64_s32.S | 2 + src/libmpg123/synth_stereo_neon64_accurate.S | 2 + src/libmpg123/synth_stereo_neon64_float.S | 2 + src/libmpg123/synth_stereo_neon64_s32.S | 2 + 10 files changed, 72 insertions(+) create mode 100644 src/libmpg123/aarch64_defs.h diff --git a/src/libmpg123/aarch64_defs.h b/src/libmpg123/aarch64_defs.h new file mode 100644 index 00000000..23b4c90d --- /dev/null +++ b/src/libmpg123/aarch64_defs.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: LGPL-2.1 + * + * aarch64_defs.h: Support macros for the aarch64 architectural features + */ + +#ifndef SRC_LIBMPG123_AARCH64_DEFS_H_ +#define SRC_LIBMPG123_AARCH64_DEFS_H_ + +/* + * Guard this header so arm assembly files can just include it without the need + * to if-def each instance. + */ +#ifdef __aarch64__ + +/* + * References: + * - https://developer.arm.com/documentation/101028/0012/5--Feature-test-macros + * - https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst + */ + +#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 + #define BTI_C hint 34 /* bti c: for calls, IE blr instructions */ + #define GNU_PROPERTY_AARCH64_BTI 1 /* bit 0 GNU Notes is for BTI support */ +#else + #define BTI_C + #define GNU_PROPERTY_AARCH64_BTI 0 +#endif + +#if defined(__ARM_FEATURE_PAC_DEFAULT) + #define GNU_PROPERTY_AARCH64_POINTER_AUTH 2 /* bit 1 GNU Notes is for PAC support */ +#else + #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 +#endif + +/* Add the BTI support to GNU Notes section */ +#if defined(__ASSEMBLER__) && defined(__ELF__) +#if GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 + .pushsection .note.gnu.property, "a"; /* Start a new allocatable section */ + .balign 8; /* align it on a byte boundry */ + .long 4; /* size of "GNU\0" */ + .long 0x10; /* size of descriptor */ + .long 0x5; /* NT_GNU_PROPERTY_TYPE_0 */ + .asciz "GNU"; + .long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ + .long 4; /* Four bytes of data */ + .long (GNU_PROPERTY_AARCH64_BTI|GNU_PROPERTY_AARCH64_POINTER_AUTH); /* BTI or PAC is enabled */ + .long 0; /* padding for 8 byte alignment */ + .popsection; /* end the section */ +#endif /* GNU Notes additions */ +#endif /* if __ASSEMBLER__ and __ELF__ */ + +#endif /* __arch64__ */ + +#endif /* SRC_LIBMPG123_AARCH64_DEFS_H_ */ diff --git a/src/libmpg123/check_neon.S b/src/libmpg123/check_neon.S index 008c491c..2816d369 100644 --- a/src/libmpg123/check_neon.S +++ b/src/libmpg123/check_neon.S @@ -6,6 +6,7 @@ initially written by Taihei Momma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __aarch64__ @@ -25,6 +26,7 @@ ALIGN4 ASM_NAME(INT123_check_neon): #ifdef __aarch64__ + BTI_C orr v0.16b, v0.16b, v0.16b ret #else diff --git a/src/libmpg123/dct36_neon64.S b/src/libmpg123/dct36_neon64.S index b2c9134a..56b51a1c 100644 --- a/src/libmpg123/dct36_neon64.S +++ b/src/libmpg123/dct36_neon64.S @@ -6,6 +6,7 @@ initially written by Taihei Monma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __APPLE__ @@ -49,6 +50,7 @@ dct36_aarch64_COS9: .type ASM_NAME(INT123_dct36_neon64), %function #endif ASM_NAME(INT123_dct36_neon64): + BTI_C adrp x5, AARCH64_PCREL_HI(dct36_aarch64_COS9) add x5, x5, AARCH64_PCREL_LO(dct36_aarch64_COS9) cmeq v28.16b, v28.16b, v28.16b diff --git a/src/libmpg123/dct64_neon64_float.S b/src/libmpg123/dct64_neon64_float.S index 0b81a4c7..aaebaaaa 100644 --- a/src/libmpg123/dct64_neon64_float.S +++ b/src/libmpg123/dct64_neon64_float.S @@ -6,6 +6,7 @@ initially written by Taihei Monma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __APPLE__ @@ -54,6 +55,7 @@ costab_neon_aarch64: .type ASM_NAME(INT123_dct64_real_neon64), %function #endif ASM_NAME(INT123_dct64_real_neon64): + BTI_C add x3, x2, #64 adrp x4, AARCH64_PCREL_HI(costab_neon_aarch64) add x4, x4, AARCH64_PCREL_LO(costab_neon_aarch64) diff --git a/src/libmpg123/synth_neon64_accurate.S b/src/libmpg123/synth_neon64_accurate.S index dda77f1c..13c2c611 100644 --- a/src/libmpg123/synth_neon64_accurate.S +++ b/src/libmpg123/synth_neon64_accurate.S @@ -6,6 +6,7 @@ initially written by Taihei Monma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __APPLE__ @@ -24,6 +25,7 @@ maxmin_s16: .type ASM_NAME(INT123_synth_1to1_neon64_accurate_asm), %function #endif ASM_NAME(INT123_synth_1to1_neon64_accurate_asm): + BTI_C add x0, x0, #64 sub x0, x0, x3, lsl #2 eor v31.16b, v31.16b, v31.16b diff --git a/src/libmpg123/synth_neon64_float.S b/src/libmpg123/synth_neon64_float.S index af1695f3..3457cf16 100644 --- a/src/libmpg123/synth_neon64_float.S +++ b/src/libmpg123/synth_neon64_float.S @@ -6,6 +6,7 @@ initially written by Taihei Monma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __APPLE__ @@ -23,6 +24,7 @@ scale: .type ASM_NAME(INT123_synth_1to1_real_neon64_asm), %function #endif ASM_NAME(INT123_synth_1to1_real_neon64_asm): + BTI_C add x0, x0, #64 sub x0, x0, x3, lsl #2 adrp x5, AARCH64_PCREL_HI(scale) diff --git a/src/libmpg123/synth_neon64_s32.S b/src/libmpg123/synth_neon64_s32.S index f0174152..9a930919 100644 --- a/src/libmpg123/synth_neon64_s32.S +++ b/src/libmpg123/synth_neon64_s32.S @@ -6,6 +6,7 @@ initially written by Taihei Monma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __APPLE__ @@ -25,6 +26,7 @@ maxmin_s32: .type ASM_NAME(INT123_synth_1to1_s32_neon64_asm), %function #endif ASM_NAME(INT123_synth_1to1_s32_neon64_asm): + BTI_C add x0, x0, #64 sub x0, x0, x3, lsl #2 eor v31.16b, v31.16b, v31.16b diff --git a/src/libmpg123/synth_stereo_neon64_accurate.S b/src/libmpg123/synth_stereo_neon64_accurate.S index 6cf05e50..30386386 100644 --- a/src/libmpg123/synth_stereo_neon64_accurate.S +++ b/src/libmpg123/synth_stereo_neon64_accurate.S @@ -6,6 +6,7 @@ initially written by Taihei Monma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __APPLE__ @@ -24,6 +25,7 @@ maxmin_s16: .type ASM_NAME(INT123_synth_1to1_s_neon64_accurate_asm), %function #endif ASM_NAME(INT123_synth_1to1_s_neon64_accurate_asm): + BTI_C add x0, x0, #64 sub x0, x0, x4, lsl #2 eor v30.16b, v30.16b, v30.16b diff --git a/src/libmpg123/synth_stereo_neon64_float.S b/src/libmpg123/synth_stereo_neon64_float.S index 3429596c..dd60f224 100644 --- a/src/libmpg123/synth_stereo_neon64_float.S +++ b/src/libmpg123/synth_stereo_neon64_float.S @@ -6,6 +6,7 @@ initially written by Taihei Monma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __APPLE__ @@ -23,6 +24,7 @@ scale: .type ASM_NAME(INT123_synth_1to1_real_s_neon64_asm), %function #endif ASM_NAME(INT123_synth_1to1_real_s_neon64_asm): + BTI_C add x0, x0, #64 sub x0, x0, x4, lsl #2 adrp x5, AARCH64_PCREL_HI(scale) diff --git a/src/libmpg123/synth_stereo_neon64_s32.S b/src/libmpg123/synth_stereo_neon64_s32.S index 2d61664e..02ee152f 100644 --- a/src/libmpg123/synth_stereo_neon64_s32.S +++ b/src/libmpg123/synth_stereo_neon64_s32.S @@ -6,6 +6,7 @@ initially written by Taihei Monma */ +#include "aarch64_defs.h" #include "mangle.h" #ifndef __APPLE__ @@ -25,6 +26,7 @@ maxmin_s32: .type ASM_NAME(INT123_synth_1to1_s32_s_neon64_asm), %function #endif ASM_NAME(INT123_synth_1to1_s32_s_neon64_asm): + BTI_C add x0, x0, #64 sub x0, x0, x4, lsl #2 eor v31.16b, v31.16b, v31.16b