| // Copyright 2025 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/compiler/__stack_chk_fail.h" |
| |
| #include <lib/zircon-internal/unique-backtrace.h> |
| |
| #include "src/__support/common.h" |
| |
| extern "C" { |
| |
| // Calls to this function are generated by the compiler automatically in |
| // various modes controlled by `-fstack-protector` and other related switches. |
| // These are usually on by default, the various options controlling what kinds |
| // of functions will be "protected" by extra code in their frame setup logic. |
| // The Fuchsia Compiler ABI provides a pointer-sized "stack guard" value (via |
| // the thread pointer as specified in <zircon/tls.h>), which is randomized at |
| // process startup. The compiler reserves a slot at the edge of a "protected" |
| // function's stack frame, called the "stack canary". It emits extra code in |
| // the function prologue to copy the stack guard value provided by the ABI into |
| // the stack canary slot in the new call frame. Corresponding code in the |
| // function's epilogue then fetches the guard value via the ABI again and |
| // compares it to the stack canary. If they don't match, the epilogue calls |
| // __stack_chk_fail so the corrupted function will never return. This can be |
| // an important safety and security measure, because the return address may be |
| // stored on the stack nearby to the stack canary word--if the canary is |
| // corrupted, the return value may also be corrupted and perhaps exploited to |
| // hijack control flow. (This is not a direct risk when either safe-stack or |
| // shadow-call-stack is in use. When using safe-stack, the canary is on the |
| // unsafe stack while the return address is on the machine stack; when using |
| // shadow-call-stack, the canary is on the machine stack while the return |
| // address is on the shadow call stack. But other kinds of corruption can be |
| // dangerous and possibly exploited, so early detection here is still valued |
| // for safety and security.) |
| LLVM_LIBC_FUNCTION_ATTR [[noreturn]] void __stack_chk_fail() { |
| // If this is in a backtrace, it indicates that the calling function's stack |
| // frame was corrupted sometime between entering that function and returning |
| // from it. This can happen via a buffer overrun in that function itself, or |
| // in one of its previous callees; or via other kinds of memory corruption. |
| CRASH_WITH_UNIQUE_BACKTRACE(); |
| } |
| |
| } // extern "C" |