From 3348c23bb919703a57a7be775ad302f229e1afaa 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 and CXXFLAGS for all combinations: 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 | 52 ++++++++++++++++++++ src/libmpg123/check_neon.S | 1 + src/libmpg123/dct36_neon64.S | 1 + src/libmpg123/dct64_neon64_float.S | 1 + src/libmpg123/synth_neon64_accurate.S | 1 + src/libmpg123/synth_neon64_float.S | 1 + src/libmpg123/synth_neon64_s32.S | 1 + src/libmpg123/synth_stereo_neon64_accurate.S | 1 + src/libmpg123/synth_stereo_neon64_float.S | 1 + src/libmpg123/synth_stereo_neon64_s32.S | 1 + 10 files changed, 61 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..f303b105 --- /dev/null +++ b/src/libmpg123/aarch64_defs.h @@ -0,0 +1,52 @@ +/* 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 GNU_PROPERTY_AARCH64_BTI 1 /* bit 0 GNU Notes is for BTI support */ +#else + #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..87f5f226 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__ diff --git a/src/libmpg123/dct36_neon64.S b/src/libmpg123/dct36_neon64.S index b2c9134a..f225f6d0 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__ diff --git a/src/libmpg123/dct64_neon64_float.S b/src/libmpg123/dct64_neon64_float.S index 0b81a4c7..902300ce 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__ diff --git a/src/libmpg123/synth_neon64_accurate.S b/src/libmpg123/synth_neon64_accurate.S index dda77f1c..2f8451f1 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__ diff --git a/src/libmpg123/synth_neon64_float.S b/src/libmpg123/synth_neon64_float.S index af1695f3..bdbae263 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__ diff --git a/src/libmpg123/synth_neon64_s32.S b/src/libmpg123/synth_neon64_s32.S index f0174152..4deca077 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__ diff --git a/src/libmpg123/synth_stereo_neon64_accurate.S b/src/libmpg123/synth_stereo_neon64_accurate.S index 6cf05e50..fa6ba380 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__ diff --git a/src/libmpg123/synth_stereo_neon64_float.S b/src/libmpg123/synth_stereo_neon64_float.S index 3429596c..6c5eb4f2 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__ diff --git a/src/libmpg123/synth_stereo_neon64_s32.S b/src/libmpg123/synth_stereo_neon64_s32.S index 2d61664e..85d3a58b 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__