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 // 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(void);
105 size_t __scudo_get_stack_depot_size(void);
106 
107 const char *__scudo_get_region_info_addr(void);
108 size_t __scudo_get_region_info_size(void);
109 
110 const char *__scudo_get_ring_buffer_addr(void);
111 size_t __scudo_get_ring_buffer_size(void);
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 #ifndef M_PURGE_ALL
122 #define M_PURGE_ALL -104
123 #endif
124 
125 // Tune the allocator's choice of memory tags to make it more likely that
126 // a certain class of memory errors will be detected. The value argument should
127 // be one of the M_MEMTAG_TUNING_* constants below.
128 #ifndef M_MEMTAG_TUNING
129 #define M_MEMTAG_TUNING -102
130 #endif
131 
132 // Per-thread memory initialization tuning. The value argument should be one of:
133 // 1: Disable automatic heap initialization and, where possible, memory tagging,
134 //    on this thread.
135 // 0: Normal behavior.
136 #ifndef M_THREAD_DISABLE_MEM_INIT
137 #define M_THREAD_DISABLE_MEM_INIT -103
138 #endif
139 
140 #ifndef M_CACHE_COUNT_MAX
141 #define M_CACHE_COUNT_MAX -200
142 #endif
143 
144 #ifndef M_CACHE_SIZE_MAX
145 #define M_CACHE_SIZE_MAX -201
146 #endif
147 
148 #ifndef M_TSDS_COUNT_MAX
149 #define M_TSDS_COUNT_MAX -202
150 #endif
151 
152 // Tune for buffer overflows.
153 #ifndef M_MEMTAG_TUNING_BUFFER_OVERFLOW
154 #define M_MEMTAG_TUNING_BUFFER_OVERFLOW 0
155 #endif
156 
157 // Tune for use-after-free.
158 #ifndef M_MEMTAG_TUNING_UAF
159 #define M_MEMTAG_TUNING_UAF 1
160 #endif
161 
162 // Print internal stats to the log.
163 #ifndef M_LOG_STATS
164 #define M_LOG_STATS -205
165 #endif
166 
167 } // extern "C"
168 
169 #endif // SCUDO_INTERFACE_H_
170