1 //===-- dfsan.cpp ---------------------------------------------------------===// 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 // This file is a part of DataFlowSanitizer. 10 // 11 // DataFlowSanitizer runtime. This file defines the public interface to 12 // DataFlowSanitizer as well as the definition of certain runtime functions 13 // called automatically by the compiler (specifically the instrumentation pass 14 // in llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp). 15 // 16 // The public interface is defined in include/sanitizer/dfsan_interface.h whose 17 // functions are prefixed dfsan_ while the compiler interface functions are 18 // prefixed __dfsan_. 19 //===----------------------------------------------------------------------===// 20 21 #include "dfsan/dfsan.h" 22 23 #include "dfsan/dfsan_chained_origin_depot.h" 24 #include "dfsan/dfsan_flags.h" 25 #include "dfsan/dfsan_origin.h" 26 #include "dfsan/dfsan_thread.h" 27 #include "sanitizer_common/sanitizer_atomic.h" 28 #include "sanitizer_common/sanitizer_common.h" 29 #include "sanitizer_common/sanitizer_file.h" 30 #include "sanitizer_common/sanitizer_flag_parser.h" 31 #include "sanitizer_common/sanitizer_flags.h" 32 #include "sanitizer_common/sanitizer_internal_defs.h" 33 #include "sanitizer_common/sanitizer_libc.h" 34 #include "sanitizer_common/sanitizer_report_decorator.h" 35 #include "sanitizer_common/sanitizer_stacktrace.h" 36 37 using namespace __dfsan; 38 39 Flags __dfsan::flags_data; 40 41 // The size of TLS variables. These constants must be kept in sync with the ones 42 // in DataFlowSanitizer.cpp. 43 static const int kDFsanArgTlsSize = 800; 44 static const int kDFsanRetvalTlsSize = 800; 45 static const int kDFsanArgOriginTlsSize = 800; 46 47 SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64 48 __dfsan_retval_tls[kDFsanRetvalTlsSize / sizeof(u64)]; 49 SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u32 __dfsan_retval_origin_tls; 50 SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64 51 __dfsan_arg_tls[kDFsanArgTlsSize / sizeof(u64)]; 52 SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u32 53 __dfsan_arg_origin_tls[kDFsanArgOriginTlsSize / sizeof(u32)]; 54 55 SANITIZER_INTERFACE_ATTRIBUTE uptr __dfsan_shadow_ptr_mask; 56 57 // Instrumented code may set this value in terms of -dfsan-track-origins. 58 // * undefined or 0: do not track origins. 59 // * 1: track origins at memory store operations. 60 // * 2: TODO: track origins at memory store operations and callsites. 61 extern "C" SANITIZER_WEAK_ATTRIBUTE const int __dfsan_track_origins; 62 63 int __dfsan_get_track_origins() { 64 return &__dfsan_track_origins ? __dfsan_track_origins : 0; 65 } 66 67 // On Linux/x86_64, memory is laid out as follows: 68 // 69 // +--------------------+ 0x800000000000 (top of memory) 70 // | application memory | 71 // +--------------------+ 0x700000008000 (kAppAddr) 72 // | | 73 // | unused | 74 // | | 75 // +--------------------+ 0x300000000000 (kUnusedAddr) 76 // | origin | 77 // +--------------------+ 0x200000008000 (kOriginAddr) 78 // | unused | 79 // +--------------------+ 0x200000000000 80 // | shadow memory | 81 // +--------------------+ 0x100000008000 (kShadowAddr) 82 // | unused | 83 // +--------------------+ 0x000000010000 84 // | reserved by kernel | 85 // +--------------------+ 0x000000000000 86 // 87 // To derive a shadow memory address from an application memory address, bits 88 // 45-46 are cleared to bring the address into the range 89 // [0x100000008000,0x200000000000). See the function shadow_for below. 90 // 91 // On Linux/MIPS64, memory is laid out as follows: 92 // 93 // +--------------------+ 0x10000000000 (top of memory) 94 // | application memory | 95 // +--------------------+ 0xF000008000 (kAppAddr) 96 // | | 97 // | unused | 98 // | | 99 // +--------------------+ 0x2000000000 (kUnusedAddr) 100 // | shadow memory | 101 // +--------------------+ 0x1000008000 (kShadowAddr) 102 // | unused | 103 // +--------------------+ 0x0000010000 104 // | reserved by kernel | 105 // +--------------------+ 0x0000000000 106 107 // On Linux/AArch64 (39-bit VMA), memory is laid out as follow: 108 // 109 // +--------------------+ 0x8000000000 (top of memory) 110 // | application memory | 111 // +--------------------+ 0x7000008000 (kAppAddr) 112 // | | 113 // | unused | 114 // | | 115 // +--------------------+ 0x1000000000 (kUnusedAddr) 116 // | shadow memory | 117 // +--------------------+ 0x0000010000 (kShadowAddr) 118 // | reserved by kernel | 119 // +--------------------+ 0x0000000000 120 121 // On Linux/AArch64 (42-bit VMA), memory is laid out as follow: 122 // 123 // +--------------------+ 0x40000000000 (top of memory) 124 // | application memory | 125 // +--------------------+ 0x3ff00008000 (kAppAddr) 126 // | | 127 // | unused | 128 // | | 129 // +--------------------+ 0x8000000000 (kUnusedAddr) 130 // | shadow memory | 131 // +--------------------+ 0x0000010000 (kShadowAddr) 132 // | reserved by kernel | 133 // +--------------------+ 0x0000000000 134 135 // On Linux/AArch64 (48-bit VMA), memory is laid out as follow: 136 // 137 // +--------------------+ 0x1000000000000 (top of memory) 138 // | application memory | 139 // +--------------------+ 0xffff00008000 (kAppAddr) 140 // | unused | 141 // +--------------------+ 0xaaaab0000000 (top of PIE address) 142 // | application PIE | 143 // +--------------------+ 0xaaaaa0000000 (top of PIE address) 144 // | | 145 // | unused | 146 // | | 147 // +--------------------+ 0x8000000000 (kUnusedAddr) 148 // | shadow memory | 149 // +--------------------+ 0x0000010000 (kShadowAddr) 150 // | reserved by kernel | 151 // +--------------------+ 0x0000000000 152 153 #ifdef DFSAN_RUNTIME_VMA 154 // Runtime detected VMA size. 155 int __dfsan::vmaSize; 156 #endif 157 158 extern "C" SANITIZER_INTERFACE_ATTRIBUTE 159 dfsan_label __dfsan_union_load(const dfsan_label *ls, uptr n) { 160 dfsan_label label = ls[0]; 161 for (uptr i = 1; i != n; ++i) 162 label |= ls[i]; 163 return label; 164 } 165 166 // Return the union of all the n labels from addr at the high 32 bit, and the 167 // origin of the first taint byte at the low 32 bit. 168 extern "C" SANITIZER_INTERFACE_ATTRIBUTE u64 169 __dfsan_load_label_and_origin(const void *addr, uptr n) { 170 dfsan_label label = 0; 171 u64 ret = 0; 172 uptr p = (uptr)addr; 173 dfsan_label *s = shadow_for((void *)p); 174 for (uptr i = 0; i < n; ++i) { 175 dfsan_label l = s[i]; 176 if (!l) 177 continue; 178 label |= l; 179 if (!ret) 180 ret = *(dfsan_origin *)origin_for((void *)(p + i)); 181 } 182 return ret | (u64)label << 32; 183 } 184 185 extern "C" SANITIZER_INTERFACE_ATTRIBUTE 186 void __dfsan_unimplemented(char *fname) { 187 if (flags().warn_unimplemented) 188 Report("WARNING: DataFlowSanitizer: call to uninstrumented function %s\n", 189 fname); 190 } 191 192 // Use '-mllvm -dfsan-debug-nonzero-labels' and break on this function 193 // to try to figure out where labels are being introduced in a nominally 194 // label-free program. 195 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_nonzero_label() { 196 if (flags().warn_nonzero_labels) 197 Report("WARNING: DataFlowSanitizer: saw nonzero label\n"); 198 } 199 200 // Indirect call to an uninstrumented vararg function. We don't have a way of 201 // handling these at the moment. 202 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void 203 __dfsan_vararg_wrapper(const char *fname) { 204 Report("FATAL: DataFlowSanitizer: unsupported indirect call to vararg " 205 "function %s\n", fname); 206 Die(); 207 } 208 209 // Resolves the union of two labels. 210 SANITIZER_INTERFACE_ATTRIBUTE dfsan_label 211 dfsan_union(dfsan_label l1, dfsan_label l2) { 212 return l1 | l2; 213 } 214 215 // Return the origin of the first taint byte in the size bytes from the address 216 // addr. 217 static dfsan_origin GetOriginIfTainted(uptr addr, uptr size) { 218 for (uptr i = 0; i < size; ++i, ++addr) { 219 dfsan_label *s = shadow_for((void *)addr); 220 if (!is_shadow_addr_valid((uptr)s)) { 221 // The current DFSan memory layout is not always correct. For example, 222 // addresses (0, 0x10000) are mapped to (0, 0x10000). Before fixing the 223 // issue, we ignore such addresses. 224 continue; 225 } 226 if (*s) 227 return *(dfsan_origin *)origin_for((void *)addr); 228 } 229 return 0; 230 } 231 232 // For platforms which support slow unwinder only, we need to restrict the store 233 // context size to 1, basically only storing the current pc, because the slow 234 // unwinder which is based on libunwind is not async signal safe and causes 235 // random freezes in forking applications as well as in signal handlers. 236 // DFSan supports only Linux. So we do not restrict the store context size. 237 #define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \ 238 BufferedStackTrace stack; \ 239 stack.Unwind(pc, bp, nullptr, true, flags().store_context_size); 240 241 #define PRINT_CALLER_STACK_TRACE \ 242 { \ 243 GET_CALLER_PC_BP_SP; \ 244 (void)sp; \ 245 GET_STORE_STACK_TRACE_PC_BP(pc, bp) \ 246 stack.Print(); \ 247 } 248 249 // Return a chain with the previous ID id and the current stack. 250 // from_init = true if this is the first chain of an origin tracking path. 251 static u32 ChainOrigin(u32 id, StackTrace *stack, bool from_init = false) { 252 // StackDepot is not async signal safe. Do not create new chains in a signal 253 // handler. 254 DFsanThread *t = GetCurrentThread(); 255 if (t && t->InSignalHandler()) 256 return id; 257 258 // As an optimization the origin of an application byte is updated only when 259 // its shadow is non-zero. Because we are only interested in the origins of 260 // taint labels, it does not matter what origin a zero label has. This reduces 261 // memory write cost. MSan does similar optimization. The following invariant 262 // may not hold because of some bugs. We check the invariant to help debug. 263 if (!from_init && id == 0 && flags().check_origin_invariant) { 264 Printf(" DFSan found invalid origin invariant\n"); 265 PRINT_CALLER_STACK_TRACE 266 } 267 268 Origin o = Origin::FromRawId(id); 269 stack->tag = StackTrace::TAG_UNKNOWN; 270 Origin chained = Origin::CreateChainedOrigin(o, stack); 271 return chained.raw_id(); 272 } 273 274 static const uptr kOriginAlign = sizeof(dfsan_origin); 275 static const uptr kOriginAlignMask = ~(kOriginAlign - 1UL); 276 277 static uptr AlignUp(uptr u) { 278 return (u + kOriginAlign - 1) & kOriginAlignMask; 279 } 280 281 static uptr AlignDown(uptr u) { return u & kOriginAlignMask; } 282 283 static void ChainAndWriteOriginIfTainted(uptr src, uptr size, uptr dst, 284 StackTrace *stack) { 285 dfsan_origin o = GetOriginIfTainted(src, size); 286 if (o) { 287 o = ChainOrigin(o, stack); 288 *(dfsan_origin *)origin_for((void *)dst) = o; 289 } 290 } 291 292 // Copy the origins of the size bytes from src to dst. The source and target 293 // memory ranges cannot be overlapped. This is used by memcpy. stack records the 294 // stack trace of the memcpy. When dst and src are not 4-byte aligned properly, 295 // origins at the unaligned address boundaries may be overwritten because four 296 // contiguous bytes share the same origin. 297 static void CopyOrigin(const void *dst, const void *src, uptr size, 298 StackTrace *stack) { 299 uptr d = (uptr)dst; 300 uptr beg = AlignDown(d); 301 // Copy left unaligned origin if that memory is tainted. 302 if (beg < d) { 303 ChainAndWriteOriginIfTainted((uptr)src, beg + kOriginAlign - d, beg, stack); 304 beg += kOriginAlign; 305 } 306 307 uptr end = AlignDown(d + size); 308 // If both ends fall into the same 4-byte slot, we are done. 309 if (end < beg) 310 return; 311 312 // Copy right unaligned origin if that memory is tainted. 313 if (end < d + size) 314 ChainAndWriteOriginIfTainted((uptr)src + (end - d), (d + size) - end, end, 315 stack); 316 317 if (beg >= end) 318 return; 319 320 // Align src up. 321 uptr s = AlignUp((uptr)src); 322 dfsan_origin *src_o = (dfsan_origin *)origin_for((void *)s); 323 u32 *src_s = (u32 *)shadow_for((void *)s); 324 dfsan_origin *src_end = (dfsan_origin *)origin_for((void *)(s + (end - beg))); 325 dfsan_origin *dst_o = (dfsan_origin *)origin_for((void *)beg); 326 dfsan_origin last_src_o = 0; 327 dfsan_origin last_dst_o = 0; 328 for (; src_o < src_end; ++src_o, ++src_s, ++dst_o) { 329 if (!*src_s) 330 continue; 331 if (*src_o != last_src_o) { 332 last_src_o = *src_o; 333 last_dst_o = ChainOrigin(last_src_o, stack); 334 } 335 *dst_o = last_dst_o; 336 } 337 } 338 339 // Copy the origins of the size bytes from src to dst. The source and target 340 // memory ranges may be overlapped. So the copy is done in a reverse order. 341 // This is used by memmove. stack records the stack trace of the memmove. 342 static void ReverseCopyOrigin(const void *dst, const void *src, uptr size, 343 StackTrace *stack) { 344 uptr d = (uptr)dst; 345 uptr end = AlignDown(d + size); 346 347 // Copy right unaligned origin if that memory is tainted. 348 if (end < d + size) 349 ChainAndWriteOriginIfTainted((uptr)src + (end - d), (d + size) - end, end, 350 stack); 351 352 uptr beg = AlignDown(d); 353 354 if (beg + kOriginAlign < end) { 355 // Align src up. 356 uptr s = AlignUp((uptr)src); 357 dfsan_origin *src = 358 (dfsan_origin *)origin_for((void *)(s + end - beg - kOriginAlign)); 359 u32 *src_s = (u32 *)shadow_for((void *)(s + end - beg - kOriginAlign)); 360 dfsan_origin *src_begin = (dfsan_origin *)origin_for((void *)s); 361 dfsan_origin *dst = 362 (dfsan_origin *)origin_for((void *)(end - kOriginAlign)); 363 dfsan_origin src_o = 0; 364 dfsan_origin dst_o = 0; 365 for (; src >= src_begin; --src, --src_s, --dst) { 366 if (!*src_s) 367 continue; 368 if (*src != src_o) { 369 src_o = *src; 370 dst_o = ChainOrigin(src_o, stack); 371 } 372 *dst = dst_o; 373 } 374 } 375 376 // Copy left unaligned origin if that memory is tainted. 377 if (beg < d) 378 ChainAndWriteOriginIfTainted((uptr)src, beg + kOriginAlign - d, beg, stack); 379 } 380 381 // Copy or move the origins of the len bytes from src to dst. The source and 382 // target memory ranges may or may not be overlapped. This is used by memory 383 // transfer operations. stack records the stack trace of the memory transfer 384 // operation. 385 static void MoveOrigin(const void *dst, const void *src, uptr size, 386 StackTrace *stack) { 387 if (!has_valid_shadow_addr(dst) || 388 !has_valid_shadow_addr((void *)((uptr)dst + size)) || 389 !has_valid_shadow_addr(src) || 390 !has_valid_shadow_addr((void *)((uptr)src + size))) { 391 return; 392 } 393 // If destination origin range overlaps with source origin range, move 394 // origins by copying origins in a reverse order; otherwise, copy origins in 395 // a normal order. The orders of origin transfer are consistent with the 396 // orders of how memcpy and memmove transfer user data. 397 uptr src_aligned_beg = reinterpret_cast<uptr>(src) & ~3UL; 398 uptr src_aligned_end = (reinterpret_cast<uptr>(src) + size) & ~3UL; 399 uptr dst_aligned_beg = reinterpret_cast<uptr>(dst) & ~3UL; 400 if (dst_aligned_beg < src_aligned_end && dst_aligned_beg >= src_aligned_beg) 401 return ReverseCopyOrigin(dst, src, size, stack); 402 return CopyOrigin(dst, src, size, stack); 403 } 404 405 // Set the size bytes from the addres dst to be the origin value. 406 static void SetOrigin(const void *dst, uptr size, u32 origin) { 407 if (size == 0) 408 return; 409 410 // Origin mapping is 4 bytes per 4 bytes of application memory. 411 // Here we extend the range such that its left and right bounds are both 412 // 4 byte aligned. 413 uptr x = unaligned_origin_for((uptr)dst); 414 uptr beg = AlignDown(x); 415 uptr end = AlignUp(x + size); // align up. 416 u64 origin64 = ((u64)origin << 32) | origin; 417 // This is like memset, but the value is 32-bit. We unroll by 2 to write 418 // 64 bits at once. May want to unroll further to get 128-bit stores. 419 if (beg & 7ULL) { 420 if (*(u32 *)beg != origin) 421 *(u32 *)beg = origin; 422 beg += 4; 423 } 424 for (uptr addr = beg; addr < (end & ~7UL); addr += 8) { 425 if (*(u64 *)addr == origin64) 426 continue; 427 *(u64 *)addr = origin64; 428 } 429 if (end & 7ULL) 430 if (*(u32 *)(end - kOriginAlign) != origin) 431 *(u32 *)(end - kOriginAlign) = origin; 432 } 433 434 static void WriteShadowInRange(dfsan_label label, uptr beg_shadow_addr, 435 uptr end_shadow_addr) { 436 // TODO: After changing dfsan_label to 8bit, use internal_memset when label 437 // is not 0. 438 dfsan_label *labelp = (dfsan_label *)beg_shadow_addr; 439 if (label) { 440 for (; (uptr)labelp < end_shadow_addr; ++labelp) *labelp = label; 441 return; 442 } 443 444 for (; (uptr)labelp < end_shadow_addr; ++labelp) { 445 // Don't write the label if it is already the value we need it to be. 446 // In a program where most addresses are not labeled, it is common that 447 // a page of shadow memory is entirely zeroed. The Linux copy-on-write 448 // implementation will share all of the zeroed pages, making a copy of a 449 // page when any value is written. The un-sharing will happen even if 450 // the value written does not change the value in memory. Avoiding the 451 // write when both |label| and |*labelp| are zero dramatically reduces 452 // the amount of real memory used by large programs. 453 if (!*labelp) 454 continue; 455 456 *labelp = 0; 457 } 458 } 459 460 static void WriteShadowWithSize(dfsan_label label, uptr shadow_addr, 461 uptr size) { 462 WriteShadowInRange(label, shadow_addr, shadow_addr + size * sizeof(label)); 463 } 464 465 #define RET_CHAIN_ORIGIN(id) \ 466 GET_CALLER_PC_BP_SP; \ 467 (void)sp; \ 468 GET_STORE_STACK_TRACE_PC_BP(pc, bp); \ 469 return ChainOrigin(id, &stack); 470 471 // Return a new origin chain with the previous ID id and the current stack 472 // trace. 473 extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin 474 __dfsan_chain_origin(dfsan_origin id) { 475 RET_CHAIN_ORIGIN(id) 476 } 477 478 // Return a new origin chain with the previous ID id and the current stack 479 // trace if the label is tainted. 480 extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin 481 __dfsan_chain_origin_if_tainted(dfsan_label label, dfsan_origin id) { 482 if (!label) 483 return id; 484 RET_CHAIN_ORIGIN(id) 485 } 486 487 // Copy or move the origins of the len bytes from src to dst. 488 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_mem_origin_transfer( 489 const void *dst, const void *src, uptr len) { 490 if (src == dst) 491 return; 492 GET_CALLER_PC_BP; 493 GET_STORE_STACK_TRACE_PC_BP(pc, bp); 494 MoveOrigin(dst, src, len, &stack); 495 } 496 497 SANITIZER_INTERFACE_ATTRIBUTE void dfsan_mem_origin_transfer(const void *dst, 498 const void *src, 499 uptr len) { 500 __dfsan_mem_origin_transfer(dst, src, len); 501 } 502 503 namespace __dfsan { 504 505 bool dfsan_inited = false; 506 bool dfsan_init_is_running = false; 507 508 void dfsan_copy_memory(void *dst, const void *src, uptr size) { 509 internal_memcpy(dst, src, size); 510 internal_memcpy((void *)shadow_for(dst), (const void *)shadow_for(src), 511 size * sizeof(dfsan_label)); 512 if (__dfsan_get_track_origins()) 513 dfsan_mem_origin_transfer(dst, src, size); 514 } 515 516 } // namespace __dfsan 517 518 // If the label s is tainted, set the size bytes from the address p to be a new 519 // origin chain with the previous ID o and the current stack trace. This is 520 // used by instrumentation to reduce code size when too much code is inserted. 521 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_maybe_store_origin( 522 dfsan_label s, void *p, uptr size, dfsan_origin o) { 523 if (UNLIKELY(s)) { 524 GET_CALLER_PC_BP_SP; 525 (void)sp; 526 GET_STORE_STACK_TRACE_PC_BP(pc, bp); 527 SetOrigin(p, size, ChainOrigin(o, &stack)); 528 } 529 } 530 531 // Releases the pages within the origin address range. 532 static void ReleaseOrigins(void *addr, uptr size) { 533 const uptr beg_origin_addr = (uptr)__dfsan::origin_for(addr); 534 const void *end_addr = (void *)((uptr)addr + size); 535 const uptr end_origin_addr = (uptr)__dfsan::origin_for(end_addr); 536 537 if (end_origin_addr - beg_origin_addr < 538 common_flags()->clear_shadow_mmap_threshold) 539 return; 540 541 const uptr page_size = GetPageSizeCached(); 542 const uptr beg_aligned = RoundUpTo(beg_origin_addr, page_size); 543 const uptr end_aligned = RoundDownTo(end_origin_addr, page_size); 544 545 if (!MmapFixedSuperNoReserve(beg_aligned, end_aligned - beg_aligned)) 546 Die(); 547 } 548 549 // Releases the pages within the shadow address range, and sets 550 // the shadow addresses not on the pages to be 0. 551 static void ReleaseOrClearShadows(void *addr, uptr size) { 552 const uptr beg_shadow_addr = (uptr)__dfsan::shadow_for(addr); 553 const void *end_addr = (void *)((uptr)addr + size); 554 const uptr end_shadow_addr = (uptr)__dfsan::shadow_for(end_addr); 555 556 if (end_shadow_addr - beg_shadow_addr < 557 common_flags()->clear_shadow_mmap_threshold) 558 return WriteShadowWithSize(0, beg_shadow_addr, size); 559 560 const uptr page_size = GetPageSizeCached(); 561 const uptr beg_aligned = RoundUpTo(beg_shadow_addr, page_size); 562 const uptr end_aligned = RoundDownTo(end_shadow_addr, page_size); 563 564 if (beg_aligned >= end_aligned) { 565 WriteShadowWithSize(0, beg_shadow_addr, size); 566 } else { 567 if (beg_aligned != beg_shadow_addr) 568 WriteShadowInRange(0, beg_shadow_addr, beg_aligned); 569 if (end_aligned != end_shadow_addr) 570 WriteShadowInRange(0, end_aligned, end_shadow_addr); 571 if (!MmapFixedSuperNoReserve(beg_aligned, end_aligned - beg_aligned)) 572 Die(); 573 } 574 } 575 576 void SetShadow(dfsan_label label, void *addr, uptr size, dfsan_origin origin) { 577 if (0 != label) { 578 const uptr beg_shadow_addr = (uptr)__dfsan::shadow_for(addr); 579 WriteShadowWithSize(label, beg_shadow_addr, size); 580 if (__dfsan_get_track_origins()) 581 SetOrigin(addr, size, origin); 582 return; 583 } 584 585 if (__dfsan_get_track_origins()) 586 ReleaseOrigins(addr, size); 587 588 ReleaseOrClearShadows(addr, size); 589 } 590 591 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_set_label( 592 dfsan_label label, dfsan_origin origin, void *addr, uptr size) { 593 SetShadow(label, addr, size, origin); 594 } 595 596 SANITIZER_INTERFACE_ATTRIBUTE 597 void dfsan_set_label(dfsan_label label, void *addr, uptr size) { 598 dfsan_origin init_origin = 0; 599 if (label && __dfsan_get_track_origins()) { 600 GET_CALLER_PC_BP; 601 GET_STORE_STACK_TRACE_PC_BP(pc, bp); 602 init_origin = ChainOrigin(0, &stack, true); 603 } 604 SetShadow(label, addr, size, init_origin); 605 } 606 607 SANITIZER_INTERFACE_ATTRIBUTE 608 void dfsan_add_label(dfsan_label label, void *addr, uptr size) { 609 if (0 == label) 610 return; 611 612 if (__dfsan_get_track_origins()) { 613 GET_CALLER_PC_BP; 614 GET_STORE_STACK_TRACE_PC_BP(pc, bp); 615 dfsan_origin init_origin = ChainOrigin(0, &stack, true); 616 SetOrigin(addr, size, init_origin); 617 } 618 619 for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp) 620 *labelp |= label; 621 } 622 623 // Unlike the other dfsan interface functions the behavior of this function 624 // depends on the label of one of its arguments. Hence it is implemented as a 625 // custom function. 626 extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label 627 __dfsw_dfsan_get_label(long data, dfsan_label data_label, 628 dfsan_label *ret_label) { 629 *ret_label = 0; 630 return data_label; 631 } 632 633 extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label __dfso_dfsan_get_label( 634 long data, dfsan_label data_label, dfsan_label *ret_label, 635 dfsan_origin data_origin, dfsan_origin *ret_origin) { 636 *ret_label = 0; 637 *ret_origin = 0; 638 return data_label; 639 } 640 641 // This function is used if dfsan_get_origin is called when origin tracking is 642 // off. 643 extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin __dfsw_dfsan_get_origin( 644 long data, dfsan_label data_label, dfsan_label *ret_label) { 645 *ret_label = 0; 646 return 0; 647 } 648 649 extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin __dfso_dfsan_get_origin( 650 long data, dfsan_label data_label, dfsan_label *ret_label, 651 dfsan_origin data_origin, dfsan_origin *ret_origin) { 652 *ret_label = 0; 653 *ret_origin = 0; 654 return data_origin; 655 } 656 657 SANITIZER_INTERFACE_ATTRIBUTE dfsan_label 658 dfsan_read_label(const void *addr, uptr size) { 659 if (size == 0) 660 return 0; 661 return __dfsan_union_load(shadow_for(addr), size); 662 } 663 664 SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin 665 dfsan_read_origin_of_first_taint(const void *addr, uptr size) { 666 return GetOriginIfTainted((uptr)addr, size); 667 } 668 669 SANITIZER_INTERFACE_ATTRIBUTE void dfsan_set_label_origin(dfsan_label label, 670 dfsan_origin origin, 671 void *addr, 672 uptr size) { 673 __dfsan_set_label(label, origin, addr, size); 674 } 675 676 extern "C" SANITIZER_INTERFACE_ATTRIBUTE int 677 dfsan_has_label(dfsan_label label, dfsan_label elem) { 678 return (label & elem) == elem; 679 } 680 681 class Decorator : public __sanitizer::SanitizerCommonDecorator { 682 public: 683 Decorator() : SanitizerCommonDecorator() {} 684 const char *Origin() const { return Magenta(); } 685 }; 686 687 namespace { 688 689 void PrintNoOriginTrackingWarning() { 690 Decorator d; 691 Printf( 692 " %sDFSan: origin tracking is not enabled. Did you specify the " 693 "-dfsan-track-origins=1 option?%s\n", 694 d.Warning(), d.Default()); 695 } 696 697 void PrintNoTaintWarning(const void *address) { 698 Decorator d; 699 Printf(" %sDFSan: no tainted value at %x%s\n", d.Warning(), address, 700 d.Default()); 701 } 702 703 void PrintInvalidOriginWarning(dfsan_label label, const void *address) { 704 Decorator d; 705 Printf( 706 " %sTaint value 0x%x (at %p) has invalid origin tracking. This can " 707 "be a DFSan bug.%s\n", 708 d.Warning(), label, address, d.Default()); 709 } 710 711 bool PrintOriginTraceToStr(const void *addr, const char *description, 712 InternalScopedString *out) { 713 CHECK(out); 714 CHECK(__dfsan_get_track_origins()); 715 Decorator d; 716 717 const dfsan_label label = *__dfsan::shadow_for(addr); 718 CHECK(label); 719 720 const dfsan_origin origin = *__dfsan::origin_for(addr); 721 722 out->append(" %sTaint value 0x%x (at %p) origin tracking (%s)%s\n", 723 d.Origin(), label, addr, description ? description : "", 724 d.Default()); 725 726 Origin o = Origin::FromRawId(origin); 727 bool found = false; 728 729 while (o.isChainedOrigin()) { 730 StackTrace stack; 731 dfsan_origin origin_id = o.raw_id(); 732 o = o.getNextChainedOrigin(&stack); 733 if (o.isChainedOrigin()) 734 out->append( 735 " %sOrigin value: 0x%x, Taint value was stored to memory at%s\n", 736 d.Origin(), origin_id, d.Default()); 737 else 738 out->append(" %sOrigin value: 0x%x, Taint value was created at%s\n", 739 d.Origin(), origin_id, d.Default()); 740 741 // Includes a trailing newline, so no need to add it again. 742 stack.PrintTo(out); 743 found = true; 744 } 745 746 return found; 747 } 748 749 } // namespace 750 751 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void dfsan_print_origin_trace( 752 const void *addr, const char *description) { 753 if (!__dfsan_get_track_origins()) { 754 PrintNoOriginTrackingWarning(); 755 return; 756 } 757 758 const dfsan_label label = *__dfsan::shadow_for(addr); 759 if (!label) { 760 PrintNoTaintWarning(addr); 761 return; 762 } 763 764 InternalScopedString trace; 765 bool success = PrintOriginTraceToStr(addr, description, &trace); 766 767 if (trace.length()) 768 Printf("%s", trace.data()); 769 770 if (!success) 771 PrintInvalidOriginWarning(label, addr); 772 } 773 774 extern "C" SANITIZER_INTERFACE_ATTRIBUTE size_t 775 dfsan_sprint_origin_trace(const void *addr, const char *description, 776 char *out_buf, size_t out_buf_size) { 777 CHECK(out_buf); 778 779 if (!__dfsan_get_track_origins()) { 780 PrintNoOriginTrackingWarning(); 781 return 0; 782 } 783 784 const dfsan_label label = *__dfsan::shadow_for(addr); 785 if (!label) { 786 PrintNoTaintWarning(addr); 787 return 0; 788 } 789 790 InternalScopedString trace; 791 bool success = PrintOriginTraceToStr(addr, description, &trace); 792 793 if (!success) { 794 PrintInvalidOriginWarning(label, addr); 795 return 0; 796 } 797 798 if (out_buf_size) { 799 internal_strncpy(out_buf, trace.data(), out_buf_size - 1); 800 out_buf[out_buf_size - 1] = '\0'; 801 } 802 803 return trace.length(); 804 } 805 806 extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_origin 807 dfsan_get_init_origin(const void *addr) { 808 if (!__dfsan_get_track_origins()) 809 return 0; 810 811 const dfsan_label label = *__dfsan::shadow_for(addr); 812 if (!label) 813 return 0; 814 815 const dfsan_origin origin = *__dfsan::origin_for(addr); 816 817 Origin o = Origin::FromRawId(origin); 818 dfsan_origin origin_id = o.raw_id(); 819 while (o.isChainedOrigin()) { 820 StackTrace stack; 821 origin_id = o.raw_id(); 822 o = o.getNextChainedOrigin(&stack); 823 } 824 return origin_id; 825 } 826 827 void __sanitizer::BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, 828 void *context, 829 bool request_fast, 830 u32 max_depth) { 831 using namespace __dfsan; 832 DFsanThread *t = GetCurrentThread(); 833 if (!t || !StackTrace::WillUseFastUnwind(request_fast)) { 834 return Unwind(max_depth, pc, bp, context, 0, 0, false); 835 } 836 Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true); 837 } 838 839 extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_print_stack_trace() { 840 GET_CALLER_PC_BP; 841 GET_STORE_STACK_TRACE_PC_BP(pc, bp); 842 stack.Print(); 843 } 844 845 extern "C" SANITIZER_INTERFACE_ATTRIBUTE size_t 846 dfsan_sprint_stack_trace(char *out_buf, size_t out_buf_size) { 847 CHECK(out_buf); 848 GET_CALLER_PC_BP; 849 GET_STORE_STACK_TRACE_PC_BP(pc, bp); 850 return stack.PrintTo(out_buf, out_buf_size); 851 } 852 853 void Flags::SetDefaults() { 854 #define DFSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 855 #include "dfsan_flags.inc" 856 #undef DFSAN_FLAG 857 } 858 859 static void RegisterDfsanFlags(FlagParser *parser, Flags *f) { 860 #define DFSAN_FLAG(Type, Name, DefaultValue, Description) \ 861 RegisterFlag(parser, #Name, Description, &f->Name); 862 #include "dfsan_flags.inc" 863 #undef DFSAN_FLAG 864 } 865 866 static void InitializeFlags() { 867 SetCommonFlagsDefaults(); 868 { 869 CommonFlags cf; 870 cf.CopyFrom(*common_flags()); 871 cf.intercept_tls_get_addr = true; 872 OverrideCommonFlags(cf); 873 } 874 flags().SetDefaults(); 875 876 FlagParser parser; 877 RegisterCommonFlags(&parser); 878 RegisterDfsanFlags(&parser, &flags()); 879 parser.ParseStringFromEnv("DFSAN_OPTIONS"); 880 InitializeCommonFlags(); 881 if (Verbosity()) ReportUnrecognizedFlags(); 882 if (common_flags()->help) parser.PrintFlagDescriptions(); 883 } 884 885 SANITIZER_INTERFACE_ATTRIBUTE 886 void dfsan_clear_arg_tls(uptr offset, uptr size) { 887 internal_memset((void *)((uptr)__dfsan_arg_tls + offset), 0, size); 888 } 889 890 SANITIZER_INTERFACE_ATTRIBUTE 891 void dfsan_clear_thread_local_state() { 892 internal_memset(__dfsan_arg_tls, 0, sizeof(__dfsan_arg_tls)); 893 internal_memset(__dfsan_retval_tls, 0, sizeof(__dfsan_retval_tls)); 894 895 if (__dfsan_get_track_origins()) { 896 internal_memset(__dfsan_arg_origin_tls, 0, sizeof(__dfsan_arg_origin_tls)); 897 internal_memset(&__dfsan_retval_origin_tls, 0, 898 sizeof(__dfsan_retval_origin_tls)); 899 } 900 } 901 902 static void InitializePlatformEarly() { 903 AvoidCVE_2016_2143(); 904 #ifdef DFSAN_RUNTIME_VMA 905 __dfsan::vmaSize = 906 (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); 907 if (__dfsan::vmaSize == 39 || __dfsan::vmaSize == 42 || 908 __dfsan::vmaSize == 48) { 909 __dfsan_shadow_ptr_mask = ShadowMask(); 910 } else { 911 Printf("FATAL: DataFlowSanitizer: unsupported VMA range\n"); 912 Printf("FATAL: Found %d - Supported 39, 42, and 48\n", __dfsan::vmaSize); 913 Die(); 914 } 915 #endif 916 } 917 918 extern "C" void dfsan_flush() { 919 if (!MmapFixedSuperNoReserve(ShadowAddr(), UnusedAddr() - ShadowAddr())) 920 Die(); 921 } 922 923 static void DFsanInit(int argc, char **argv, char **envp) { 924 CHECK(!dfsan_init_is_running); 925 if (dfsan_inited) 926 return; 927 dfsan_init_is_running = true; 928 SanitizerToolName = "DataflowSanitizer"; 929 930 InitializeFlags(); 931 932 ::InitializePlatformEarly(); 933 934 dfsan_flush(); 935 if (common_flags()->use_madv_dontdump) 936 DontDumpShadowMemory(ShadowAddr(), UnusedAddr() - ShadowAddr()); 937 938 // Protect the region of memory we don't use, to preserve the one-to-one 939 // mapping from application to shadow memory. But if ASLR is disabled, Linux 940 // will load our executable in the middle of our unused region. This mostly 941 // works so long as the program doesn't use too much memory. We support this 942 // case by disabling memory protection when ASLR is disabled. 943 uptr init_addr = (uptr)&DFsanInit; 944 if (!(init_addr >= UnusedAddr() && init_addr < AppAddr())) 945 MmapFixedNoAccess(UnusedAddr(), AppAddr() - UnusedAddr()); 946 947 initialize_interceptors(); 948 949 // Set up threads 950 DFsanTSDInit(DFsanTSDDtor); 951 952 dfsan_allocator_init(); 953 954 DFsanThread *main_thread = DFsanThread::Create(nullptr, nullptr, nullptr); 955 SetCurrentThread(main_thread); 956 main_thread->ThreadStart(); 957 958 dfsan_init_is_running = false; 959 dfsan_inited = true; 960 } 961 962 namespace __dfsan { 963 964 void dfsan_init() { DFsanInit(0, nullptr, nullptr); } 965 966 } // namespace __dfsan 967 968 #if SANITIZER_CAN_USE_PREINIT_ARRAY 969 __attribute__((section(".preinit_array"), 970 used)) static void (*dfsan_init_ptr)(int, char **, 971 char **) = DFsanInit; 972 #endif 973