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