diff --git a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs index bfd88bd042e62..61226809e52a2 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64gc_unknown_none_elf.rs @@ -28,7 +28,7 @@ pub fn target() -> Target { code_model: Some(CodeModel::Medium), emit_debug_gdb_scripts: false, eh_frame_header: false, - supported_sanitizers: SanitizerSet::KERNELADDRESS, + supported_sanitizers: SanitizerSet::KERNELADDRESS | SanitizerSet::SHADOWCALLSTACK, ..Default::default() }, } diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs index fa3f1eff45781..b7444df04cd1f 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_none_elf.rs @@ -27,7 +27,7 @@ pub fn target() -> Target { code_model: Some(CodeModel::Medium), emit_debug_gdb_scripts: false, eh_frame_header: false, - supported_sanitizers: SanitizerSet::KERNELADDRESS, + supported_sanitizers: SanitizerSet::KERNELADDRESS | SanitizerSet::SHADOWCALLSTACK, ..Default::default() }, } diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index edc63a25ac1be..31c2e922f79c4 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -776,21 +776,42 @@ See the [Clang SafeStack documentation][clang-safestack] for more details. # ShadowCallStack ShadowCallStack provides backward edge control flow protection by storing a function's return address in a separately allocated 'shadow call stack' and loading the return address from that shadow call stack. - -ShadowCallStack requires a platform ABI which reserves `x18` as the instrumentation makes use of this register. +To that end, implementation of this sanitizer requires reservation of one of the registers on the target platform. +Software support from the operating system and runtime may be required depending on the target platform which is detailed in the remaining section. +See the [Clang ShadowCallStack documentation][clang-scs] for more details. ShadowCallStack can be enabled with `-Zsanitizer=shadow-call-stack` option and is supported on the following targets: -* `aarch64-linux-android` +## AArch64 family -A runtime must be provided by the application or operating system. +ShadowCallStack requires on this platform ABI reservation of the register `x18` as the instrumentation makes use of this register. +When `x18` is not reserved on the target AArch64 platform and is availabe as a scratch register, enabling ShadowCallStack leds to undefined behaviour. +In other words, code that is calling into or called by functions instrumented with ShadowCallStack must reserve the `x18` register or preserve its value. -See the [Clang ShadowCallStack documentation][clang-scs] for more details. +### `aarch64-linux-android` -* `aarch64-unknown-none` +This target already reserves the `x18` register. +A runtime must be provided by the application or operating system. +If `bionic` is used on this target, the software support is provided. +Otherwise, a runtime needs to prepare a memory region and points `x18` to the region which serves as the shadow call stack. + +### `aarch64-unknown-none` In addition to support from a runtime by the application or operating system, the `-Zfixed-x18` flag is also mandatory. +## RISC-V 64 family + +ShadowCallStack uses either the `gp` register for software shadow stack, also known as `x3`, or the `ssp` register if [`Zicfiss`][riscv-zicfiss] extension is available. +`gp`/`x3` is currently always reserved and available for ShadowCallStack instrumentation, and `ssp` in case of `Zicfiss` is only accessible through its dedicated shadow stack instructions. + +Support from the runtime and operating system is required when `gp`/`x3` is used for software shadow stack. +A runtime must prepare a memory region and point `gp`/`x3` to the region before executing the code. + +The following targets support ShadowCallStack. + +* `riscv64imac-unknown-none-elf` +* `riscv64gc-unknown-none-elf` + # ThreadSanitizer ThreadSanitizer is a data race detection tool. It is supported on the following @@ -912,3 +933,4 @@ Sanitizers produce symbolized stacktraces when llvm-symbolizer binary is in `PAT [clang-tsan]: https://clang.llvm.org/docs/ThreadSanitizer.html [linux-kasan]: https://www.kernel.org/doc/html/latest/dev-tools/kasan.html [llvm-memtag]: https://llvm.org/docs/MemTagSanitizer.html +[riscv-zicfiss]: https://github.com/riscv/riscv-cfi/blob/3f8e450c481ac303bd5643444f7a89672f24476e/src/cfi_backward.adoc