178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===-- msan.cc -----------------------------------------------------------===// 278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// 378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// The LLVM Compiler Infrastructure 478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// 578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// This file is distributed under the University of Illinois Open Source 678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// License. See LICENSE.TXT for details. 778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// 878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===----------------------------------------------------------------------===// 978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// 1078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// This file is a part of MemorySanitizer. 1178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// 1278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// MemorySanitizer runtime. 1378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov//===----------------------------------------------------------------------===// 1478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 1578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "msan.h" 1678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_atomic.h" 1778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_common.h" 1878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_flags.h" 1978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_libc.h" 2078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_procmaps.h" 2178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_stacktrace.h" 2278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "sanitizer_common/sanitizer_symbolizer.h" 2378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 2478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov#include "interception/interception.h" 2578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 2678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// ACHTUNG! No system header includes in this file. 2778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 2878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovusing namespace __sanitizer; 2978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 3078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// Globals. 3178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic THREADLOCAL int msan_expect_umr = 0; 3278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic THREADLOCAL int msan_expected_umr_found = 0; 3378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 3478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic int msan_running_under_dr = 0; 3578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 3678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovSANITIZER_INTERFACE_ATTRIBUTE 3778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovTHREADLOCAL u64 __msan_param_tls[kMsanParamTlsSizeInWords]; 3878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 3978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovSANITIZER_INTERFACE_ATTRIBUTE 4078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovTHREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSizeInWords]; 4178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 4278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovSANITIZER_INTERFACE_ATTRIBUTE 4378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovTHREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSizeInWords]; 4478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 4578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovSANITIZER_INTERFACE_ATTRIBUTE 4678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovTHREADLOCAL u32 __msan_retval_origin_tls; 4778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 4878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovSANITIZER_INTERFACE_ATTRIBUTE 4978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovTHREADLOCAL u64 __msan_va_arg_tls[kMsanParamTlsSizeInWords]; 5078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 5178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovSANITIZER_INTERFACE_ATTRIBUTE 5278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovTHREADLOCAL u64 __msan_va_arg_overflow_size_tls; 5378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 5478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovSANITIZER_INTERFACE_ATTRIBUTE 5578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovTHREADLOCAL u32 __msan_origin_tls; 5678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 5778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic THREADLOCAL struct { 5878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov uptr stack_top, stack_bottom; 5978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} __msan_stack_bounds; 6078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 6170c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryanystatic THREADLOCAL bool is_in_symbolizer; 620f92deb81207c80481ff0257fbaba640fe669633Reid Klecknerstatic THREADLOCAL bool is_in_loader; 6370c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany 64a879f10ee6aa04f6169d056ef2a9c39502fff290Evgeniy Stepanovextern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins; 65b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov 6678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovint __msan_get_track_origins() { 67b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov return &__msan_track_origins ? __msan_track_origins : 0; 6878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 6978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 70bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanovextern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going; 71bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov 7278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovnamespace __msan { 7378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 7478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic bool IsRunningUnderDr() { 7578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov bool result = false; 769ae2883d88dd28b9c5dc862107e6e6d12a35926eAlexander Potapenko MemoryMappingLayout proc_maps(/*cache_enabled*/true); 7778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov const sptr kBufSize = 4095; 7878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov char *filename = (char*)MmapOrDie(kBufSize, __FUNCTION__); 7978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov while (proc_maps.Next(/* start */0, /* end */0, /* file_offset */0, 8045717c9d5e39a434749ae10509111f9df1b2cdf4Alexey Samsonov filename, kBufSize, /* protection */0)) { 8178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (internal_strstr(filename, "libdynamorio") != 0) { 8278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov result = true; 8378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov break; 8478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 8578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 8678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov UnmapOrDie(filename, kBufSize); 8778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return result; 8878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 8978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 9070c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryanyvoid EnterSymbolizer() { is_in_symbolizer = true; } 9170c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryanyvoid ExitSymbolizer() { is_in_symbolizer = false; } 9270c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryanybool IsInSymbolizer() { return is_in_symbolizer; } 9370c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany 940f92deb81207c80481ff0257fbaba640fe669633Reid Klecknervoid EnterLoader() { is_in_loader = true; } 950f92deb81207c80481ff0257fbaba640fe669633Reid Klecknervoid ExitLoader() { is_in_loader = false; } 960f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner 970f92deb81207c80481ff0257fbaba640fe669633Reid Klecknerextern "C" { 980f92deb81207c80481ff0257fbaba640fe669633Reid KlecknerSANITIZER_INTERFACE_ATTRIBUTE 990f92deb81207c80481ff0257fbaba640fe669633Reid Klecknerbool __msan_is_in_loader() { return is_in_loader; } 1000f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner} 1010f92deb81207c80481ff0257fbaba640fe669633Reid Kleckner 10278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic Flags msan_flags; 10378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 10478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovFlags *flags() { 10578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return &msan_flags; 10678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 10778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 10878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovint msan_inited = 0; 10978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovbool msan_init_is_running; 11078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 11199bf1d71c634ab0ed39d7614fd8f8f2c2201e111Evgeniy Stepanovint msan_report_count = 0; 11299bf1d71c634ab0ed39d7614fd8f8f2c2201e111Evgeniy Stepanov 11378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// Array of stack origins. 11478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// FIXME: make it resizable. 11578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic const uptr kNumStackOriginDescrs = 1024 * 1024; 11678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic const char *StackOriginDescr[kNumStackOriginDescrs]; 11778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic atomic_uint32_t NumStackOriginDescrs; 11878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 11978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic void ParseFlagsFromString(Flags *f, const char *str) { 1200b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev ParseCommonFlagsFromString(str); 12178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov ParseFlag(str, &f->poison_heap_with_zeroes, "poison_heap_with_zeroes"); 12278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov ParseFlag(str, &f->poison_stack_with_zeroes, "poison_stack_with_zeroes"); 12378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov ParseFlag(str, &f->poison_in_malloc, "poison_in_malloc"); 12478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov ParseFlag(str, &f->exit_code, "exit_code"); 12578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (f->exit_code < 0 || f->exit_code > 127) { 12678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("Exit code not in [0, 128) range: %d\n", f->exit_code); 12778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov f->exit_code = 1; 12878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Die(); 12978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 13078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov ParseFlag(str, &f->report_umrs, "report_umrs"); 13178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov ParseFlag(str, &f->verbosity, "verbosity"); 132a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov ParseFlag(str, &f->wrap_signals, "wrap_signals"); 133bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov ParseFlag(str, &f->keep_going, "keep_going"); 13478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 13578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 13678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic void InitializeFlags(Flags *f, const char *options) { 1370b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev CommonFlags *cf = common_flags(); 1380b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev cf->external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); 1390b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev cf->strip_path_prefix = ""; 1400b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev cf->fast_unwind_on_fatal = false; 1410b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev cf->fast_unwind_on_malloc = true; 1420b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev cf->malloc_context_size = 20; 143745dd0d296e7bef712df4b5c7f86c72534953738Evgeniy Stepanov cf->handle_ioctl = true; 144b6246066a271e3b01732d1b4381ef745152747d2Evgeniy Stepanov cf->log_path = 0; 14578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 1460b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev internal_memset(f, 0, sizeof(*f)); 14778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov f->poison_heap_with_zeroes = false; 14878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov f->poison_stack_with_zeroes = false; 14978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov f->poison_in_malloc = true; 15078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov f->exit_code = 77; 15178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov f->report_umrs = true; 15278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov f->verbosity = 0; 153a213ab66e1c743ec7a52af4a49ec6c126cc245aeEvgeniy Stepanov f->wrap_signals = true; 154bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov f->keep_going = !!&__msan_keep_going; 15578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 15670c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany // Override from user-specified string. 15770c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany if (__msan_default_options) 15870c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany ParseFlagsFromString(f, __msan_default_options()); 15978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov ParseFlagsFromString(f, options); 16078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 16178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 16278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic void GetCurrentStackBounds(uptr *stack_top, uptr *stack_bottom) { 16378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (__msan_stack_bounds.stack_top == 0) { 16478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // Break recursion (GetStackTrace -> GetThreadStackTopAndBottom -> 16578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // realloc -> GetStackTrace). 16678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov __msan_stack_bounds.stack_top = __msan_stack_bounds.stack_bottom = 1; 16778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov GetThreadStackTopAndBottom(/* at_initialization */false, 16878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov &__msan_stack_bounds.stack_top, 16978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov &__msan_stack_bounds.stack_bottom); 17078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 17178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov *stack_top = __msan_stack_bounds.stack_top; 17278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov *stack_bottom = __msan_stack_bounds.stack_bottom; 17378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 17478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 175efbc43528892b0a30039f68633e0b4ed3bbd2daeEvgeniy Stepanovvoid GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, 176efbc43528892b0a30039f68633e0b4ed3bbd2daeEvgeniy Stepanov bool fast) { 17793c26022f362c9e0a6acbe3bf3c7c395e19e0835Reid Kleckner if (!fast) { 17893c26022f362c9e0a6acbe3bf3c7c395e19e0835Reid Kleckner // Block reports from our interceptors during _Unwind_Backtrace. 17993c26022f362c9e0a6acbe3bf3c7c395e19e0835Reid Kleckner SymbolizerScope sym_scope; 180efbc43528892b0a30039f68633e0b4ed3bbd2daeEvgeniy Stepanov return stack->SlowUnwindStack(pc, max_s); 18193c26022f362c9e0a6acbe3bf3c7c395e19e0835Reid Kleckner } 182efbc43528892b0a30039f68633e0b4ed3bbd2daeEvgeniy Stepanov 18378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov uptr stack_top, stack_bottom; 18478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov GetCurrentStackBounds(&stack_top, &stack_bottom); 18578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov stack->size = 0; 18678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov stack->trace[0] = pc; 18778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov stack->max_size = max_s; 18878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov stack->FastUnwindStack(pc, bp, stack_top, stack_bottom); 18978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 19078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 19178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid PrintWarning(uptr pc, uptr bp) { 19278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov PrintWarningWithOrigin(pc, bp, __msan_origin_tls); 19378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 19478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 195db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanovbool OriginIsValid(u32 origin) { 196db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov return origin != 0 && origin != (u32)-1; 197db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov} 198db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov 19978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) { 20078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (msan_expect_umr) { 20178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // Printf("Expected UMR\n"); 20278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov __msan_origin_tls = origin; 20378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov msan_expected_umr_found = 1; 20478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return; 20578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 20678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 20799bf1d71c634ab0ed39d7614fd8f8f2c2201e111Evgeniy Stepanov ++msan_report_count; 20899bf1d71c634ab0ed39d7614fd8f8f2c2201e111Evgeniy Stepanov 209db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov StackTrace stack; 2100b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev GetStackTrace(&stack, kStackTraceMax, pc, bp, 2110b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev common_flags()->fast_unwind_on_fatal); 212db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov 213db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov u32 report_origin = 214b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov (__msan_get_track_origins() && OriginIsValid(origin)) ? origin : 0; 215db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov ReportUMR(&stack, report_origin); 216db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov 217b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov if (__msan_get_track_origins() && !OriginIsValid(origin)) { 218db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov Printf(" ORIGIN: invalid (%x). Might be a bug in MemorySanitizer, " 219db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov "please report to MemorySanitizer developers.\n", 220db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov origin); 22178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 22278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 22378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 224c2918bf11fc65b1f9551eee03719e9bdf02eedd5Alexey Samsonovvoid UnpoisonParam(uptr n) { 225c2918bf11fc65b1f9551eee03719e9bdf02eedd5Alexey Samsonov internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls)); 226c2918bf11fc65b1f9551eee03719e9bdf02eedd5Alexey Samsonov} 227c2918bf11fc65b1f9551eee03719e9bdf02eedd5Alexey Samsonov 22878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} // namespace __msan 22978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 23078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// Interface. 23178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 23278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovusing namespace __msan; 23378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 23478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_warning() { 23578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov GET_CALLER_PC_BP_SP; 23678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov (void)sp; 23778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov PrintWarning(pc, bp); 238bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov if (!__msan::flags()->keep_going) { 239bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov Printf("Exiting\n"); 240bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov Die(); 241bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov } 24278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 24378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 24478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_warning_noreturn() { 24578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov GET_CALLER_PC_BP_SP; 24678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov (void)sp; 24778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov PrintWarning(pc, bp); 24878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("Exiting\n"); 24978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Die(); 25078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 25178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 25278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_init() { 25378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (msan_inited) return; 25478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov msan_init_is_running = 1; 255859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany SanitizerToolName = "MemorySanitizer"; 25678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 25799bf1d71c634ab0ed39d7614fd8f8f2c2201e111Evgeniy Stepanov InstallAtExitHandler(); 25878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov SetDieCallback(MsanDie); 25910fd3227546d17c7411241a45ebc143b2031c78dEvgeniy Stepanov InitTlsSize(); 26078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov InitializeInterceptors(); 26178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 262a897400cec0284763da5a6db4670fa0a64bbfcd9Evgeniy Stepanov if (MSAN_REPLACE_OPERATORS_NEW_AND_DELETE) 263a897400cec0284763da5a6db4670fa0a64bbfcd9Evgeniy Stepanov ReplaceOperatorsNewAndDelete(); 264f35eae83757946decb312deab3f0fe155fe5d580Evgeniy Stepanov const char *msan_options = GetEnv("MSAN_OPTIONS"); 265f35eae83757946decb312deab3f0fe155fe5d580Evgeniy Stepanov InitializeFlags(&msan_flags, msan_options); 266b6246066a271e3b01732d1b4381ef745152747d2Evgeniy Stepanov __sanitizer_set_report_path(common_flags()->log_path); 26778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (StackSizeIsUnlimited()) { 26878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (flags()->verbosity) 26978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("Unlimited stack, doing reexec\n"); 27078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // A reasonably large stack size. It is bigger than the usual 8Mb, because, 27178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // well, the program could have been run with unlimited stack for a reason. 27278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov SetStackSizeLimitInBytes(32 * 1024 * 1024); 27378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov ReExec(); 27478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 275f35eae83757946decb312deab3f0fe155fe5d580Evgeniy Stepanov 27678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (flags()->verbosity) 27778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("MSAN_OPTIONS: %s\n", msan_options ? msan_options : "<empty>"); 278f35eae83757946decb312deab3f0fe155fe5d580Evgeniy Stepanov 27978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov msan_running_under_dr = IsRunningUnderDr(); 28078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov __msan_clear_on_return(); 281b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov if (__msan_get_track_origins() && flags()->verbosity > 0) 28278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("msan_track_origins\n"); 283b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov if (!InitShadow(/* prot1 */ false, /* prot2 */ true, /* map_shadow */ true, 284b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov __msan_get_track_origins())) { 28578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // FIXME: prot1 = false is only required when running under DR. 2864c9ddc143839c9f4b79152737cd2869c99e8e86dEvgeniy Stepanov Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n"); 28778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); 2884c9ddc143839c9f4b79152737cd2869c99e8e86dEvgeniy Stepanov Printf("FATAL: Disabling ASLR is known to cause this error.\n"); 2894b48f4563ca25d8915155acc5837e195cf0e5c57Kostya Serebryany Printf("FATAL: If running under GDB, try " 2904b48f4563ca25d8915155acc5837e195cf0e5c57Kostya Serebryany "'set disable-randomization off'.\n"); 29178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov DumpProcessMap(); 29278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Die(); 29378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 29478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 2950b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev const char *external_symbolizer = common_flags()->external_symbolizer_path; 29678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (external_symbolizer && external_symbolizer[0]) { 29778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov CHECK(InitializeExternalSymbolizer(external_symbolizer)); 29878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 29978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 30078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov GetThreadStackTopAndBottom(/* at_initialization */true, 30178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov &__msan_stack_bounds.stack_top, 30278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov &__msan_stack_bounds.stack_bottom); 30378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (flags()->verbosity) 30478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("MemorySanitizer init done\n"); 30578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov msan_init_is_running = 0; 30678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov msan_inited = 1; 30778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 30878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 30978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_set_exit_code(int exit_code) { 31078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov flags()->exit_code = exit_code; 31178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 31278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 313bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanovvoid __msan_set_keep_going(int keep_going) { 314bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov flags()->keep_going = keep_going; 315bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov} 316bb881c736eff073a84cc640d431ae1e58a5e07d4Evgeniy Stepanov 31778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_set_expect_umr(int expect_umr) { 31878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (expect_umr) { 31978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov msan_expected_umr_found = 0; 32078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } else if (!msan_expected_umr_found) { 32178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov GET_CALLER_PC_BP_SP; 32278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov (void)sp; 323db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov StackTrace stack; 32458b52b5efb7641b27c1728be0946889f335d83e1Evgeniy Stepanov GetStackTrace(&stack, kStackTraceMax, pc, bp, 3250b4bf4d72be10ba114c9b1f73aca45acd0e44ddcSergey Matveev common_flags()->fast_unwind_on_fatal); 326db010dae23962ab6089ad1e97af176b7215cb35cEvgeniy Stepanov ReportExpectedUMRNotFound(&stack); 32778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Die(); 32878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 32978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov msan_expect_umr = expect_umr; 33078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 33178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 33278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_print_shadow(const void *x, uptr size) { 33378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov unsigned char *s = (unsigned char*)MEM_TO_SHADOW(x); 33478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov u32 *o = (u32*)MEM_TO_ORIGIN(x); 33578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov for (uptr i = 0; i < size; i++) { 33678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("%x%x ", s[i] >> 4, s[i] & 0xf); 33778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 33878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("\n"); 339b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov if (__msan_get_track_origins()) { 34078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov for (uptr i = 0; i < size / 4; i++) { 34178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf(" o: %x ", o[i]); 34278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 34378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("\n"); 34478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 34578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 34678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 34778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_print_param_shadow() { 34878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov for (int i = 0; i < 16; i++) { 34978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("#%d:%zx ", i, __msan_param_tls[i]); 35078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 35178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("\n"); 35278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 35378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 35478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovsptr __msan_test_shadow(const void *x, uptr size) { 35578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov unsigned char *s = (unsigned char*)MEM_TO_SHADOW((uptr)x); 35678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov for (uptr i = 0; i < size; ++i) 35778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (s[i]) 35878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return i; 35978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return -1; 36078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 36178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 36278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovint __msan_set_poison_in_malloc(int do_poison) { 36378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov int old = flags()->poison_in_malloc; 36478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov flags()->poison_in_malloc = do_poison; 36578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return old; 36678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 36778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 36878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovint __msan_has_dynamic_component() { 36978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return msan_running_under_dr; 37078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 37178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 37278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy StepanovNOINLINE 37378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_clear_on_return() { 37478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov __msan_param_tls[0] = 0; 37578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 37678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 37778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovstatic void* get_tls_base() { 37878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov u64 p; 37978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov asm("mov %%fs:0, %0" 38078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov : "=r"(p) ::); 38178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return (void*)p; 38278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 38378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 38478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovint __msan_get_retval_tls_offset() { 38578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // volatile here is needed to avoid UB, because the compiler thinks that we 38678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // are doing address arithmetics on unrelated pointers, and takes some 38778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // shortcuts 38878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov volatile sptr retval_tls_p = (sptr)&__msan_retval_tls; 38978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov volatile sptr tls_base_p = (sptr)get_tls_base(); 39078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return retval_tls_p - tls_base_p; 39178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 39278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 39378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovint __msan_get_param_tls_offset() { 39478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // volatile here is needed to avoid UB, because the compiler thinks that we 39578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // are doing address arithmetics on unrelated pointers, and takes some 39678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // shortcuts 39778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov volatile sptr param_tls_p = (sptr)&__msan_param_tls; 39878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov volatile sptr tls_base_p = (sptr)get_tls_base(); 39978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return param_tls_p - tls_base_p; 40078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 40178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 40211347bf5f008b5970f699241617381d95526d73dAlexey Samsonovvoid __msan_partial_poison(const void* data, void* shadow, uptr size) { 40378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size); 40478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 40578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 40678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_load_unpoisoned(void *src, uptr size, void *dst) { 40778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov internal_memcpy(dst, src, size); 40878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov __msan_unpoison(dst, size); 40978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 41078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 41111347bf5f008b5970f699241617381d95526d73dAlexey Samsonovvoid __msan_set_origin(const void *a, uptr size, u32 origin) { 41278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // Origin mapping is 4 bytes per 4 bytes of application memory. 41378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // Here we extend the range such that its left and right bounds are both 41478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // 4 byte aligned. 415b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov if (!__msan_get_track_origins()) return; 41678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov uptr x = MEM_TO_ORIGIN((uptr)a); 41778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov uptr beg = x & ~3UL; // align down. 41878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov uptr end = (x + size + 3) & ~3UL; // align up. 41978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov u64 origin64 = ((u64)origin << 32) | origin; 42078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // This is like memset, but the value is 32-bit. We unroll by 2 two write 42178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov // 64-bits at once. May want to unroll further to get 128-bit stores. 42278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (beg & 7ULL) { 42378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov *(u32*)beg = origin; 42478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov beg += 4; 42578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 42678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov for (uptr addr = beg; addr < (end & ~7UL); addr += 8) 42778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov *(u64*)addr = origin64; 42878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (end & 7ULL) 42978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov *(u32*)(end - 4) = origin; 43078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 43178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 43278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// 'descr' is created at compile time and contains '----' in the beginning. 43378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// When we see descr for the first time we replace '----' with a uniq id 43478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov// and set the origin to (id | (31-th bit)). 43578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovvoid __msan_set_alloca_origin(void *a, uptr size, const char *descr) { 43678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov static const u32 dash = '-'; 43778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov static const u32 first_timer = 43878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov dash + (dash << 8) + (dash << 16) + (dash << 24); 43978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov u32 *id_ptr = (u32*)descr; 44078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov bool print = false; // internal_strstr(descr + 4, "AllocaTOTest") != 0; 44178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov u32 id = *id_ptr; 44278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (id == first_timer) { 44378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov id = atomic_fetch_add(&NumStackOriginDescrs, 44478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 1, memory_order_relaxed); 44578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov *id_ptr = id; 44678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov CHECK_LT(id, kNumStackOriginDescrs); 44778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov StackOriginDescr[id] = descr + 4; 44878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (print) 44978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("First time: id=%d %s \n", id, descr + 4); 45078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov } 45178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov id |= 1U << 31; 45278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if (print) 45378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov Printf("__msan_set_alloca_origin: descr=%s id=%x\n", descr + 4, id); 45478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov __msan_set_origin(a, size, id); 45578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 45678c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 45778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanovconst char *__msan_get_origin_descr_if_stack(u32 id) { 45878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov if ((id >> 31) == 0) return 0; 45978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov id &= (1U << 31) - 1; 46078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov CHECK_LT(id, kNumStackOriginDescrs); 46178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return StackOriginDescr[id]; 46278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 46378c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 46478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 46511347bf5f008b5970f699241617381d95526d73dAlexey Samsonovu32 __msan_get_origin(const void *a) { 466b36779d6e9c55e97b2258fe30e8e02c416b14ddaEvgeniy Stepanov if (!__msan_get_track_origins()) return 0; 46778c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov uptr x = (uptr)a; 46878c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov uptr aligned = x & ~3ULL; 46978c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov uptr origin_ptr = MEM_TO_ORIGIN(aligned); 47078c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return *(u32*)origin_ptr; 47178c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 47278c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov 47312c46937db2a5ab9237ce314c3f3a83636e8a575Evgeniy Stepanovu32 __msan_get_umr_origin() { 47478c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov return __msan_origin_tls; 47578c56c3c407d2c92825c86e6af7a0230d6019a1cEvgeniy Stepanov} 47670c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany 4772e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanovu16 __sanitizer_unaligned_load16(const uu16 *p) { 4782e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov __msan_retval_tls[0] = *(uu16 *)MEM_TO_SHADOW((uptr)p); 4792e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov return *p; 480f43f6026dc9374e657fb6300840b18ead6347b74Evgeniy Stepanov} 4812e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanovu32 __sanitizer_unaligned_load32(const uu32 *p) { 4822e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov __msan_retval_tls[0] = *(uu32 *)MEM_TO_SHADOW((uptr)p); 4832e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov return *p; 484f43f6026dc9374e657fb6300840b18ead6347b74Evgeniy Stepanov} 4852e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanovu64 __sanitizer_unaligned_load64(const uu64 *p) { 4862e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov __msan_retval_tls[0] = *(uu64 *)MEM_TO_SHADOW((uptr)p); 4872e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov return *p; 488f43f6026dc9374e657fb6300840b18ead6347b74Evgeniy Stepanov} 4892e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanovvoid __sanitizer_unaligned_store16(uu16 *p, u16 x) { 4902e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov *(uu16 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1]; 4912e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov *p = x; 492f43f6026dc9374e657fb6300840b18ead6347b74Evgeniy Stepanov} 4932e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanovvoid __sanitizer_unaligned_store32(uu32 *p, u32 x) { 4942e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov *(uu32 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1]; 4952e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov *p = x; 496f43f6026dc9374e657fb6300840b18ead6347b74Evgeniy Stepanov} 4972e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanovvoid __sanitizer_unaligned_store64(uu64 *p, u64 x) { 4982e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov *(uu64 *)MEM_TO_SHADOW((uptr)p) = __msan_param_tls[1]; 4992e9ffcbc2184f308881fc04ce0799c557b7e5b0fEvgeniy Stepanov *p = x; 500f43f6026dc9374e657fb6300840b18ead6347b74Evgeniy Stepanov} 501f43f6026dc9374e657fb6300840b18ead6347b74Evgeniy Stepanov 50270c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany#if !SANITIZER_SUPPORTS_WEAK_HOOKS 50370c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryanyextern "C" { 50470c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya SerebryanySANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE 50570c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryanyconst char* __msan_default_options() { return ""; } 50670c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany} // extern "C" 50770c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany#endif 50870c6e3fb6dfddb9c4d26ac133beb5f53b71e47d9Kostya Serebryany 509