Re: [AArch64] Accelerate -fstack-protector through pointer authentication extension
On 15/02/17 15:45, Richard Earnshaw (lists) wrote: On 18/01/17 17:10, Jiong Wang wrote: NOTE, this approach however requires DWARF change as the original LR is signed, the binary needs new libgcc to make sure c++ eh works correctly. Given this acceleration already needs the user specify -mstack-protector-dialect=pauth which means the target platform largely should have install new libgcc, otherwise you can't utilize new pointer authentication features. gcc/ 2016-11-11 Jiong Wang* config/aarch64/aarch64-opts.h (aarch64_stack_protector_type): New enum. (aarch64_layout_frame): Swap callees and locals when -mstack-protector-dialect=pauth specified. (aarch64_expand_prologue): Use AARCH64_PAUTH_SSP_OR_RA_SIGN instead of AARCH64_ENABLE_RETURN_ADDRESS_SIGN. (aarch64_expand_epilogue): Likewise. * config/aarch64/aarch64.md (*do_return): Likewise. (aarch64_override_options): Sanity check for ILP32 and TARGET_PAUTH. * config/aarch64/aarch64.h (AARCH64_PAUTH_SSP_OPTION, AARCH64_PAUTH_SSP, AARCH64_PAUTH_SSP_OR_RA_SIGN, LINK_SSP_SPEC): New defines. * config/aarch64/aarch64.opt (-mstack-protector-dialect=): New option. * doc/invoke.texi (AArch64 Options): Documents -mstack-protector-dialect=. Patch updated to migrate to TARGET_STACK_PROTECT_RUNTIME_ENABLED_P. aarch64 cross check OK with the following options enabled on all testcases. -fstack-protector-all -mstack-protector-pauth OK for trunk? gcc/ 2017-01-18 Jiong Wang * config/aarch64/aarch64-protos.h (aarch64_pauth_stack_protector_enabled): New declaration. * config/aarch64/aarch64.c (aarch64_layout_frame): Swap callee-save area and locals area when aarch64_pauth_stack_protector_enabled returns true. (aarch64_stack_protect_runtime_enabled): New function. (aarch64_pauth_stack_protector_enabled): New function. (aarch64_return_address_signing_enabled): Enabled by aarch64_pauth_stack_protector_enabled. (aarch64_override_options): Sanity check for -mstack-protector-pauth. (TARGET_STACK_PROTECT_RUNTIME_ENABLED_P): Define. * config/aarch64/aarch64.h (LINK_SSP_SPEC): Likewise. * config/aarch64/aarch64.opt (-mstack-protector-pauth): New option. * doc/invoke.texi (AArch64 Options): Documents -mstack-protector-pauth. gcc/testsuite/ * gcc.target/aarch64/stack_protector_1.c: New test. 1.patch diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 632dd4768d82c340ae4e9b4a93206743756c06e7..a3ad623eef498d00b52d24bf02a5748fad576c3d 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -383,6 +383,7 @@ void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx, void aarch64_init_expanders (void); void aarch64_init_simd_builtins (void); void aarch64_emit_call_insn (rtx); +bool aarch64_pauth_stack_protector_enabled (void); void aarch64_register_pragmas (void); void aarch64_relayout_simd_types (void); void aarch64_reset_previous_fndecl (void); diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 3718ad1b3bf27c6bdb9e74831fd660e617cccbde..dd742d37ab6fc6fb5085e1c6b5d86d5ce1ce5f8a 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -958,4 +958,11 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); extern tree aarch64_fp16_type_node; extern tree aarch64_fp16_ptr_type_node; +#ifndef TARGET_LIBC_PROVIDES_SSP +#define LINK_SSP_SPEC "%{!mstack-protector-pauth:\ +%{fstack-protector|fstack-protector-all\ + |fstack-protector-strong|fstack-protector-explicit:\ + -lssp_nonshared -lssp}}" +#endif + I don't think we want to suppress this. PAUTH pased stack protections isn't an all-or-nothing solution. What if some object files are built with traditional -fstack-protector code? I had done a decription on this in the ping email (changed summary may caused trouble to email client) -- Code compiled with "-mstack-protector-pauth" can co-work with code compiled without "-mstack-protector-pauth". The only problem is when "-mstack-protector-pauth" is specified, "-lssp/-lssp_nonshared" won't be implied as the software runtime supports are not required any more. So if the user has some object files compiled using default stack protector and wants them to be linked with object files compiled using "-mstack-protector-pauth", if "-mstack-protector-pauth" appear in the final command line and "gcc" is used as linker driver, then "-lssp/-lssp_nonshared" needs to be specified explicitly. -- Generally, after
Re: [AArch64] Accelerate -fstack-protector through pointer authentication extension
On 18/01/17 17:10, Jiong Wang wrote: >> NOTE, this approach however requires DWARF change as the original LR >> is signed, >> the binary needs new libgcc to make sure c++ eh works correctly. >> Given this >> acceleration already needs the user specify >> -mstack-protector-dialect=pauth >> which means the target platform largely should have install new >> libgcc, otherwise >> you can't utilize new pointer authentication features. >> >> gcc/ >> 2016-11-11 Jiong Wang>> >> * config/aarch64/aarch64-opts.h >> (aarch64_stack_protector_type): New >> enum. >> (aarch64_layout_frame): Swap callees and locals when >> -mstack-protector-dialect=pauth specified. >> (aarch64_expand_prologue): Use AARCH64_PAUTH_SSP_OR_RA_SIGN >> instead >> of AARCH64_ENABLE_RETURN_ADDRESS_SIGN. >> (aarch64_expand_epilogue): Likewise. >> * config/aarch64/aarch64.md (*do_return): Likewise. >> (aarch64_override_options): Sanity check for ILP32 and >> TARGET_PAUTH. >> * config/aarch64/aarch64.h (AARCH64_PAUTH_SSP_OPTION, >> AARCH64_PAUTH_SSP, >> AARCH64_PAUTH_SSP_OR_RA_SIGN, LINK_SSP_SPEC): New defines. >> * config/aarch64/aarch64.opt (-mstack-protector-dialect=): New >> option. >> * doc/invoke.texi (AArch64 Options): Documents >> -mstack-protector-dialect=. >> > Patch updated > to migrate to TARGET_STACK_PROTECT_RUNTIME_ENABLED_P. > > aarch64 cross check OK with the following options enabled on all testcases. > -fstack-protector-all -mstack-protector-pauth > > OK for trunk? > gcc/ > 2017-01-18 Jiong Wang >* config/aarch64/aarch64-protos.h > (aarch64_pauth_stack_protector_enabled): New declaration. > * config/aarch64/aarch64.c (aarch64_layout_frame): Swap > callee-save area > and locals area when aarch64_pauth_stack_protector_enabled > returns true. > (aarch64_stack_protect_runtime_enabled): New function. > (aarch64_pauth_stack_protector_enabled): New function. > (aarch64_return_address_signing_enabled): Enabled by > aarch64_pauth_stack_protector_enabled. > (aarch64_override_options): Sanity check for > -mstack-protector-pauth. > (TARGET_STACK_PROTECT_RUNTIME_ENABLED_P): Define. > * config/aarch64/aarch64.h (LINK_SSP_SPEC): Likewise. > * config/aarch64/aarch64.opt (-mstack-protector-pauth): New option. > * doc/invoke.texi (AArch64 Options): Documents > -mstack-protector-pauth. > > gcc/testsuite/ > * gcc.target/aarch64/stack_protector_1.c: New test. > > > 1.patch > > > diff --git a/gcc/config/aarch64/aarch64-protos.h > b/gcc/config/aarch64/aarch64-protos.h > index > 632dd4768d82c340ae4e9b4a93206743756c06e7..a3ad623eef498d00b52d24bf02a5748fad576c3d > 100644 > --- a/gcc/config/aarch64/aarch64-protos.h > +++ b/gcc/config/aarch64/aarch64-protos.h > @@ -383,6 +383,7 @@ void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, > const_tree, rtx, > void aarch64_init_expanders (void); > void aarch64_init_simd_builtins (void); > void aarch64_emit_call_insn (rtx); > +bool aarch64_pauth_stack_protector_enabled (void); > void aarch64_register_pragmas (void); > void aarch64_relayout_simd_types (void); > void aarch64_reset_previous_fndecl (void); > diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h > index > 3718ad1b3bf27c6bdb9e74831fd660e617cccbde..dd742d37ab6fc6fb5085e1c6b5d86d5ce1ce5f8a > 100644 > --- a/gcc/config/aarch64/aarch64.h > +++ b/gcc/config/aarch64/aarch64.h > @@ -958,4 +958,11 @@ extern const char *host_detect_local_cpu (int argc, > const char **argv); > extern tree aarch64_fp16_type_node; > extern tree aarch64_fp16_ptr_type_node; > > +#ifndef TARGET_LIBC_PROVIDES_SSP > +#define LINK_SSP_SPEC "%{!mstack-protector-pauth:\ > + %{fstack-protector|fstack-protector-all\ > +|fstack-protector-strong|fstack-protector-explicit:\ > +-lssp_nonshared -lssp}}" > +#endif > + I don't think we want to suppress this. PAUTH pased stack protections isn't an all-or-nothing solution. What if some object files are built with traditional -fstack-protector code? If the library isn't referenced by any of the input objects we won't pull anything useful in from the library, so leaving it in the link list should be harmless. > #endif /* GCC_AARCH64_H */ > diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c > index > 6451b08191cf1a44aed502930da8603111f6e8ca..461f7b59584af9315accaecc0256abc9a2df4350 > 100644 > --- a/gcc/config/aarch64/aarch64.c > +++ b/gcc/config/aarch64/aarch64.c > @@ -2884,8 +2884,28 @@ aarch64_layout_frame (void) >else if (cfun->machine->frame.wb_candidate1 != INVALID_REGNUM) > max_push_offset = 256; > > -
[AArch64] Accelerate -fstack-protector through pointer authentication extension
NOTE, this approach however requires DWARF change as the original LR is signed, the binary needs new libgcc to make sure c++ eh works correctly. Given this acceleration already needs the user specify -mstack-protector-dialect=pauth which means the target platform largely should have install new libgcc, otherwise you can't utilize new pointer authentication features. gcc/ 2016-11-11 Jiong Wang* config/aarch64/aarch64-opts.h (aarch64_stack_protector_type): New enum. (aarch64_layout_frame): Swap callees and locals when -mstack-protector-dialect=pauth specified. (aarch64_expand_prologue): Use AARCH64_PAUTH_SSP_OR_RA_SIGN instead of AARCH64_ENABLE_RETURN_ADDRESS_SIGN. (aarch64_expand_epilogue): Likewise. * config/aarch64/aarch64.md (*do_return): Likewise. (aarch64_override_options): Sanity check for ILP32 and TARGET_PAUTH. * config/aarch64/aarch64.h (AARCH64_PAUTH_SSP_OPTION, AARCH64_PAUTH_SSP, AARCH64_PAUTH_SSP_OR_RA_SIGN, LINK_SSP_SPEC): New defines. * config/aarch64/aarch64.opt (-mstack-protector-dialect=): New option. * doc/invoke.texi (AArch64 Options): Documents -mstack-protector-dialect=. Patch updated to migrate to TARGET_STACK_PROTECT_RUNTIME_ENABLED_P. aarch64 cross check OK with the following options enabled on all testcases. -fstack-protector-all -mstack-protector-pauth OK for trunk? gcc/ 2017-01-18 Jiong Wang * config/aarch64/aarch64-protos.h (aarch64_pauth_stack_protector_enabled): New declaration. * config/aarch64/aarch64.c (aarch64_layout_frame): Swap callee-save area and locals area when aarch64_pauth_stack_protector_enabled returns true. (aarch64_stack_protect_runtime_enabled): New function. (aarch64_pauth_stack_protector_enabled): New function. (aarch64_return_address_signing_enabled): Enabled by aarch64_pauth_stack_protector_enabled. (aarch64_override_options): Sanity check for -mstack-protector-pauth. (TARGET_STACK_PROTECT_RUNTIME_ENABLED_P): Define. * config/aarch64/aarch64.h (LINK_SSP_SPEC): Likewise. * config/aarch64/aarch64.opt (-mstack-protector-pauth): New option. * doc/invoke.texi (AArch64 Options): Documents -mstack-protector-pauth. gcc/testsuite/ * gcc.target/aarch64/stack_protector_1.c: New test. diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 632dd4768d82c340ae4e9b4a93206743756c06e7..a3ad623eef498d00b52d24bf02a5748fad576c3d 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -383,6 +383,7 @@ void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx, void aarch64_init_expanders (void); void aarch64_init_simd_builtins (void); void aarch64_emit_call_insn (rtx); +bool aarch64_pauth_stack_protector_enabled (void); void aarch64_register_pragmas (void); void aarch64_relayout_simd_types (void); void aarch64_reset_previous_fndecl (void); diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 3718ad1b3bf27c6bdb9e74831fd660e617cccbde..dd742d37ab6fc6fb5085e1c6b5d86d5ce1ce5f8a 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -958,4 +958,11 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); extern tree aarch64_fp16_type_node; extern tree aarch64_fp16_ptr_type_node; +#ifndef TARGET_LIBC_PROVIDES_SSP +#define LINK_SSP_SPEC "%{!mstack-protector-pauth:\ + %{fstack-protector|fstack-protector-all\ + |fstack-protector-strong|fstack-protector-explicit:\ + -lssp_nonshared -lssp}}" +#endif + #endif /* GCC_AARCH64_H */ diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 6451b08191cf1a44aed502930da8603111f6e8ca..461f7b59584af9315accaecc0256abc9a2df4350 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -2884,8 +2884,28 @@ aarch64_layout_frame (void) else if (cfun->machine->frame.wb_candidate1 != INVALID_REGNUM) max_push_offset = 256; - if (cfun->machine->frame.frame_size < max_push_offset - && crtl->outgoing_args_size == 0) + /* Swap callee-save and local variables area to make callee-save which + includes return address register X30/LR position above local variables + that any local buffer overflow will override return address. */ + if (aarch64_pauth_stack_protector_enabled ()) +{ + if (varargs_and_saved_regs_size < max_push_offset) + /* stp reg1, reg2, [sp, -varargs_and_saved_regs_size]!. */ + cfun->machine->frame.callee_adjust = varargs_and_saved_regs_size; + else + /* sub sp, sp, varargs_and_saved_regs_size. */ + cfun->machine->frame.initial_adjust = varargs_and_saved_regs_size; + + /*
[9/9][RFC][AArch64] Accelerate -fstack-protector through pointer authentication extension
This patch accelerates GCC's existed -fstack-protector using ARMv8.3-A pointer authentication instructions. Given AArch64 currently has the following stack layout: | caller's LR | | | canary<- sentinel for -fstack-protector | locals (buffer located here) | | | other callees | | callee's LR <- sentinel for -msign-return-address | | we can switch locals and callees, | ... | vararg | | other callee | | LR | | locals (buffer located here) We then sign LR and make it serve as canary value. There are several benefits of this approach: * It's evetually -msign-return-address + swap locals and callees areas. * Require nearly no modifications on prologue and epilogue, avoid making them complexer. * No need of any other runtime support, libssp is not required. The runtime overhead before and after this patch will be: o canary insert GCC default SSP runtime was loading from global variable "__stack_chk_guard" initilized in libssp: adrpx19, _GLOBAL_OFFSET_TABLE_ ldr x19, [x19, #:gotpage_lo15:__stack_chk_guard] ldr x2, [x19] str x2, [x29, 56] this patch accelerats into: sign lr o canary check GCC default SSP runtime was reloading from stack, then comparing with original value and branch to abort function: ldr x2, [x29, 56] ldr x1, [x19] eor x1, x2, x1 cbnzx1, .L5 ... ret .L5: bl __stack_chk_fail acclerated into: aut lr + ret or retaa the the canary value (signed LR) fails authentication, the return to invalid address will cause exception. NOTE, this approach however requires DWARF change as the original LR is signed, the binary needs new libgcc to make sure c++ eh works correctly. Given this acceleration already needs the user specify -mstack-protector-dialect=pauth which means the target platform largely should have install new libgcc, otherwise you can't utilize new pointer authentication features. gcc/ 2016-11-11 Jiong Wang* config/aarch64/aarch64-opts.h (aarch64_stack_protector_type): New enum. (aarch64_layout_frame): Swap callees and locals when -mstack-protector-dialect=pauth specified. (aarch64_expand_prologue): Use AARCH64_PAUTH_SSP_OR_RA_SIGN instead of AARCH64_ENABLE_RETURN_ADDRESS_SIGN. (aarch64_expand_epilogue): Likewise. * config/aarch64/aarch64.md (*do_return): Likewise. (aarch64_override_options): Sanity check for ILP32 and TARGET_PAUTH. * config/aarch64/aarch64.h (AARCH64_PAUTH_SSP_OPTION, AARCH64_PAUTH_SSP, AARCH64_PAUTH_SSP_OR_RA_SIGN, LINK_SSP_SPEC): New defines. * config/aarch64/aarch64.opt (-mstack-protector-dialect=): New option. * doc/invoke.texi (AArch64 Options): Documents -mstack-protector-dialect=. diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h index 41c14b38a6188d399eb04baca2896e033c03ff1b..ff464ea5675146d62f0b676fe776f882fc1b8d80 100644 --- a/gcc/config/aarch64/aarch64-opts.h +++ b/gcc/config/aarch64/aarch64-opts.h @@ -99,4 +99,10 @@ enum aarch64_function_type { AARCH64_FUNCTION_ALL }; +/* GCC standard stack protector (Canary insertion based) types for AArch64. */ +enum aarch64_stack_protector_type { + STACK_PROTECTOR_TRAD, + STACK_PROTECTOR_PAUTH +}; + #endif diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 907e8bdf5b4961b3107dcd5a481de28335e4be89..73ef2677a11450fe21f765011317bd3367ef0d94 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -982,4 +982,25 @@ enum aarch64_pauth_action_type AARCH64_PAUTH_AUTH }; +/* Pointer authentication accelerated -fstack-protector. */ +#define AARCH64_PAUTH_SSP_OPTION \ + (TARGET_PAUTH && aarch64_stack_protector_dialect == STACK_PROTECTOR_PAUTH) + +#define AARCH64_PAUTH_SSP \ + (crtl->stack_protect_guard && AARCH64_PAUTH_SSP_OPTION) + +#define AARCH64_PAUTH_SSP_OR_RA_SIGN \ + (AARCH64_PAUTH_SSP || AARCH64_ENABLE_RETURN_ADDRESS_SIGN) + +#ifndef TARGET_LIBC_PROVIDES_SSP +#define LINK_SSP_SPEC "%{!mstack-protector-dialect=pauth:\ + %{fstack-protector|fstack-protector-all\ + |fstack-protector-strong|fstack-protector-explicit:\ + -lssp_nonshared -lssp}}" +#endif + +/* Don't use GCC default SSP runtime if pointer authentication acceleration + enabled. */ +#define ENABLE_DEFAULT_SSP_RUNTIME !(AARCH64_PAUTH_SSP_OPTION) + #endif /* GCC_AARCH64_H */ diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index cae177dca511fdb909ef82c972d3bbdebab215e2..c469baf92268ff894f5cf0ea9f5dbd4180714b98 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -2993,6 +2993,15 @@ aarch64_layout_frame (void) = cfun->machine->frame.frame_size -