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