]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/asan/asan_errors.h
MFV r315290, r315291: 7303 dynamic metaslab selection
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / asan / asan_errors.h
1 //===-- asan_errors.h -------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of AddressSanitizer, an address sanity checker.
11 //
12 // ASan-private header for error structures.
13 //===----------------------------------------------------------------------===//
14 #ifndef ASAN_ERRORS_H
15 #define ASAN_ERRORS_H
16
17 #include "asan_descriptions.h"
18 #include "asan_scariness_score.h"
19 #include "sanitizer_common/sanitizer_common.h"
20
21 namespace __asan {
22
23 struct ErrorBase {
24   ErrorBase() = default;
25   explicit ErrorBase(u32 tid_) : tid(tid_) {}
26   ScarinessScoreBase scariness;
27   u32 tid;
28 };
29
30 struct ErrorStackOverflow : ErrorBase {
31   uptr addr, pc, bp, sp;
32   // ErrorStackOverflow never owns the context.
33   void *context;
34   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
35   // constructor
36   ErrorStackOverflow() = default;
37   ErrorStackOverflow(u32 tid, const SignalContext &sig)
38       : ErrorBase(tid),
39         addr(sig.addr),
40         pc(sig.pc),
41         bp(sig.bp),
42         sp(sig.sp),
43         context(sig.context) {
44     scariness.Clear();
45     scariness.Scare(10, "stack-overflow");
46   }
47   void Print();
48 };
49
50 struct ErrorDeadlySignal : ErrorBase {
51   uptr addr, pc, bp, sp;
52   // ErrorDeadlySignal never owns the context.
53   void *context;
54   int signo;
55   SignalContext::WriteFlag write_flag;
56   bool is_memory_access;
57   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
58   // constructor
59   ErrorDeadlySignal() = default;
60   ErrorDeadlySignal(u32 tid, const SignalContext &sig, int signo_)
61       : ErrorBase(tid),
62         addr(sig.addr),
63         pc(sig.pc),
64         bp(sig.bp),
65         sp(sig.sp),
66         context(sig.context),
67         signo(signo_),
68         write_flag(sig.write_flag),
69         is_memory_access(sig.is_memory_access) {
70     scariness.Clear();
71     if (is_memory_access) {
72       if (addr < GetPageSizeCached()) {
73         scariness.Scare(10, "null-deref");
74       } else if (addr == pc) {
75         scariness.Scare(60, "wild-jump");
76       } else if (write_flag == SignalContext::WRITE) {
77         scariness.Scare(30, "wild-addr-write");
78       } else if (write_flag == SignalContext::READ) {
79         scariness.Scare(20, "wild-addr-read");
80       } else {
81         scariness.Scare(25, "wild-addr");
82       }
83     } else {
84       scariness.Scare(10, "signal");
85     }
86   }
87   void Print();
88 };
89
90 struct ErrorDoubleFree : ErrorBase {
91   // ErrorDoubleFree doesn't own the stack trace.
92   const BufferedStackTrace *second_free_stack;
93   HeapAddressDescription addr_description;
94   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
95   // constructor
96   ErrorDoubleFree() = default;
97   ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr)
98       : ErrorBase(tid), second_free_stack(stack) {
99     CHECK_GT(second_free_stack->size, 0);
100     GetHeapAddressInformation(addr, 1, &addr_description);
101     scariness.Clear();
102     scariness.Scare(42, "double-free");
103   }
104   void Print();
105 };
106
107 struct ErrorNewDeleteSizeMismatch : ErrorBase {
108   // ErrorNewDeleteSizeMismatch doesn't own the stack trace.
109   const BufferedStackTrace *free_stack;
110   HeapAddressDescription addr_description;
111   uptr delete_size;
112   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
113   // constructor
114   ErrorNewDeleteSizeMismatch() = default;
115   ErrorNewDeleteSizeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
116                              uptr delete_size_)
117       : ErrorBase(tid), free_stack(stack), delete_size(delete_size_) {
118     GetHeapAddressInformation(addr, 1, &addr_description);
119     scariness.Clear();
120     scariness.Scare(10, "new-delete-type-mismatch");
121   }
122   void Print();
123 };
124
125 struct ErrorFreeNotMalloced : ErrorBase {
126   // ErrorFreeNotMalloced doesn't own the stack trace.
127   const BufferedStackTrace *free_stack;
128   AddressDescription addr_description;
129   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
130   // constructor
131   ErrorFreeNotMalloced() = default;
132   ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr)
133       : ErrorBase(tid),
134         free_stack(stack),
135         addr_description(addr, /*shouldLockThreadRegistry=*/false) {
136     scariness.Clear();
137     scariness.Scare(40, "bad-free");
138   }
139   void Print();
140 };
141
142 struct ErrorAllocTypeMismatch : ErrorBase {
143   // ErrorAllocTypeMismatch doesn't own the stack trace.
144   const BufferedStackTrace *dealloc_stack;
145   HeapAddressDescription addr_description;
146   AllocType alloc_type, dealloc_type;
147   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
148   // constructor
149   ErrorAllocTypeMismatch() = default;
150   ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
151                          AllocType alloc_type_, AllocType dealloc_type_)
152       : ErrorBase(tid),
153         dealloc_stack(stack),
154         alloc_type(alloc_type_),
155         dealloc_type(dealloc_type_) {
156     GetHeapAddressInformation(addr, 1, &addr_description);
157     scariness.Clear();
158     scariness.Scare(10, "alloc-dealloc-mismatch");
159   };
160   void Print();
161 };
162
163 struct ErrorMallocUsableSizeNotOwned : ErrorBase {
164   // ErrorMallocUsableSizeNotOwned doesn't own the stack trace.
165   const BufferedStackTrace *stack;
166   AddressDescription addr_description;
167   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
168   // constructor
169   ErrorMallocUsableSizeNotOwned() = default;
170   ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr)
171       : ErrorBase(tid),
172         stack(stack_),
173         addr_description(addr, /*shouldLockThreadRegistry=*/false) {
174     scariness.Clear();
175     scariness.Scare(10, "bad-malloc_usable_size");
176   }
177   void Print();
178 };
179
180 struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
181   // ErrorSanitizerGetAllocatedSizeNotOwned doesn't own the stack trace.
182   const BufferedStackTrace *stack;
183   AddressDescription addr_description;
184   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
185   // constructor
186   ErrorSanitizerGetAllocatedSizeNotOwned() = default;
187   ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_,
188                                          uptr addr)
189       : ErrorBase(tid),
190         stack(stack_),
191         addr_description(addr, /*shouldLockThreadRegistry=*/false) {
192     scariness.Clear();
193     scariness.Scare(10, "bad-__sanitizer_get_allocated_size");
194   }
195   void Print();
196 };
197
198 struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
199   // ErrorStringFunctionMemoryRangesOverlap doesn't own the stack trace.
200   const BufferedStackTrace *stack;
201   uptr length1, length2;
202   AddressDescription addr1_description;
203   AddressDescription addr2_description;
204   const char *function;
205   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
206   // constructor
207   ErrorStringFunctionMemoryRangesOverlap() = default;
208   ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
209                                          uptr addr1, uptr length1_, uptr addr2,
210                                          uptr length2_, const char *function_)
211       : ErrorBase(tid),
212         stack(stack_),
213         length1(length1_),
214         length2(length2_),
215         addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
216         addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
217         function(function_) {
218     char bug_type[100];
219     internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
220     scariness.Clear();
221     scariness.Scare(10, bug_type);
222   }
223   void Print();
224 };
225
226 struct ErrorStringFunctionSizeOverflow : ErrorBase {
227   // ErrorStringFunctionSizeOverflow doesn't own the stack trace.
228   const BufferedStackTrace *stack;
229   AddressDescription addr_description;
230   uptr size;
231   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
232   // constructor
233   ErrorStringFunctionSizeOverflow() = default;
234   ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
235                                   uptr addr, uptr size_)
236       : ErrorBase(tid),
237         stack(stack_),
238         addr_description(addr, /*shouldLockThreadRegistry=*/false),
239         size(size_) {
240     scariness.Clear();
241     scariness.Scare(10, "negative-size-param");
242   }
243   void Print();
244 };
245
246 struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
247   // ErrorBadParamsToAnnotateContiguousContainer doesn't own the stack trace.
248   const BufferedStackTrace *stack;
249   uptr beg, end, old_mid, new_mid;
250   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
251   // constructor
252   ErrorBadParamsToAnnotateContiguousContainer() = default;
253   // PS4: Do we want an AddressDescription for beg?
254   ErrorBadParamsToAnnotateContiguousContainer(u32 tid,
255                                               BufferedStackTrace *stack_,
256                                               uptr beg_, uptr end_,
257                                               uptr old_mid_, uptr new_mid_)
258       : ErrorBase(tid),
259         stack(stack_),
260         beg(beg_),
261         end(end_),
262         old_mid(old_mid_),
263         new_mid(new_mid_) {
264     scariness.Clear();
265     scariness.Scare(10, "bad-__sanitizer_annotate_contiguous_container");
266   }
267   void Print();
268 };
269
270 struct ErrorODRViolation : ErrorBase {
271   __asan_global global1, global2;
272   u32 stack_id1, stack_id2;
273   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
274   // constructor
275   ErrorODRViolation() = default;
276   ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_,
277                     const __asan_global *g2, u32 stack_id2_)
278       : ErrorBase(tid),
279         global1(*g1),
280         global2(*g2),
281         stack_id1(stack_id1_),
282         stack_id2(stack_id2_) {
283     scariness.Clear();
284     scariness.Scare(10, "odr-violation");
285   }
286   void Print();
287 };
288
289 struct ErrorInvalidPointerPair : ErrorBase {
290   uptr pc, bp, sp;
291   AddressDescription addr1_description;
292   AddressDescription addr2_description;
293   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
294   // constructor
295   ErrorInvalidPointerPair() = default;
296   ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1,
297                           uptr p2)
298       : ErrorBase(tid),
299         pc(pc_),
300         bp(bp_),
301         sp(sp_),
302         addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
303         addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false)  {
304     scariness.Clear();
305     scariness.Scare(10, "invalid-pointer-pair");
306   }
307   void Print();
308 };
309
310 struct ErrorGeneric : ErrorBase {
311   AddressDescription addr_description;
312   uptr pc, bp, sp;
313   uptr access_size;
314   const char *bug_descr;
315   bool is_write;
316   u8 shadow_val;
317   // VS2013 doesn't implement unrestricted unions, so we need a trivial default
318   // constructor
319   ErrorGeneric() = default;
320   ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_,
321                uptr access_size_);
322   void Print();
323 };
324
325 // clang-format off
326 #define ASAN_FOR_EACH_ERROR_KIND(macro)         \
327   macro(StackOverflow)                          \
328   macro(DeadlySignal)                           \
329   macro(DoubleFree)                             \
330   macro(NewDeleteSizeMismatch)                  \
331   macro(FreeNotMalloced)                        \
332   macro(AllocTypeMismatch)                      \
333   macro(MallocUsableSizeNotOwned)               \
334   macro(SanitizerGetAllocatedSizeNotOwned)      \
335   macro(StringFunctionMemoryRangesOverlap)      \
336   macro(StringFunctionSizeOverflow)             \
337   macro(BadParamsToAnnotateContiguousContainer) \
338   macro(ODRViolation)                           \
339   macro(InvalidPointerPair)                     \
340   macro(Generic)
341 // clang-format on
342
343 #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
344 #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
345 #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
346   ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
347 #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
348   case kErrorKind##name:                   \
349     return name.Print();
350
351 enum ErrorKind {
352   kErrorKindInvalid = 0,
353   ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND)
354 };
355
356 struct ErrorDescription {
357   ErrorKind kind;
358   // We're using a tagged union because it allows us to have a trivially
359   // copiable type and use the same structures as the public interface.
360   //
361   // We can add a wrapper around it to make it "more c++-like", but that would
362   // add a lot of code and the benefit wouldn't be that big.
363   union {
364     ErrorBase Base;
365     ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
366   };
367
368   ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
369   ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR)
370
371   bool IsValid() { return kind != kErrorKindInvalid; }
372   void Print() {
373     switch (kind) {
374       ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT)
375       case kErrorKindInvalid:
376         CHECK(0);
377     }
378     CHECK(0);
379   }
380 };
381
382 #undef ASAN_FOR_EACH_ERROR_KIND
383 #undef ASAN_DEFINE_ERROR_KIND
384 #undef ASAN_ERROR_DESCRIPTION_MEMBER
385 #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
386 #undef ASAN_ERROR_DESCRIPTION_PRINT
387
388 }  // namespace __asan
389
390 #endif  // ASAN_ERRORS_H