Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[compiler-rt] Fix interceptors with AArch64 BTI #84061

Merged
merged 1 commit into from
Mar 13, 2024
Merged

Conversation

melver
Copy link
Contributor

@melver melver commented Mar 5, 2024

On AArch64 with BTI, we have to start functions with the appropriate
BTI hint to indicate that the function is a valid call target.

To support interceptors with AArch64 BTI, add "BTI c".

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 5, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Marco Elver (melver)

Changes

On AArch64 with BTI and/or PAC, we have to prefix the function body with the appropriate hints/checks. PACIASP is an implicit branch target identification instructions which is equivalent to BTI c.


Full diff: https://github.com/llvm/llvm-project/pull/84061.diff

2 Files Affected:

  • (modified) compiler-rt/lib/interception/interception.h (+1)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_asm.h (+7)
diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h
index 00bcd979638b53..5a8fb24a9ccb2c 100644
--- a/compiler-rt/lib/interception/interception.h
+++ b/compiler-rt/lib/interception/interception.h
@@ -205,6 +205,7 @@ const interpose_substitution substitution_##func_name[]             \
          ASM_TYPE_FUNCTION_STR "\n"                                            \
        SANITIZER_STRINGIFY(TRAMPOLINE(func)) ":\n"                             \
        SANITIZER_STRINGIFY(CFI_STARTPROC) "\n"                                 \
+       SANITIZER_STRINGIFY(ASM_PAC_STARTPROC) "\n"                             \
        C_ASM_TAIL_CALL(SANITIZER_STRINGIFY(TRAMPOLINE(func)),                  \
                        "__interceptor_"                                        \
                          SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func))) "\n"  \
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
index 3af66a4e449988..bd4421b1991c2b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
@@ -42,6 +42,12 @@
 # define CFI_RESTORE(reg)
 #endif
 
+#if defined(__aarch64__)
+# define ASM_PAC_STARTPROC paciasp
+#else
+# define ASM_PAC_STARTPROC
+#endif
+
 #if defined(__x86_64__) || defined(__i386__) || defined(__sparc__)
 # define ASM_TAIL_CALL jmp
 #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
@@ -115,6 +121,7 @@
          ASM_TYPE_FUNCTION(__interceptor_trampoline_##name);                   \
          __interceptor_trampoline_##name:                                      \
                  CFI_STARTPROC;                                                \
+                 ASM_PAC_STARTPROC;                                            \
                  ASM_TAIL_CALL ASM_PREEMPTIBLE_SYM(__interceptor_##name);      \
                  CFI_ENDPROC;                                                  \
          ASM_SIZE(__interceptor_trampoline_##name)

Copy link

github-actions bot commented Mar 5, 2024

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 17162b61c2e6968482fab928f89bdca8b4ac06d9 f6f0c2a3ad24651decaa739893c17a75e49550ef -- compiler-rt/lib/interception/interception.h compiler-rt/lib/sanitizer_common/sanitizer_asm.h
View the diff from clang-format here.
diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h
index 38c152952e..029a1d7de3 100644
--- a/compiler-rt/lib/interception/interception.h
+++ b/compiler-rt/lib/interception/interception.h
@@ -191,12 +191,12 @@ const interpose_substitution substitution_##func_name[]             \
 #   define ASM_TYPE_FUNCTION_STR "@function"
 #  endif
 // Keep trampoline implementation in sync with sanitizer_common/sanitizer_asm.h
-#  define DECLARE_WRAPPER(ret_type, func, ...)                                 \
-     extern "C" ret_type func(__VA_ARGS__);                                    \
-     extern "C" ret_type TRAMPOLINE(func)(__VA_ARGS__);                        \
-     extern "C" ret_type __interceptor_##func(__VA_ARGS__)                     \
-       INTERCEPTOR_ATTRIBUTE __attribute__((weak)) ALIAS(WRAP(func));          \
-     asm(                                                                      \
+#    define DECLARE_WRAPPER(ret_type, func, ...)                         \
+      extern "C" ret_type func(__VA_ARGS__);                             \
+      extern "C" ret_type TRAMPOLINE(func)(__VA_ARGS__);                 \
+      extern "C" ret_type __interceptor_##func(__VA_ARGS__)              \
+          INTERCEPTOR_ATTRIBUTE __attribute__((weak)) ALIAS(WRAP(func)); \
+      asm(                                                                      \
        ".text\n"                                                               \
        __ASM_WEAK_WRAPPER(func)                                                \
        ".set " #func ", " SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n"           \
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
index 30e9d15184..ac8b497ac6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
@@ -43,11 +43,13 @@
 #endif
 
 #if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT)
-# define ASM_STARTPROC CFI_STARTPROC; hint #34
-# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) "\nhint #34"
+#  define ASM_STARTPROC \
+    CFI_STARTPROC;      \
+    hint #34
+#  define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) "\nhint #34"
 #else
-# define ASM_STARTPROC CFI_STARTPROC
-# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC)
+#  define ASM_STARTPROC CFI_STARTPROC
+#  define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC)
 #endif
 #define ASM_ENDPROC CFI_ENDPROC
 #define C_ASM_ENDPROC SANITIZER_STRINGIFY(CFI_ENDPROC)
@@ -118,17 +120,16 @@
 #  define ASM_TRAMPOLINE_ALIAS(symbol, name)                                   \
          .weak symbol;                                                         \
          .set symbol, __interceptor_trampoline_##name
-#  define ASM_INTERCEPTOR_TRAMPOLINE(name)                                     \
-         .weak __interceptor_##name;                                           \
-         .set __interceptor_##name, ASM_WRAPPER_NAME(name);                    \
-         .globl __interceptor_trampoline_##name;                               \
-         ASM_TYPE_FUNCTION(__interceptor_trampoline_##name);                   \
-         __interceptor_trampoline_##name:                                      \
-                 ASM_STARTPROC;                                                \
-                 ASM_TAIL_CALL ASM_PREEMPTIBLE_SYM(__interceptor_##name);      \
-                 ASM_ENDPROC;                                                  \
-         ASM_SIZE(__interceptor_trampoline_##name)
-#  define ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT 1
+#    define ASM_INTERCEPTOR_TRAMPOLINE(name)                   \
+      .weak __interceptor_##name;                              \
+      .set __interceptor_##name, ASM_WRAPPER_NAME(name);       \
+      .globl __interceptor_trampoline_##name;                  \
+      ASM_TYPE_FUNCTION(__interceptor_trampoline_##name);      \
+      __interceptor_trampoline_##name : ASM_STARTPROC;         \
+      ASM_TAIL_CALL ASM_PREEMPTIBLE_SYM(__interceptor_##name); \
+      ASM_ENDPROC;                                             \
+      ASM_SIZE(__interceptor_trampoline_##name)
+#    define ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT 1
 # endif  // Architecture supports interceptor trampoline
 #else
 # define ASM_HIDDEN(symbol)

@melver
Copy link
Contributor Author

melver commented Mar 5, 2024

Question: Do we need both PACIASP or just BTI hint?

@eugenis
Copy link
Contributor

eugenis commented Mar 5, 2024

It has to be BTI C, AFAIK. PACIASP will sign LR, which I believe will break when the callee will try to sign it again.

On AArch64 with BTI, we have to start functions with the appropriate
BTI hint to indicate that the function is a valid call target.

To support interceptors with AArch64 BTI, add "BTI c".
@melver melver changed the title [compiler-rt] Fix interceptors with BTI and PAC [compiler-rt] Fix interceptors with AArch64 BTI Mar 6, 2024
@melver
Copy link
Contributor Author

melver commented Mar 6, 2024

PTAL

@melver melver requested a review from vitalybuka March 9, 2024 09:07
@eugenis
Copy link
Contributor

eugenis commented Mar 12, 2024

LGTM, thanks!

@melver melver merged commit 1c792d2 into llvm:main Mar 13, 2024
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants