GCC 12 Adds Support For AArch64 Shadow Call Stack
LLVM/Clang spearheaded Shadow Call Stack (SCS) for protecting the return address of a function at run-time. Shadow Call Stack has proven useful on AArch64 while was a bust on x86_64 and already removed.
The LLVM documentation sums up Shadow Call Stack as:
ShadowCallStack is an instrumentation pass, currently only implemented for aarch64, that protects 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 prolog in non-leaf functions and loading the return address from the shadow call stack in the function epilog. The return address is also stored on the regular stack for compatibility with unwinders, but is otherwise unused.
The aarch64 implementation is considered production ready, and an implementation of the runtime has been added to Android’s libc (bionic). An x86_64 implementation was evaluated using Chromium and was found to have critical performance and security deficiencies–it was removed in LLVM 9.0.
Thanks to the work of an Alibaba engineer, GCC now has Shadow Call Stack support on AArch64 too for the compiler-side changes for SCS support.
Like with Clang, the GCC SCS AArch64 functionality can be enabled with the -fsanitize=shadow-call-stack compiler option.