1 //===-- scudo/interface.h ---------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef SCUDO_INTERFACE_H_ 10 #define SCUDO_INTERFACE_H_ 11 12 #include <stddef.h> 13 #include <stdint.h> 14 15 extern "C" { 16 17 __attribute__((weak)) const char *__scudo_default_options(void); 18 19 // Post-allocation & pre-deallocation hooks. 20 __attribute__((weak)) void __scudo_allocate_hook(void *ptr, size_t size); 21 __attribute__((weak)) void __scudo_deallocate_hook(void *ptr); 22 23 // `realloc` involves both deallocation and allocation but they are not reported 24 // atomically. In one specific case which may keep taking a snapshot right in 25 // the middle of `realloc` reporting the deallocation and allocation, it may 26 // confuse the user by missing memory from `realloc`. To alleviate that case, 27 // define the two `realloc` hooks to get the knowledge of the bundled hook 28 // calls. These hooks are optional and should only be used when a hooks user 29 // wants to track reallocs more closely. 30 // 31 // See more details in the comment of `realloc` in wrapper_c.inc. 32 __attribute__((weak)) void 33 __scudo_realloc_allocate_hook(void *old_ptr, void *new_ptr, size_t size); 34 __attribute__((weak)) void __scudo_realloc_deallocate_hook(void *old_ptr); 35 36 void __scudo_print_stats(void); 37 38 typedef void (*iterate_callback)(uintptr_t base, size_t size, void *arg); 39 40 // Determine the likely cause of a tag check fault or other memory protection 41 // error on a system with memory tagging support. The results are returned via 42 // the error_info data structure. Up to three possible causes are returned in 43 // the reports array, in decreasing order of probability. The remaining elements 44 // of reports are zero-initialized. 45 // 46 // This function may be called from a different process from the one that 47 // crashed. In this case, various data structures must be copied from the 48 // crashing process to the process that analyzes the crash. 49 // 50 // This interface is not guaranteed to be stable and may change at any time. 51 // Furthermore, the version of scudo in the crashing process must be the same as 52 // the version in the process that analyzes the crash. 53 // 54 // fault_addr is the fault address. On aarch64 this is available in the system 55 // register FAR_ELx, or siginfo.si_addr in Linux 5.11 or above. This address 56 // must include the pointer tag; this is available if SA_EXPOSE_TAGBITS was set 57 // in sigaction.sa_flags when the signal handler was registered. Note that the 58 // kernel strips the tag from the field sigcontext.fault_address, so this 59 // address is not suitable to be passed as fault_addr. 60 // 61 // stack_depot is a pointer to the stack depot data structure, which may be 62 // obtained by calling the function __scudo_get_stack_depot_addr() in the 63 // crashing process. The size of the stack depot is available by calling the 64 // function __scudo_get_stack_depot_size(). 65 // 66 // region_info is a pointer to the region info data structure, which may be 67 // obtained by calling the function __scudo_get_region_info_addr() in the 68 // crashing process. The size of the region info is available by calling the 69 // function __scudo_get_region_info_size(). 70 // 71 // memory is a pointer to a region of memory surrounding the fault address. 72 // The more memory available via this pointer, the more likely it is that the 73 // function will be able to analyze a crash correctly. It is recommended to 74 // provide an amount of memory equal to 16 * the primary allocator's largest 75 // size class either side of the fault address. 76 // 77 // memory_tags is a pointer to an array of memory tags for the memory accessed 78 // via memory. Each byte of this array corresponds to a region of memory of size 79 // equal to the architecturally defined memory tag granule size (16 on aarch64). 80 // 81 // memory_addr is the start address of memory in the crashing process's address 82 // space. 83 // 84 // memory_size is the size of the memory region referred to by the memory 85 // pointer. 86 void __scudo_get_error_info(struct scudo_error_info *error_info, 87 uintptr_t fault_addr, const char *stack_depot, 88 size_t stack_depot_size, const char *region_info, 89 const char *ring_buffer, size_t ring_buffer_size, 90 const char *memory, const char *memory_tags, 91 uintptr_t memory_addr, size_t memory_size); 92 93 enum scudo_error_type { 94 UNKNOWN, 95 USE_AFTER_FREE, 96 BUFFER_OVERFLOW, 97 BUFFER_UNDERFLOW, 98 }; 99 100 struct scudo_error_report { 101 enum scudo_error_type error_type; 102 103 uintptr_t allocation_address; 104 uintptr_t allocation_size; 105 106 uint32_t allocation_tid; 107 uintptr_t allocation_trace[64]; 108 109 uint32_t deallocation_tid; 110 uintptr_t deallocation_trace[64]; 111 }; 112 113 struct scudo_error_info { 114 struct scudo_error_report reports[3]; 115 }; 116 117 const char *__scudo_get_stack_depot_addr(void); 118 size_t __scudo_get_stack_depot_size(void); 119 120 const char *__scudo_get_region_info_addr(void); 121 size_t __scudo_get_region_info_size(void); 122 123 const char *__scudo_get_ring_buffer_addr(void); 124 size_t __scudo_get_ring_buffer_size(void); 125 126 #ifndef M_DECAY_TIME 127 #define M_DECAY_TIME -100 128 #endif 129 130 #ifndef M_PURGE 131 #define M_PURGE -101 132 #endif 133 134 #ifndef M_PURGE_ALL 135 #define M_PURGE_ALL -104 136 #endif 137 138 // Tune the allocator's choice of memory tags to make it more likely that 139 // a certain class of memory errors will be detected. The value argument should 140 // be one of the M_MEMTAG_TUNING_* constants below. 141 #ifndef M_MEMTAG_TUNING 142 #define M_MEMTAG_TUNING -102 143 #endif 144 145 // Per-thread memory initialization tuning. The value argument should be one of: 146 // 1: Disable automatic heap initialization and, where possible, memory tagging, 147 // on this thread. 148 // 0: Normal behavior. 149 #ifndef M_THREAD_DISABLE_MEM_INIT 150 #define M_THREAD_DISABLE_MEM_INIT -103 151 #endif 152 153 #ifndef M_CACHE_COUNT_MAX 154 #define M_CACHE_COUNT_MAX -200 155 #endif 156 157 #ifndef M_CACHE_SIZE_MAX 158 #define M_CACHE_SIZE_MAX -201 159 #endif 160 161 #ifndef M_TSDS_COUNT_MAX 162 #define M_TSDS_COUNT_MAX -202 163 #endif 164 165 // Tune for buffer overflows. 166 #ifndef M_MEMTAG_TUNING_BUFFER_OVERFLOW 167 #define M_MEMTAG_TUNING_BUFFER_OVERFLOW 0 168 #endif 169 170 // Tune for use-after-free. 171 #ifndef M_MEMTAG_TUNING_UAF 172 #define M_MEMTAG_TUNING_UAF 1 173 #endif 174 175 // Print internal stats to the log. 176 #ifndef M_LOG_STATS 177 #define M_LOG_STATS -205 178 #endif 179 180 } // extern "C" 181 182 #endif // SCUDO_INTERFACE_H_ 183