Lines Matching +full:x +full:- +full:origin
1 //===-- dfsan.cpp ---------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
19 //===----------------------------------------------------------------------===//
58 // Instrumented code may set this value in terms of -dfsan-track-origins.
71 // +--------------------+ 0x800000000000 (top of memory)
73 // +--------------------+ 0x700000000000
75 // +--------------------+ 0x610000000000
76 // | origin 1 |
77 // +--------------------+ 0x600000000000
79 // +--------------------+ 0x510000000000
81 // +--------------------+ 0x500000000000
83 // +--------------------+ 0x400000000000
84 // | origin 3 |
85 // +--------------------+ 0x300000000000
87 // +--------------------+ 0x200000000000
88 // | origin 2 |
89 // +--------------------+ 0x110000000000
91 // +--------------------+ 0x100000000000
93 // +--------------------+ 0x010000000000
95 // +--------------------+ 0x000000000000
109 // origin of the first taint byte at the low 32 bit.
145 // Use '-mllvm -dfsan-debug-nonzero-labels' and break on this function
147 // label-free program.
169 static const uptr kOriginAlignMask = ~(kOriginAlign - 1UL);
172 return (u + kOriginAlign - 1) & kOriginAlignMask; in OriginAlignUp()
177 // Return the origin of the first taint byte in the size bytes from the address
209 // from_init = true if this is the first chain of an origin tracking path.
214 if (t && t->InSignalHandler()) in ChainOrigin()
217 // As an optimization the origin of an application byte is updated only when in ChainOrigin()
218 // its shadow is non-zero. Because we are only interested in the origins of in ChainOrigin()
219 // taint labels, it does not matter what origin a zero label has. This reduces in ChainOrigin()
223 Printf(" DFSan found invalid origin invariant\n"); in ChainOrigin()
227 Origin o = Origin::FromRawId(id); in ChainOrigin()
228 stack->tag = StackTrace::TAG_UNKNOWN; in ChainOrigin()
229 Origin chained = Origin::CreateChainedOrigin(o, stack); in ChainOrigin()
244 // stack trace of the memcpy. When dst and src are not 4-byte aligned properly,
246 // contiguous bytes share the same origin.
251 // Copy left unaligned origin if that memory is tainted. in CopyOrigin()
253 ChainAndWriteOriginIfTainted((uptr)src, beg + kOriginAlign - d, beg, stack); in CopyOrigin()
258 // If both ends fall into the same 4-byte slot, we are done. in CopyOrigin()
262 // Copy right unaligned origin if that memory is tainted. in CopyOrigin()
264 ChainAndWriteOriginIfTainted((uptr)src + (end - d), (d + size) - end, end, in CopyOrigin()
274 dfsan_origin *src_end = origin_for((void *)(src_a + (end - beg))); in CopyOrigin()
297 // Copy right unaligned origin if that memory is tainted. in ReverseCopyOrigin()
299 ChainAndWriteOriginIfTainted((uptr)src + (end - d), (d + size) - end, end, in ReverseCopyOrigin()
307 void *src_end = (void *)(src_a + end - beg - kOriginAlign); in ReverseCopyOrigin()
311 dfsan_origin *dst = origin_for((void *)(end - kOriginAlign)); in ReverseCopyOrigin()
314 for (; src_end_o >= src_begin_o; --src_end_o, --src_end_s, --dst) { in ReverseCopyOrigin()
325 // Copy left unaligned origin if that memory is tainted. in ReverseCopyOrigin()
327 ChainAndWriteOriginIfTainted((uptr)src, beg + kOriginAlign - d, beg, stack); in ReverseCopyOrigin()
344 // If destination origin range overlaps with source origin range, move in MoveOrigin()
346 // a normal order. The orders of origin transfer are consistent with the in MoveOrigin()
356 // Set the size bytes from the addres dst to be the origin value.
357 static void SetOrigin(const void *dst, uptr size, u32 origin) { in SetOrigin() argument
361 // Origin mapping is 4 bytes per 4 bytes of application memory. in SetOrigin()
364 uptr x = unaligned_origin_for((uptr)dst); in SetOrigin() local
365 uptr beg = OriginAlignDown(x); in SetOrigin()
366 uptr end = OriginAlignUp(x + size); // align up. in SetOrigin()
367 u64 origin64 = ((u64)origin << 32) | origin; in SetOrigin()
368 // This is like memset, but the value is 32-bit. We unroll by 2 to write in SetOrigin()
369 // 64 bits at once. May want to unroll further to get 128-bit stores. in SetOrigin()
371 if (*(u32 *)beg != origin) in SetOrigin()
372 *(u32 *)beg = origin; in SetOrigin()
381 if (*(u32 *)(end - kOriginAlign) != origin) in SetOrigin()
382 *(u32 *)(end - kOriginAlign) = origin; in SetOrigin()
390 // Return a new origin chain with the previous ID id and the current stack
397 // Return a new origin chain with the previous ID id and the current stack
488 // Releases the pages within the origin address range.
494 if (end_origin_addr - beg_origin_addr < in ReleaseOrigins()
495 common_flags()->clear_shadow_mmap_threshold) in ReleaseOrigins()
502 if (!MmapFixedSuperNoReserve(beg_aligned, end_aligned - beg_aligned)) in ReleaseOrigins()
509 // a page of shadow memory is entirely zeroed. The Linux copy-on-write in WriteZeroShadowInRange()
511 // page when any value is written. The un-sharing will happen even if in WriteZeroShadowInRange()
515 if (!mem_is_zero((const char *)beg, end - beg)) in WriteZeroShadowInRange()
516 internal_memset((void *)beg, 0, end - beg); in WriteZeroShadowInRange()
526 if (end_shadow_addr - beg_shadow_addr < in ReleaseOrClearShadows()
527 common_flags()->clear_shadow_mmap_threshold) { in ReleaseOrClearShadows()
543 if (!MmapFixedSuperNoReserve(beg_aligned, end_aligned - beg_aligned)) in ReleaseOrClearShadows()
548 void SetShadow(dfsan_label label, void *addr, uptr size, dfsan_origin origin) { in SetShadow() argument
553 SetOrigin(addr, size, origin); in SetShadow()
566 // origin chain with the previous ID o and the current stack trace. This is
578 dfsan_label label, dfsan_origin origin, void *addr, uptr size) { in __dfsan_set_label() argument
579 __dfsan::SetShadow(label, addr, size, origin); in __dfsan_set_label()
605 for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp) in dfsan_add_label()
627 // This function is used if dfsan_get_origin is called when origin tracking is
656 dfsan_origin origin, in dfsan_set_label_origin() argument
659 __dfsan_set_label(label, origin, addr, size); in dfsan_set_label_origin()
670 dfsan_origin origin);
674 static void ConditionalCallback(dfsan_label label, dfsan_origin origin) { in ConditionalCallback() argument
690 if (t && t->InSignalHandler()) { in ConditionalCallback()
696 conditional_callback(label, origin); in ConditionalCallback()
702 __dfsan_conditional_callback_origin(dfsan_label label, dfsan_origin origin) { in __dfsan_conditional_callback_origin() argument
703 __dfsan::ConditionalCallback(label, origin); in __dfsan_conditional_callback_origin()
724 dfsan_origin origin,
731 static void ReachesFunctionCallback(dfsan_label label, dfsan_origin origin, in ReachesFunctionCallback() argument
747 if (t && t->InSignalHandler()) { in ReachesFunctionCallback()
753 reaches_function_callback(label, origin, file, line, function); in ReachesFunctionCallback()
759 __dfsan_reaches_function_callback_origin(dfsan_label label, dfsan_origin origin, in __dfsan_reaches_function_callback_origin() argument
762 __dfsan::ReachesFunctionCallback(label, origin, file, line, function); in __dfsan_reaches_function_callback_origin()
785 const char *Origin() const { return Magenta(); } in Origin() function in Decorator
793 " %sDFSan: origin tracking is not enabled. Did you specify the " in PrintNoOriginTrackingWarning()
794 "-dfsan-track-origins=1 option?%s\n", in PrintNoOriginTrackingWarning()
800 Printf(" %sDFSan: no tainted value at %x%s\n", d.Warning(), address, in PrintNoTaintWarning()
807 " %sTaint value 0x%x (at %p) has invalid origin tracking. This can " in PrintInvalidOriginWarning()
812 void PrintInvalidOriginIdWarning(dfsan_origin origin) { in PrintInvalidOriginIdWarning() argument
815 " %sOrigin Id %d has invalid origin tracking. This can " in PrintInvalidOriginIdWarning()
817 d.Warning(), origin, d.Default()); in PrintInvalidOriginIdWarning()
820 bool PrintOriginTraceFramesToStr(Origin o, InternalScopedString *out) { in PrintOriginTraceFramesToStr()
829 out->AppendF( in PrintOriginTraceFramesToStr()
830 " %sOrigin value: 0x%x, Taint value was stored to memory at%s\n", in PrintOriginTraceFramesToStr()
831 d.Origin(), origin_id, d.Default()); in PrintOriginTraceFramesToStr()
833 out->AppendF(" %sOrigin value: 0x%x, Taint value was created at%s\n", in PrintOriginTraceFramesToStr()
834 d.Origin(), origin_id, d.Default()); in PrintOriginTraceFramesToStr()
853 const dfsan_origin origin = *__dfsan::origin_for(addr); in PrintOriginTraceToStr() local
855 out->AppendF(" %sTaint value 0x%x (at %p) origin tracking (%s)%s\n", in PrintOriginTraceToStr()
856 d.Origin(), label, addr, description ? description : "", in PrintOriginTraceToStr()
859 Origin o = Origin::FromRawId(origin); in PrintOriginTraceToStr()
913 internal_strncpy(out_buf, trace.data(), out_buf_size - 1); in dfsan_sprint_origin_trace()
914 out_buf[out_buf_size - 1] = '\0'; in dfsan_sprint_origin_trace()
921 dfsan_origin origin) { in dfsan_print_origin_id_trace() argument
926 Origin o = Origin::FromRawId(origin); in dfsan_print_origin_id_trace()
935 PrintInvalidOriginIdWarning(origin); in dfsan_print_origin_id_trace()
939 dfsan_origin origin, char *out_buf, uptr out_buf_size) { in dfsan_sprint_origin_id_trace() argument
946 Origin o = Origin::FromRawId(origin); in dfsan_sprint_origin_id_trace()
952 PrintInvalidOriginIdWarning(origin); in dfsan_sprint_origin_id_trace()
957 internal_strncpy(out_buf, trace.data(), out_buf_size - 1); in dfsan_sprint_origin_id_trace()
958 out_buf[out_buf_size - 1] = '\0'; in dfsan_sprint_origin_id_trace()
973 const dfsan_origin origin = *__dfsan::origin_for(addr); in dfsan_get_init_origin() local
975 Origin o = Origin::FromRawId(origin); in dfsan_get_init_origin()
994 Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true); in UnwindImpl()
1019 RegisterFlag(parser, #Name, Description, &f->Name); in RegisterDfsanFlags()
1040 if (common_flags()->help) parser.PrintFlagDescriptions(); in InitializeFlags()
1062 // 2x to match ShadowTLSAlignment. in dfsan_set_arg_tls()
1079 uptr size = end - start; in dfsan_flush()
1082 if (type != MappingDesc::SHADOW && type != MappingDesc::ORIGIN) in dfsan_flush()
1110 CHECK(addr_is_type(end - 1, type)); in CheckMemoryLayoutSanity()
1122 addr = end - 1; in CheckMemoryLayoutSanity()
1135 uptr end = beg + size - 1; in CheckMemoryRangeAvailability()
1138 Printf("FATAL: Memory range %p - %p is not available.\n", beg, end); in CheckMemoryRangeAvailability()
1155 size -= gap; in ProtectMemoryRange()
1159 uptr end = beg + size - 1; in ProtectMemoryRange()
1160 Printf("FATAL: Cannot protect memory range %p - %p (%s).\n", beg, end, in ProtectMemoryRange()
1174 VPrintf(1, "%s: %zx - %zx\n", kMemoryLayout[i].name, kMemoryLayout[i].start, in InitShadow()
1175 kMemoryLayout[i].end - 1); in InitShadow()
1181 Printf("FATAL: Code %p is out of application range. Non-PIE build?\n", in InitShadow()
1191 uptr size = end - start; in InitShadow()
1199 (init_origins && type == MappingDesc::ORIGIN); in InitShadow()
1201 (!init_origins && type == MappingDesc::ORIGIN); in InitShadow()
1216 if (!dry_run && common_flags()->use_madv_dontdump) in InitShadow()
1232 // warning messages will cause tests to fail (even if we successfully re-exec in InitShadowWithReExec()
1237 // Perhaps ASLR entropy is too high. If ASLR is enabled, re-exec without it. in InitShadowWithReExec()
1240 (old_personality != -1) && ((old_personality & ADDR_NO_RANDOMIZE) == 0); in InitShadowWithReExec()
1245 "possibly due to high-entropy ASLR.\n" in InitShadowWithReExec()
1246 "Re-execing with fixed virtual address space.\n" in InitShadowWithReExec()
1248 CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1); in InitShadowWithReExec()
1255 // non-dry run mode. in InitShadowWithReExec()
1287 main_thread->Init(); in DFsanInit()