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