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