diff options
author | Dan Li <ashimida@linux.alibaba.com> | 2022-02-21 20:01:14 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2022-02-21 20:01:14 +0000 |
commit | ce09ab17ddd21f73ff2caf6eec3b0ee9b0e1a11e (patch) | |
tree | 08702dec30a499e78265cd09be5847b496104c0a /gcc/doc | |
parent | 02aedc6f269b5e3c1f354edcf5b84d27b0a15946 (diff) | |
download | gcc-ce09ab17ddd21f73ff2caf6eec3b0ee9b0e1a11e.zip gcc-ce09ab17ddd21f73ff2caf6eec3b0ee9b0e1a11e.tar.gz gcc-ce09ab17ddd21f73ff2caf6eec3b0ee9b0e1a11e.tar.bz2 |
aarch64: Add compiler support for Shadow Call Stack
Shadow Call Stack can be used to protect the return address of a
function at runtime, and clang already supports this feature[1].
To enable SCS in user mode, in addition to compiler, other support
is also required (as discussed in [2]). This patch only adds basic
support for SCS from the compiler side, and provides convenience
for users to enable SCS.
For linux kernel, only the support of the compiler is required.
[1] https://clang.llvm.org/docs/ShadowCallStack.html
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102768
Signed-off-by: Dan Li <ashimida@linux.alibaba.com>
gcc/ChangeLog:
* config/aarch64/aarch64.cc (SLOT_REQUIRED):
Change wb_candidate[12] to wb_push_candidate[12].
(aarch64_layout_frame): Likewise, and
change callee_adjust when scs is enabled.
(aarch64_save_callee_saves):
Change wb_candidate[12] to wb_push_candidate[12].
(aarch64_restore_callee_saves):
Change wb_candidate[12] to wb_pop_candidate[12].
(aarch64_get_separate_components):
Change wb_candidate[12] to wb_push_candidate[12].
(aarch64_expand_prologue): Push x30 onto SCS before it's
pushed onto stack.
(aarch64_expand_epilogue): Pop x30 frome SCS, while
preventing it from being popped from the regular stack again.
(aarch64_override_options_internal): Add SCS compile option check.
(TARGET_HAVE_SHADOW_CALL_STACK): New hook.
* config/aarch64/aarch64.h (struct GTY): Add is_scs_enabled,
wb_pop_candidate[12], and rename wb_candidate[12] to
wb_push_candidate[12].
* config/aarch64/aarch64.md (scs_push): New template.
(scs_pop): Likewise.
* doc/invoke.texi: Document -fsanitize=shadow-call-stack.
* doc/tm.texi: Regenerate.
* doc/tm.texi.in: Add hook have_shadow_call_stack.
* flag-types.h (enum sanitize_code):
Add SANITIZE_SHADOW_CALL_STACK.
* opts.cc (parse_sanitizer_options): Add shadow-call-stack
and exclude SANITIZE_SHADOW_CALL_STACK.
* target.def: New hook.
* toplev.cc (process_options): Add SCS compile option check.
* ubsan.cc (ubsan_expand_null_ifn): Enum type conversion.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/shadow_call_stack_1.c: New test.
* gcc.target/aarch64/shadow_call_stack_2.c: New test.
* gcc.target/aarch64/shadow_call_stack_3.c: New test.
* gcc.target/aarch64/shadow_call_stack_4.c: New test.
* gcc.target/aarch64/shadow_call_stack_5.c: New test.
* gcc.target/aarch64/shadow_call_stack_6.c: New test.
* gcc.target/aarch64/shadow_call_stack_7.c: New test.
* gcc.target/aarch64/shadow_call_stack_8.c: New test.
Diffstat (limited to 'gcc/doc')
-rw-r--r-- | gcc/doc/invoke.texi | 30 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 5 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 2 |
3 files changed, 37 insertions, 0 deletions
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e1a00c8..635c5f7 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -15620,6 +15620,36 @@ add @code{detect_invalid_pointer_pairs=2} to the environment variable @env{ASAN_OPTIONS}. Using @code{detect_invalid_pointer_pairs=1} detects invalid operation only when both pointers are non-null. +@item -fsanitize=shadow-call-stack +@opindex fsanitize=shadow-call-stack +Enable ShadowCallStack, a security enhancement mechanism used to protect +programs against return address overwrites (e.g. stack buffer overflows.) +It works by saving a function's return address to a separately allocated +shadow call stack in the function prologue and restoring the return address +from the shadow call stack in the function epilogue. Instrumentation only +occurs in functions that need to save the return address to the stack. + +Currently it only supports the aarch64 platform. It is specifically +designed for linux kernels that enable the CONFIG_SHADOW_CALL_STACK option. +For the user space programs, runtime support is not currently provided +in libc and libgcc. Users who want to use this feature in user space need +to provide their own support for the runtime. It should be noted that +this may cause the ABI rules to be broken. + +On aarch64, the instrumentation makes use of the platform register @code{x18}. +This generally means that any code that may run on the same thread as code +compiled with ShadowCallStack must be compiled with the flag +@option{-ffixed-x18}, otherwise functions compiled without +@option{-ffixed-x18} might clobber @code{x18} and so corrupt the shadow +stack pointer. + +Also, because there is no userspace runtime support, code compiled with +ShadowCallStack cannot use exception handling. Use @option{-fno-exceptions} +to turn off exceptions. + +See @uref{https://clang.llvm.org/docs/ShadowCallStack.html} for more +details. + @item -fsanitize=thread @opindex fsanitize=thread Enable ThreadSanitizer, a fast data race detector. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 962bbb8..49864dd 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -12596,3 +12596,8 @@ counters are incremented using atomic operations. Targets not supporting 64-bit atomic operations may override the default value and request a 32-bit type. @end deftypefn + +@deftypevr {Target Hook} bool TARGET_HAVE_SHADOW_CALL_STACK +This value is true if the target platform supports +@option{-fsanitize=shadow-call-stack}. The default value is false. +@end deftypevr diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 394b59e..95e5e34 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -8181,3 +8181,5 @@ maintainer is familiar with. @hook TARGET_MEMTAG_UNTAGGED_POINTER @hook TARGET_GCOV_TYPE_SIZE + +@hook TARGET_HAVE_SHADOW_CALL_STACK |