[3.12] gh-139808: Add branch protections for aarch64 in asm_trampoline.S (#130864) (#150198)

Yhg1s <[email protected]> Tue, 04 Aug 2026 05:46:58 -0400 (EDT)
Newsgroups gmane.comp.python.cvs
Message-ID <[email protected]>
https://github.com/python/cpython/commit/d9d98e0f5eb1b5ca9499f7a7dca0f1416e3eb8d1
commit: d9d98e0f5eb1b5ca9499f7a7dca0f1416e3eb8d1
branch: 3.12
author: stratakis <[email protected]>
committer: Yhg1s <[email protected]>
date: 2026-08-04T11:46:47+02:00
summary:

[3.12] gh-139808: Add branch protections for aarch64 in asm_trampoline.S (#130864) (#150198)

Apply protection against ROP/JOP attacks for aarch64 on asm_trampoline.S.

The BTI flag must be applied in assembler sources for this class
of attacks to be mitigated on newer aarch64 processors.

See also:
https://sourceware.org/annobin/annobin.html/Test-branch-protection.html
and
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/enabling-pac-and-bti-on-aarch64

Co-authored-by: Victor Stinner <[email protected]>

files:
A Misc/NEWS.d/next/Core and Builtins/2026-05-12-16-47-23.gh-issue-139808.iIs7_E.rst
A Python/asm_trampoline_aarch64.h
M Python/asm_trampoline.S

diff --git a/Misc/NEWS.d/next/Core and Builtins/2026-05-12-16-47-23.gh-issue-139808.iIs7_E.rst b/Misc/NEWS.d/next/Core and Builtins/2026-05-12-16-47-23.gh-issue-139808.iIs7_E.rst
new file mode 100644
index 000000000000000..3e9d930bf1de894
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2026-05-12-16-47-23.gh-issue-139808.iIs7_E.rst	
@@ -0,0 +1,2 @@
+Add branch protections for AArch64 (BTI/PAC) in assembly code used by
+:option:`-X perf_jit <-X>` (Linux perf profiler integration).
diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S
index 341d0bbe51f344f..ae882660b5d4b96 100644
--- a/Python/asm_trampoline.S
+++ b/Python/asm_trampoline.S
@@ -1,3 +1,5 @@
+#include "asm_trampoline_aarch64.h"
+
     .text
     .globl	_Py_trampoline_func_start
 # The following assembly is equivalent to:
@@ -20,10 +22,12 @@ _Py_trampoline_func_start:
 #if defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__)
     // ARM64 little endian, 64bit ABI
     // generate with aarch64-linux-gnu-gcc 12.1
+    SIGN_LR
     stp     x29, x30, [sp, -16]!
     mov     x29, sp
     blr     x3
     ldp     x29, x30, [sp], 16
+    VERIFY_LR
     ret
 #endif
     .globl	_Py_trampoline_func_end
diff --git a/Python/asm_trampoline_aarch64.h b/Python/asm_trampoline_aarch64.h
new file mode 100644
index 000000000000000..bc83aa460b6860d
--- /dev/null
+++ b/Python/asm_trampoline_aarch64.h
@@ -0,0 +1,56 @@
+#ifndef ASM_TRAMPOLINE_AARCH_64_H_
+#define ASM_TRAMPOLINE_AARCH_64_H_
+
+/*
+ * 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_J hint 36 /* bti j: for jumps, IE br instructions */
+  #define BTI_C hint 34  /* bti c: for calls, IE bl instructions */
+  #define GNU_PROPERTY_AARCH64_BTI 1 /* bit 0 GNU Notes is for BTI support */
+#else
+  #define BTI_J
+  #define BTI_C
+  #define GNU_PROPERTY_AARCH64_BTI 0
+#endif
+
+#if defined(__ARM_FEATURE_PAC_DEFAULT)
+  #if __ARM_FEATURE_PAC_DEFAULT & 1
+    #define SIGN_LR hint 25 /* paciasp: sign with the A key */
+    #define VERIFY_LR hint 29 /* autiasp: verify with the A key */
+  #elif __ARM_FEATURE_PAC_DEFAULT & 2
+    #define SIGN_LR hint 27 /* pacibsp: sign with the b key */
+    #define VERIFY_LR hint 31 /* autibsp: verify with the b key */
+  #endif
+  #define GNU_PROPERTY_AARCH64_POINTER_AUTH 2 /* bit 1 GNU Notes is for PAC support */
+#else
+  #define SIGN_LR BTI_C
+  #define VERIFY_LR
+  #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0
+#endif
+
+#if defined(__ARM_FEATURE_GCS_DEFAULT) && __ARM_FEATURE_GCS_DEFAULT == 1
+  #define GNU_PROPERTY_AARCH64_GCS 4 /* bit 2 GNU Notes is for GCS support */
+#else
+  #define GNU_PROPERTY_AARCH64_GCS 0
+#endif
+
+/* Add the BTI, PAC and GCS support to GNU Notes section */
+#if GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 || GNU_PROPERTY_AARCH64_GCS != 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|GNU_PROPERTY_AARCH64_GCS); /* BTI, PAC or GCS is enabled */
+    .long 0; /* padding for 8 byte alignment */
+    .popsection; /* end the section */
+#endif
+
+#endif

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]