// Copyright 2017 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 "asan_impl.h" // In the ASan build, this file provides weak definitions for all the // same entry points that are defined by the ASan runtime library. // The definitions here are stubs that are used only during the // dynamic linker's startup phase before the ASan runtime shared // library has been loaded. These are required to satisfy the // references in libc's own code. // // LLVM provides no documentation on the ABI between the compiler and // the runtime. The set of function signatures here was culled from // the LLVM sources for the compiler instrumentation and the runtime // (see llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp and // compiler-rt/lib/asan/*). #if __has_feature(address_sanitizer) // This is referenced by generated code to decide whether to call // __asan_stack_malloc_* instead of doing normal stack allocation. // Never use stack malloc before the real runtime library is loaded. __WEAK const int __asan_option_detect_stack_use_after_return = 0; // This is the one set of things we define for real just as the // sanitizer runtime does. Generated code calls these. In practice, // almost certainly nothing in the the startup path needs them, but // defining them properly is barely more than defining trap stubs. #define ASAN_SET_SHADOW_XX(xx) \ __WEAK void __asan_set_shadow_##xx(uintptr_t addr, uintptr_t size) { \ __unsanitized_memset((void*)addr, 0x##xx, size); \ } ASAN_SET_SHADOW_XX(00) ASAN_SET_SHADOW_XX(f1) ASAN_SET_SHADOW_XX(f2) ASAN_SET_SHADOW_XX(f3) ASAN_SET_SHADOW_XX(f5) ASAN_SET_SHADOW_XX(f8) // Everything else is trap stubs. They should never be called. #define TRAP_STUB(decl) __WEAK decl { __builtin_trap(); } // These are only called when a bug is found. So unless there's // an actual bug in code that's on the dynamic linker startup path, // they'll never be called. // This is the same macro used in compiler-rt/lib/asan/asan_rtl.cc, // where it makes use of the is_write argument. The list of invocations // of this macro below is taken verbatim from that file. #define ASAN_REPORT_ERROR(type, is_write, size) \ TRAP_STUB(void __asan_report_##type##size(uintptr_t addr)) \ TRAP_STUB(void __asan_report_exp_##type##size(uintptr_t addr, \ uint32_t exp)) \ TRAP_STUB(void __asan_report_##type##size##_noabort(uintptr_t addr)) ASAN_REPORT_ERROR(load, false, 1) ASAN_REPORT_ERROR(load, false, 2) ASAN_REPORT_ERROR(load, false, 4) ASAN_REPORT_ERROR(load, false, 8) ASAN_REPORT_ERROR(load, false, 16) ASAN_REPORT_ERROR(store, true, 1) ASAN_REPORT_ERROR(store, true, 2) ASAN_REPORT_ERROR(store, true, 4) ASAN_REPORT_ERROR(store, true, 8) ASAN_REPORT_ERROR(store, true, 16) TRAP_STUB(void __asan_report_load_n(uintptr_t addr, size_t size)) TRAP_STUB(void __asan_report_load_n_noabort(uintptr_t addr, size_t size)) TRAP_STUB(void __asan_report_exp_load_n(uintptr_t addr, size_t size, uint32_t exp)) TRAP_STUB(void __asan_report_store_n(uintptr_t addr, size_t size)) TRAP_STUB(void __asan_report_store_n_noabort(uintptr_t addr, size_t size)) TRAP_STUB(void __asan_report_exp_store_n(uintptr_t addr, size_t size, uint32_t exp)) // These are sometimes called in normal operation. But they're never // called by any of the code on the startup path, so we can get away // with making them trap stubs. TRAP_STUB(void __asan_handle_no_return(void)) #define DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(class_id) \ TRAP_STUB(uintptr_t __asan_stack_malloc_##class_id(uintptr_t size)) \ TRAP_STUB(void __asan_stack_free_##class_id(uintptr_t ptr, size_t size)) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(0) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(1) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(2) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(3) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(4) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(5) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(6) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(7) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(8) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(9) DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(10) TRAP_STUB(void __asan_alloca_poison(uintptr_t addr, uintptr_t size)) TRAP_STUB(void __asan_allocas_unpoison(uintptr_t top, uintptr_t bottom)) // These are called to initialize the sanitizer runtime. These will // be needed for libc's and the dynamic linker's own code, but they // won't be called until after the sanitizer runtime is loaded. So // these trap stubs just satisfy the references in libc's own code // before other libraries are loaded, and ensure that they really // don't get called too early. TRAP_STUB(void __asan_init(void)) TRAP_STUB(void __asan_version_mismatch_check_v8(void)) TRAP_STUB(void __asan_register_globals(uintptr_t globals, size_t n)) TRAP_STUB(void __asan_unregister_globals(uintptr_t globals, size_t n)) TRAP_STUB(void __asan_register_elf_globals(uintptr_t flag, uintptr_t start, uintptr_t stop)) TRAP_STUB(void __asan_unregister_elf_globals(uintptr_t flag, uintptr_t start, uintptr_t stop)) #endif // __has_feature(address_sanitizer)