Skip to content

Commit 6145440

Browse files
kovdan01tru
authored andcommitted
[PAC][compiler-rt] Fix init/fini array signing schema (llvm#150691)
When `ptrauth_calls` is present but `ptrauth_init_fini` is not, compiler emits raw unsigned pointers in `.init_array`/`.fini_array` sections. Previously, `__do_init`/`__do_fini` pointers, which are explicitly added to the sections, were implicitly signed (due to the presense of `ptrauth_calls`), while all the other pointers in the sections were implicitly added by the compiler and thus non-signed.. As a result, the sections contained a mix of unsigned function pointers and function pointers signed with default signing schema. This patch introduces use of inline assembly for this particular case, so we can manually specify that we do not want to sign the pointers. Note that we cannot use `__builtin_ptrauth_strip` for this purpose since its result is not a constant expression. (cherry picked from commit 19ba224)
1 parent 6943f1b commit 6145440

File tree

1 file changed

+34
-12
lines changed

1 file changed

+34
-12
lines changed

compiler-rt/lib/builtins/crtbegin.c

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,33 @@ static void __attribute__((used)) __do_init(void) {
5454
}
5555

5656
#ifdef CRT_HAS_INITFINI_ARRAY
57-
#if __has_feature(ptrauth_init_fini)
57+
# if __has_feature(ptrauth_init_fini)
5858
// TODO: use __ptrauth-qualified pointers when they are supported on clang side
59-
#if __has_feature(ptrauth_init_fini_address_discrimination)
59+
# if __has_feature(ptrauth_init_fini_address_discrimination)
6060
__attribute__((section(".init_array"), used)) static void *__init =
6161
ptrauth_sign_constant(&__do_init, ptrauth_key_init_fini_pointer,
6262
ptrauth_blend_discriminator(
6363
&__init, __ptrauth_init_fini_discriminator));
64-
#else
64+
# else
6565
__attribute__((section(".init_array"), used)) static void *__init =
6666
ptrauth_sign_constant(&__do_init, ptrauth_key_init_fini_pointer,
6767
__ptrauth_init_fini_discriminator);
68-
#endif
69-
#else
68+
# endif
69+
# elif __has_feature(ptrauth_calls)
70+
# ifdef __aarch64__
71+
// If ptrauth_init_fini feature is not present, compiler emits raw unsigned
72+
// pointers in .init_array. Use inline assembly to avoid implicit signing of
73+
// __do_init function pointer with ptrauth_calls enabled.
74+
__asm__(".pushsection .init_array,\"aw\",@init_array\n\t"
75+
".xword __do_init\n\t"
76+
".popsection");
77+
# else
78+
# error "ptrauth_calls is only supported for AArch64"
79+
# endif
80+
# else
7081
__attribute__((section(".init_array"),
7182
used)) static void (*__init)(void) = __do_init;
72-
#endif
83+
# endif
7384
#elif defined(__i386__) || defined(__x86_64__)
7485
__asm__(".pushsection .init,\"ax\",@progbits\n\t"
7586
"call __do_init\n\t"
@@ -125,22 +136,33 @@ static void __attribute__((used)) __do_fini(void) {
125136
}
126137

127138
#ifdef CRT_HAS_INITFINI_ARRAY
128-
#if __has_feature(ptrauth_init_fini)
139+
# if __has_feature(ptrauth_init_fini)
129140
// TODO: use __ptrauth-qualified pointers when they are supported on clang side
130-
#if __has_feature(ptrauth_init_fini_address_discrimination)
141+
# if __has_feature(ptrauth_init_fini_address_discrimination)
131142
__attribute__((section(".fini_array"), used)) static void *__fini =
132143
ptrauth_sign_constant(&__do_fini, ptrauth_key_init_fini_pointer,
133144
ptrauth_blend_discriminator(
134145
&__fini, __ptrauth_init_fini_discriminator));
135-
#else
146+
# else
136147
__attribute__((section(".fini_array"), used)) static void *__fini =
137148
ptrauth_sign_constant(&__do_fini, ptrauth_key_init_fini_pointer,
138149
__ptrauth_init_fini_discriminator);
139-
#endif
140-
#else
150+
# endif
151+
# elif __has_feature(ptrauth_calls)
152+
# ifdef __aarch64__
153+
// If ptrauth_init_fini feature is not present, compiler emits raw unsigned
154+
// pointers in .fini_array. Use inline assembly to avoid implicit signing of
155+
// __do_fini function pointer with ptrauth_calls enabled.
156+
__asm__(".pushsection .fini_array,\"aw\",@fini_array\n\t"
157+
".xword __do_fini\n\t"
158+
".popsection");
159+
# else
160+
# error "ptrauth_calls is only supported for AArch64"
161+
# endif
162+
# else
141163
__attribute__((section(".fini_array"),
142164
used)) static void (*__fini)(void) = __do_fini;
143-
#endif
165+
# endif
144166
#elif defined(__i386__) || defined(__x86_64__)
145167
__asm__(".pushsection .fini,\"ax\",@progbits\n\t"
146168
"call __do_fini\n\t"

0 commit comments

Comments
 (0)