]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/asan/asan_errors.cc
Merge compiler-rt trunk r291476.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / asan / asan_errors.cc
1 //===-- asan_errors.cc ------------------------------------------*- 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 implementation for error structures.
13 //===----------------------------------------------------------------------===//
14
15 #include "asan_errors.h"
16 #include <signal.h>
17 #include "asan_descriptions.h"
18 #include "asan_mapping.h"
19 #include "asan_report.h"
20 #include "asan_stack.h"
21 #include "sanitizer_common/sanitizer_stackdepot.h"
22
23 namespace __asan {
24
25 void ErrorStackOverflow::Print() {
26   Decorator d;
27   Printf("%s", d.Warning());
28   Report(
29       "ERROR: AddressSanitizer: %s on address %p"
30       " (pc %p bp %p sp %p T%d)\n", scariness.GetDescription(),
31       (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
32   Printf("%s", d.EndWarning());
33   scariness.Print();
34   BufferedStackTrace stack;
35   GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
36                                   common_flags()->fast_unwind_on_fatal);
37   stack.Print();
38   ReportErrorSummary(scariness.GetDescription(), &stack);
39 }
40
41 static void MaybeDumpInstructionBytes(uptr pc) {
42   if (!flags()->dump_instruction_bytes || (pc < GetPageSizeCached())) return;
43   InternalScopedString str(1024);
44   str.append("First 16 instruction bytes at pc: ");
45   if (IsAccessibleMemoryRange(pc, 16)) {
46     for (int i = 0; i < 16; ++i) {
47       PrintMemoryByte(&str, "", ((u8 *)pc)[i], /*in_shadow*/ false, " ");
48     }
49     str.append("\n");
50   } else {
51     str.append("unaccessible\n");
52   }
53   Report("%s", str.data());
54 }
55
56 static void MaybeDumpRegisters(void *context) {
57   if (!flags()->dump_registers) return;
58   SignalContext::DumpAllRegisters(context);
59 }
60
61 void ErrorDeadlySignal::Print() {
62   Decorator d;
63   Printf("%s", d.Warning());
64   const char *description = DescribeSignalOrException(signo);
65   Report(
66       "ERROR: AddressSanitizer: %s on unknown address %p (pc %p bp %p sp %p "
67       "T%d)\n",
68       description, (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
69   Printf("%s", d.EndWarning());
70   if (pc < GetPageSizeCached()) Report("Hint: pc points to the zero page.\n");
71   if (is_memory_access) {
72     const char *access_type =
73         write_flag == SignalContext::WRITE
74             ? "WRITE"
75             : (write_flag == SignalContext::READ ? "READ" : "UNKNOWN");
76     Report("The signal is caused by a %s memory access.\n", access_type);
77     if (addr < GetPageSizeCached())
78       Report("Hint: address points to the zero page.\n");
79   }
80   scariness.Print();
81   BufferedStackTrace stack;
82   GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
83                                   common_flags()->fast_unwind_on_fatal);
84   stack.Print();
85   MaybeDumpInstructionBytes(pc);
86   MaybeDumpRegisters(context);
87   Printf("AddressSanitizer can not provide additional info.\n");
88   ReportErrorSummary(description, &stack);
89 }
90
91 void ErrorDoubleFree::Print() {
92   Decorator d;
93   Printf("%s", d.Warning());
94   char tname[128];
95   Report(
96       "ERROR: AddressSanitizer: attempting %s on %p in "
97       "thread T%d%s:\n",
98       scariness.GetDescription(), addr_description.addr, tid,
99       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
100   Printf("%s", d.EndWarning());
101   scariness.Print();
102   GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
103                         second_free_stack->top_frame_bp);
104   stack.Print();
105   addr_description.Print();
106   ReportErrorSummary(scariness.GetDescription(), &stack);
107 }
108
109 void ErrorNewDeleteSizeMismatch::Print() {
110   Decorator d;
111   Printf("%s", d.Warning());
112   char tname[128];
113   Report(
114       "ERROR: AddressSanitizer: %s on %p in thread "
115       "T%d%s:\n",
116       scariness.GetDescription(), addr_description.addr, tid,
117       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
118   Printf("%s  object passed to delete has wrong type:\n", d.EndWarning());
119   Printf(
120       "  size of the allocated type:   %zd bytes;\n"
121       "  size of the deallocated type: %zd bytes.\n",
122       addr_description.chunk_access.chunk_size, delete_size);
123   CHECK_GT(free_stack->size, 0);
124   scariness.Print();
125   GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
126   stack.Print();
127   addr_description.Print();
128   ReportErrorSummary(scariness.GetDescription(), &stack);
129   Report(
130       "HINT: if you don't care about these errors you may set "
131       "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
132 }
133
134 void ErrorFreeNotMalloced::Print() {
135   Decorator d;
136   Printf("%s", d.Warning());
137   char tname[128];
138   Report(
139       "ERROR: AddressSanitizer: attempting free on address "
140       "which was not malloc()-ed: %p in thread T%d%s\n",
141       addr_description.Address(), tid,
142       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
143   Printf("%s", d.EndWarning());
144   CHECK_GT(free_stack->size, 0);
145   scariness.Print();
146   GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
147   stack.Print();
148   addr_description.Print();
149   ReportErrorSummary(scariness.GetDescription(), &stack);
150 }
151
152 void ErrorAllocTypeMismatch::Print() {
153   static const char *alloc_names[] = {"INVALID", "malloc", "operator new",
154                                       "operator new []"};
155   static const char *dealloc_names[] = {"INVALID", "free", "operator delete",
156                                         "operator delete []"};
157   CHECK_NE(alloc_type, dealloc_type);
158   Decorator d;
159   Printf("%s", d.Warning());
160   Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n",
161          scariness.GetDescription(),
162          alloc_names[alloc_type], dealloc_names[dealloc_type],
163          addr_description.addr);
164   Printf("%s", d.EndWarning());
165   CHECK_GT(dealloc_stack->size, 0);
166   scariness.Print();
167   GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
168   stack.Print();
169   addr_description.Print();
170   ReportErrorSummary(scariness.GetDescription(), &stack);
171   Report(
172       "HINT: if you don't care about these errors you may set "
173       "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
174 }
175
176 void ErrorMallocUsableSizeNotOwned::Print() {
177   Decorator d;
178   Printf("%s", d.Warning());
179   Report(
180       "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "
181       "pointer which is not owned: %p\n",
182       addr_description.Address());
183   Printf("%s", d.EndWarning());
184   stack->Print();
185   addr_description.Print();
186   ReportErrorSummary(scariness.GetDescription(), stack);
187 }
188
189 void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
190   Decorator d;
191   Printf("%s", d.Warning());
192   Report(
193       "ERROR: AddressSanitizer: attempting to call "
194       "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",
195       addr_description.Address());
196   Printf("%s", d.EndWarning());
197   stack->Print();
198   addr_description.Print();
199   ReportErrorSummary(scariness.GetDescription(), stack);
200 }
201
202 void ErrorStringFunctionMemoryRangesOverlap::Print() {
203   Decorator d;
204   char bug_type[100];
205   internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
206   Printf("%s", d.Warning());
207   Report(
208       "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) "
209       "overlap\n",
210       bug_type, addr1_description.Address(),
211       addr1_description.Address() + length1, addr2_description.Address(),
212       addr2_description.Address() + length2);
213   Printf("%s", d.EndWarning());
214   scariness.Print();
215   stack->Print();
216   addr1_description.Print();
217   addr2_description.Print();
218   ReportErrorSummary(bug_type, stack);
219 }
220
221 void ErrorStringFunctionSizeOverflow::Print() {
222   Decorator d;
223   Printf("%s", d.Warning());
224   Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",
225          scariness.GetDescription(), size);
226   Printf("%s", d.EndWarning());
227   scariness.Print();
228   stack->Print();
229   addr_description.Print();
230   ReportErrorSummary(scariness.GetDescription(), stack);
231 }
232
233 void ErrorBadParamsToAnnotateContiguousContainer::Print() {
234   Report(
235       "ERROR: AddressSanitizer: bad parameters to "
236       "__sanitizer_annotate_contiguous_container:\n"
237       "      beg     : %p\n"
238       "      end     : %p\n"
239       "      old_mid : %p\n"
240       "      new_mid : %p\n",
241       beg, end, old_mid, new_mid);
242   uptr granularity = SHADOW_GRANULARITY;
243   if (!IsAligned(beg, granularity))
244     Report("ERROR: beg is not aligned by %d\n", granularity);
245   stack->Print();
246   ReportErrorSummary(scariness.GetDescription(), stack);
247 }
248
249 void ErrorODRViolation::Print() {
250   Decorator d;
251   Printf("%s", d.Warning());
252   Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
253          global1.beg);
254   Printf("%s", d.EndWarning());
255   InternalScopedString g1_loc(256), g2_loc(256);
256   PrintGlobalLocation(&g1_loc, global1);
257   PrintGlobalLocation(&g2_loc, global2);
258   Printf("  [1] size=%zd '%s' %s\n", global1.size,
259          MaybeDemangleGlobalName(global1.name), g1_loc.data());
260   Printf("  [2] size=%zd '%s' %s\n", global2.size,
261          MaybeDemangleGlobalName(global2.name), g2_loc.data());
262   if (stack_id1 && stack_id2) {
263     Printf("These globals were registered at these points:\n");
264     Printf("  [1]:\n");
265     StackDepotGet(stack_id1).Print();
266     Printf("  [2]:\n");
267     StackDepotGet(stack_id2).Print();
268   }
269   Report(
270       "HINT: if you don't care about these errors you may set "
271       "ASAN_OPTIONS=detect_odr_violation=0\n");
272   InternalScopedString error_msg(256);
273   error_msg.append("%s: global '%s' at %s", scariness.GetDescription(),
274                    MaybeDemangleGlobalName(global1.name), g1_loc.data());
275   ReportErrorSummary(error_msg.data());
276 }
277
278 void ErrorInvalidPointerPair::Print() {
279   Decorator d;
280   Printf("%s", d.Warning());
281   Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(),
282          addr1_description.Address(), addr2_description.Address());
283   Printf("%s", d.EndWarning());
284   GET_STACK_TRACE_FATAL(pc, bp);
285   stack.Print();
286   addr1_description.Print();
287   addr2_description.Print();
288   ReportErrorSummary(scariness.GetDescription(), &stack);
289 }
290
291 static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
292   return s[-1] > 127 && s[1] > 127;
293 }
294
295 ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
296                            bool is_write_, uptr access_size_)
297     : ErrorBase(tid),
298       addr_description(addr, access_size_, /*shouldLockThreadRegistry=*/false),
299       pc(pc_),
300       bp(bp_),
301       sp(sp_),
302       access_size(access_size_),
303       is_write(is_write_),
304       shadow_val(0) {
305   scariness.Clear();
306   if (access_size) {
307     if (access_size <= 9) {
308       char desr[] = "?-byte";
309       desr[0] = '0' + access_size;
310       scariness.Scare(access_size + access_size / 2, desr);
311     } else if (access_size >= 10) {
312       scariness.Scare(15, "multi-byte");
313     }
314     is_write ? scariness.Scare(20, "write") : scariness.Scare(1, "read");
315
316     // Determine the error type.
317     bug_descr = "unknown-crash";
318     if (AddrIsInMem(addr)) {
319       u8 *shadow_addr = (u8 *)MemToShadow(addr);
320       // If we are accessing 16 bytes, look at the second shadow byte.
321       if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) shadow_addr++;
322       // If we are in the partial right redzone, look at the next shadow byte.
323       if (*shadow_addr > 0 && *shadow_addr < 128) shadow_addr++;
324       bool far_from_bounds = false;
325       shadow_val = *shadow_addr;
326       int bug_type_score = 0;
327       // For use-after-frees reads are almost as bad as writes.
328       int read_after_free_bonus = 0;
329       switch (shadow_val) {
330         case kAsanHeapLeftRedzoneMagic:
331         case kAsanArrayCookieMagic:
332           bug_descr = "heap-buffer-overflow";
333           bug_type_score = 10;
334           far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
335           break;
336         case kAsanHeapFreeMagic:
337           bug_descr = "heap-use-after-free";
338           bug_type_score = 20;
339           if (!is_write) read_after_free_bonus = 18;
340           break;
341         case kAsanStackLeftRedzoneMagic:
342           bug_descr = "stack-buffer-underflow";
343           bug_type_score = 25;
344           far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
345           break;
346         case kAsanInitializationOrderMagic:
347           bug_descr = "initialization-order-fiasco";
348           bug_type_score = 1;
349           break;
350         case kAsanStackMidRedzoneMagic:
351         case kAsanStackRightRedzoneMagic:
352           bug_descr = "stack-buffer-overflow";
353           bug_type_score = 25;
354           far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
355           break;
356         case kAsanStackAfterReturnMagic:
357           bug_descr = "stack-use-after-return";
358           bug_type_score = 30;
359           if (!is_write) read_after_free_bonus = 18;
360           break;
361         case kAsanUserPoisonedMemoryMagic:
362           bug_descr = "use-after-poison";
363           bug_type_score = 20;
364           break;
365         case kAsanContiguousContainerOOBMagic:
366           bug_descr = "container-overflow";
367           bug_type_score = 10;
368           break;
369         case kAsanStackUseAfterScopeMagic:
370           bug_descr = "stack-use-after-scope";
371           bug_type_score = 10;
372           break;
373         case kAsanGlobalRedzoneMagic:
374           bug_descr = "global-buffer-overflow";
375           bug_type_score = 10;
376           far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
377           break;
378         case kAsanIntraObjectRedzone:
379           bug_descr = "intra-object-overflow";
380           bug_type_score = 10;
381           break;
382         case kAsanAllocaLeftMagic:
383         case kAsanAllocaRightMagic:
384           bug_descr = "dynamic-stack-buffer-overflow";
385           bug_type_score = 25;
386           far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
387           break;
388       }
389       scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);
390       if (far_from_bounds) scariness.Scare(10, "far-from-bounds");
391     }
392   }
393 }
394
395 static void PrintContainerOverflowHint() {
396   Printf("HINT: if you don't care about these errors you may set "
397          "ASAN_OPTIONS=detect_container_overflow=0.\n"
398          "If you suspect a false positive see also: "
399          "https://github.com/google/sanitizers/wiki/"
400          "AddressSanitizerContainerOverflow.\n");
401 }
402
403 static void PrintShadowByte(InternalScopedString *str, const char *before,
404     u8 byte, const char *after = "\n") {
405   PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);
406 }
407
408 static void PrintLegend(InternalScopedString *str) {
409   str->append(
410       "Shadow byte legend (one shadow byte represents %d "
411       "application bytes):\n",
412       (int)SHADOW_GRANULARITY);
413   PrintShadowByte(str, "  Addressable:           ", 0);
414   str->append("  Partially addressable: ");
415   for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte(str, "", i, " ");
416   str->append("\n");
417   PrintShadowByte(str, "  Heap left redzone:       ",
418                   kAsanHeapLeftRedzoneMagic);
419   PrintShadowByte(str, "  Freed heap region:       ", kAsanHeapFreeMagic);
420   PrintShadowByte(str, "  Stack left redzone:      ",
421                   kAsanStackLeftRedzoneMagic);
422   PrintShadowByte(str, "  Stack mid redzone:       ",
423                   kAsanStackMidRedzoneMagic);
424   PrintShadowByte(str, "  Stack right redzone:     ",
425                   kAsanStackRightRedzoneMagic);
426   PrintShadowByte(str, "  Stack after return:      ",
427                   kAsanStackAfterReturnMagic);
428   PrintShadowByte(str, "  Stack use after scope:   ",
429                   kAsanStackUseAfterScopeMagic);
430   PrintShadowByte(str, "  Global redzone:          ", kAsanGlobalRedzoneMagic);
431   PrintShadowByte(str, "  Global init order:       ",
432                   kAsanInitializationOrderMagic);
433   PrintShadowByte(str, "  Poisoned by user:        ",
434                   kAsanUserPoisonedMemoryMagic);
435   PrintShadowByte(str, "  Container overflow:      ",
436                   kAsanContiguousContainerOOBMagic);
437   PrintShadowByte(str, "  Array cookie:            ",
438                   kAsanArrayCookieMagic);
439   PrintShadowByte(str, "  Intra object redzone:    ",
440                   kAsanIntraObjectRedzone);
441   PrintShadowByte(str, "  ASan internal:           ", kAsanInternalHeapMagic);
442   PrintShadowByte(str, "  Left alloca redzone:     ", kAsanAllocaLeftMagic);
443   PrintShadowByte(str, "  Right alloca redzone:    ", kAsanAllocaRightMagic);
444 }
445
446 static void PrintShadowBytes(InternalScopedString *str, const char *before,
447                              u8 *bytes, u8 *guilty, uptr n) {
448   Decorator d;
449   if (before) str->append("%s%p:", before, bytes);
450   for (uptr i = 0; i < n; i++) {
451     u8 *p = bytes + i;
452     const char *before =
453         p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " ";
454     const char *after = p == guilty ? "]" : "";
455     PrintShadowByte(str, before, *p, after);
456   }
457   str->append("\n");
458 }
459
460 static void PrintShadowMemoryForAddress(uptr addr) {
461   if (!AddrIsInMem(addr)) return;
462   uptr shadow_addr = MemToShadow(addr);
463   const uptr n_bytes_per_row = 16;
464   uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);
465   InternalScopedString str(4096 * 8);
466   str.append("Shadow bytes around the buggy address:\n");
467   for (int i = -5; i <= 5; i++) {
468     const char *prefix = (i == 0) ? "=>" : "  ";
469     PrintShadowBytes(&str, prefix, (u8 *)(aligned_shadow + i * n_bytes_per_row),
470                      (u8 *)shadow_addr, n_bytes_per_row);
471   }
472   if (flags()->print_legend) PrintLegend(&str);
473   Printf("%s", str.data());
474 }
475
476 void ErrorGeneric::Print() {
477   Decorator d;
478   Printf("%s", d.Warning());
479   uptr addr = addr_description.Address();
480   Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n",
481          bug_descr, (void *)addr, pc, bp, sp);
482   Printf("%s", d.EndWarning());
483
484   char tname[128];
485   Printf("%s%s of size %zu at %p thread T%d%s%s\n", d.Access(),
486          access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,
487          (void *)addr, tid,
488          ThreadNameWithParenthesis(tid, tname, sizeof(tname)), d.EndAccess());
489
490   scariness.Print();
491   GET_STACK_TRACE_FATAL(pc, bp);
492   stack.Print();
493
494   // Pass bug_descr because we have a special case for
495   // initialization-order-fiasco
496   addr_description.Print(bug_descr);
497   if (shadow_val == kAsanContiguousContainerOOBMagic)
498     PrintContainerOverflowHint();
499   ReportErrorSummary(bug_descr, &stack);
500   PrintShadowMemoryForAddress(addr);
501 }
502
503 }  // namespace __asan