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(); 18 19 // Post-allocation & pre-deallocation hooks. 20 // They must be thread-safe and not use heap related functions. 21 __attribute__((weak)) void __scudo_allocate_hook(void *ptr, size_t size); 22 __attribute__((weak)) void __scudo_deallocate_hook(void *ptr); 23 24 void __scudo_print_stats(void); 25 26 typedef void (*iterate_callback)(uintptr_t base, size_t size, void *arg); 27 28 // Determine the likely cause of a tag check fault or other memory protection 29 // error on a system with memory tagging support. The results are returned via 30 // the error_info data structure. Up to three possible causes are returned in 31 // the reports array, in decreasing order of probability. The remaining elements 32 // of reports are zero-initialized. 33 // 34 // This function may be called from a different process from the one that 35 // crashed. In this case, various data structures must be copied from the 36 // crashing process to the process that analyzes the crash. 37 // 38 // This interface is not guaranteed to be stable and may change at any time. 39 // Furthermore, the version of scudo in the crashing process must be the same as 40 // the version in the process that analyzes the crash. 41 // 42 // fault_addr is the fault address. On aarch64 this is available in the system 43 // register FAR_ELx, or siginfo.si_addr in Linux 5.11 or above. This address 44 // must include the pointer tag; this is available if SA_EXPOSE_TAGBITS was set 45 // in sigaction.sa_flags when the signal handler was registered. Note that the 46 // kernel strips the tag from the field sigcontext.fault_address, so this 47 // address is not suitable to be passed as fault_addr. 48 // 49 // stack_depot is a pointer to the stack depot data structure, which may be 50 // obtained by calling the function __scudo_get_stack_depot_addr() in the 51 // crashing process. The size of the stack depot is available by calling the 52 // function __scudo_get_stack_depot_size(). 53 // 54 // region_info is a pointer to the region info data structure, which may be 55 // obtained by calling the function __scudo_get_region_info_addr() in the 56 // crashing process. The size of the region info is available by calling the 57 // function __scudo_get_region_info_size(). 58 // 59 // memory is a pointer to a region of memory surrounding the fault address. 60 // The more memory available via this pointer, the more likely it is that the 61 // function will be able to analyze a crash correctly. It is recommended to 62 // provide an amount of memory equal to 16 * the primary allocator's largest 63 // size class either side of the fault address. 64 // 65 // memory_tags is a pointer to an array of memory tags for the memory accessed 66 // via memory. Each byte of this array corresponds to a region of memory of size 67 // equal to the architecturally defined memory tag granule size (16 on aarch64). 68 // 69 // memory_addr is the start address of memory in the crashing process's address 70 // space. 71 // 72 // memory_size is the size of the memory region referred to by the memory 73 // pointer. 74 void __scudo_get_error_info(struct scudo_error_info *error_info, 75 uintptr_t fault_addr, const char *stack_depot, 76 const char *region_info, const char *ring_buffer, 77 const char *memory, const char *memory_tags, 78 uintptr_t memory_addr, size_t memory_size); 79 80 enum scudo_error_type { 81 UNKNOWN, 82 USE_AFTER_FREE, 83 BUFFER_OVERFLOW, 84 BUFFER_UNDERFLOW, 85 }; 86 87 struct scudo_error_report { 88 enum scudo_error_type error_type; 89 90 uintptr_t allocation_address; 91 uintptr_t allocation_size; 92 93 uint32_t allocation_tid; 94 uintptr_t allocation_trace[64]; 95 96 uint32_t deallocation_tid; 97 uintptr_t deallocation_trace[64]; 98 }; 99 100 struct scudo_error_info { 101 struct scudo_error_report reports[3]; 102 }; 103 104 const char *__scudo_get_stack_depot_addr(); 105 size_t __scudo_get_stack_depot_size(); 106 107 const char *__scudo_get_region_info_addr(); 108 size_t __scudo_get_region_info_size(); 109 110 const char *__scudo_get_ring_buffer_addr(); 111 size_t __scudo_get_ring_buffer_size(); 112 113 #ifndef M_DECAY_TIME 114 #define M_DECAY_TIME -100 115 #endif 116 117 #ifndef M_PURGE 118 #define M_PURGE -101 119 #endif 120 121 // Tune the allocator's choice of memory tags to make it more likely that 122 // a certain class of memory errors will be detected. The value argument should 123 // be one of the M_MEMTAG_TUNING_* constants below. 124 #ifndef M_MEMTAG_TUNING 125 #define M_MEMTAG_TUNING -102 126 #endif 127 128 // Per-thread memory initialization tuning. The value argument should be one of: 129 // 1: Disable automatic heap initialization and, where possible, memory tagging, 130 // on this thread. 131 // 0: Normal behavior. 132 #ifndef M_THREAD_DISABLE_MEM_INIT 133 #define M_THREAD_DISABLE_MEM_INIT -103 134 #endif 135 136 #ifndef M_CACHE_COUNT_MAX 137 #define M_CACHE_COUNT_MAX -200 138 #endif 139 140 #ifndef M_CACHE_SIZE_MAX 141 #define M_CACHE_SIZE_MAX -201 142 #endif 143 144 #ifndef M_TSDS_COUNT_MAX 145 #define M_TSDS_COUNT_MAX -202 146 #endif 147 148 // Tune for buffer overflows. 149 #ifndef M_MEMTAG_TUNING_BUFFER_OVERFLOW 150 #define M_MEMTAG_TUNING_BUFFER_OVERFLOW 0 151 #endif 152 153 // Tune for use-after-free. 154 #ifndef M_MEMTAG_TUNING_UAF 155 #define M_MEMTAG_TUNING_UAF 1 156 #endif 157 158 } // extern "C" 159 160 #endif // SCUDO_INTERFACE_H_ 161