1 1.1 kamil //===-- msan.cc -----------------------------------------------------------===// 2 1.1 kamil // 3 1.1 kamil // The LLVM Compiler Infrastructure 4 1.1 kamil // 5 1.1 kamil // This file is distributed under the University of Illinois Open Source 6 1.1 kamil // License. See LICENSE.TXT for details. 7 1.1 kamil // 8 1.1 kamil //===----------------------------------------------------------------------===// 9 1.1 kamil // 10 1.1 kamil // This file is a part of MemorySanitizer. 11 1.1 kamil // 12 1.1 kamil // MemorySanitizer runtime. 13 1.1 kamil //===----------------------------------------------------------------------===// 14 1.1 kamil 15 1.1 kamil #include "msan.h" 16 1.1 kamil #include "msan_chained_origin_depot.h" 17 1.1 kamil #include "msan_origin.h" 18 1.1 kamil #include "msan_report.h" 19 1.1 kamil #include "msan_thread.h" 20 1.1 kamil #include "msan_poisoning.h" 21 1.1 kamil #include "sanitizer_common/sanitizer_atomic.h" 22 1.1 kamil #include "sanitizer_common/sanitizer_common.h" 23 1.1 kamil #include "sanitizer_common/sanitizer_flags.h" 24 1.1 kamil #include "sanitizer_common/sanitizer_flag_parser.h" 25 1.1 kamil #include "sanitizer_common/sanitizer_libc.h" 26 1.1 kamil #include "sanitizer_common/sanitizer_procmaps.h" 27 1.1 kamil #include "sanitizer_common/sanitizer_stacktrace.h" 28 1.1 kamil #include "sanitizer_common/sanitizer_symbolizer.h" 29 1.1 kamil #include "sanitizer_common/sanitizer_stackdepot.h" 30 1.1 kamil #include "ubsan/ubsan_flags.h" 31 1.1 kamil #include "ubsan/ubsan_init.h" 32 1.1 kamil 33 1.1 kamil // ACHTUNG! No system header includes in this file. 34 1.1 kamil 35 1.1 kamil using namespace __sanitizer; 36 1.1 kamil 37 1.1 kamil // Globals. 38 1.1 kamil static THREADLOCAL int msan_expect_umr = 0; 39 1.1 kamil static THREADLOCAL int msan_expected_umr_found = 0; 40 1.1 kamil 41 1.1 kamil // Function argument shadow. Each argument starts at the next available 8-byte 42 1.1 kamil // aligned address. 43 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 44 1.1 kamil THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSize / sizeof(u64)]; 45 1.1 kamil 46 1.1 kamil // Function argument origin. Each argument starts at the same offset as the 47 1.1 kamil // corresponding shadow in (__msan_param_tls). Slightly weird, but changing this 48 1.1 kamil // would break compatibility with older prebuilt binaries. 49 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 50 1.1 kamil THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSize / sizeof(u32)]; 51 1.1 kamil 52 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 53 1.1 kamil THREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSize / sizeof(u64)]; 54 1.1 kamil 55 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 56 1.1 kamil THREADLOCAL u32 __msan_retval_origin_tls; 57 1.1 kamil 58 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 59 1.1 kamil ALIGNED(16) THREADLOCAL u64 __msan_va_arg_tls[kMsanParamTlsSize / sizeof(u64)]; 60 1.1 kamil 61 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 62 1.1 kamil ALIGNED(16) 63 1.1 kamil THREADLOCAL u32 __msan_va_arg_origin_tls[kMsanParamTlsSize / sizeof(u32)]; 64 1.1 kamil 65 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 66 1.1 kamil THREADLOCAL u64 __msan_va_arg_overflow_size_tls; 67 1.1 kamil 68 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 69 1.1 kamil THREADLOCAL u32 __msan_origin_tls; 70 1.1 kamil 71 1.1 kamil static THREADLOCAL int is_in_symbolizer; 72 1.1 kamil 73 1.1 kamil extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins; 74 1.1 kamil 75 1.1 kamil int __msan_get_track_origins() { 76 1.1 kamil return &__msan_track_origins ? __msan_track_origins : 0; 77 1.1 kamil } 78 1.1 kamil 79 1.1 kamil extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going; 80 1.1 kamil 81 1.1 kamil namespace __msan { 82 1.1 kamil 83 1.1 kamil void EnterSymbolizer() { ++is_in_symbolizer; } 84 1.1 kamil void ExitSymbolizer() { --is_in_symbolizer; } 85 1.1 kamil bool IsInSymbolizer() { return is_in_symbolizer; } 86 1.1 kamil 87 1.1 kamil static Flags msan_flags; 88 1.1 kamil 89 1.1 kamil Flags *flags() { 90 1.1 kamil return &msan_flags; 91 1.1 kamil } 92 1.1 kamil 93 1.1 kamil int msan_inited = 0; 94 1.1 kamil bool msan_init_is_running; 95 1.1 kamil 96 1.1 kamil int msan_report_count = 0; 97 1.1 kamil 98 1.1 kamil // Array of stack origins. 99 1.1 kamil // FIXME: make it resizable. 100 1.1 kamil static const uptr kNumStackOriginDescrs = 1024 * 1024; 101 1.1 kamil static const char *StackOriginDescr[kNumStackOriginDescrs]; 102 1.1 kamil static uptr StackOriginPC[kNumStackOriginDescrs]; 103 1.1 kamil static atomic_uint32_t NumStackOriginDescrs; 104 1.1 kamil 105 1.1 kamil void Flags::SetDefaults() { 106 1.1 kamil #define MSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 107 1.1 kamil #include "msan_flags.inc" 108 1.1 kamil #undef MSAN_FLAG 109 1.1 kamil } 110 1.1 kamil 111 1.1 kamil // keep_going is an old name for halt_on_error, 112 1.1 kamil // and it has inverse meaning. 113 1.1 kamil class FlagHandlerKeepGoing : public FlagHandlerBase { 114 1.1 kamil bool *halt_on_error_; 115 1.1 kamil 116 1.1 kamil public: 117 1.1 kamil explicit FlagHandlerKeepGoing(bool *halt_on_error) 118 1.1 kamil : halt_on_error_(halt_on_error) {} 119 1.1 kamil bool Parse(const char *value) final { 120 1.1 kamil bool tmp; 121 1.1 kamil FlagHandler<bool> h(&tmp); 122 1.1 kamil if (!h.Parse(value)) return false; 123 1.1 kamil *halt_on_error_ = !tmp; 124 1.1 kamil return true; 125 1.1 kamil } 126 1.1 kamil }; 127 1.1 kamil 128 1.1 kamil static void RegisterMsanFlags(FlagParser *parser, Flags *f) { 129 1.1 kamil #define MSAN_FLAG(Type, Name, DefaultValue, Description) \ 130 1.1 kamil RegisterFlag(parser, #Name, Description, &f->Name); 131 1.1 kamil #include "msan_flags.inc" 132 1.1 kamil #undef MSAN_FLAG 133 1.1 kamil 134 1.1 kamil FlagHandlerKeepGoing *fh_keep_going = new (FlagParser::Alloc) // NOLINT 135 1.1 kamil FlagHandlerKeepGoing(&f->halt_on_error); 136 1.1 kamil parser->RegisterHandler("keep_going", fh_keep_going, 137 1.1 kamil "deprecated, use halt_on_error"); 138 1.1 kamil } 139 1.1 kamil 140 1.1 kamil static void InitializeFlags() { 141 1.1 kamil SetCommonFlagsDefaults(); 142 1.1 kamil { 143 1.1 kamil CommonFlags cf; 144 1.1 kamil cf.CopyFrom(*common_flags()); 145 1.1 kamil cf.external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); 146 1.1 kamil cf.malloc_context_size = 20; 147 1.1 kamil cf.handle_ioctl = true; 148 1.1 kamil // FIXME: test and enable. 149 1.1 kamil cf.check_printf = false; 150 1.1 kamil cf.intercept_tls_get_addr = true; 151 1.1 kamil cf.exitcode = 77; 152 1.1 kamil OverrideCommonFlags(cf); 153 1.1 kamil } 154 1.1 kamil 155 1.1 kamil Flags *f = flags(); 156 1.1 kamil f->SetDefaults(); 157 1.1 kamil 158 1.1 kamil FlagParser parser; 159 1.1 kamil RegisterMsanFlags(&parser, f); 160 1.1 kamil RegisterCommonFlags(&parser); 161 1.1 kamil 162 1.1 kamil #if MSAN_CONTAINS_UBSAN 163 1.1 kamil __ubsan::Flags *uf = __ubsan::flags(); 164 1.1 kamil uf->SetDefaults(); 165 1.1 kamil 166 1.1 kamil FlagParser ubsan_parser; 167 1.1 kamil __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); 168 1.1 kamil RegisterCommonFlags(&ubsan_parser); 169 1.1 kamil #endif 170 1.1 kamil 171 1.1 kamil // Override from user-specified string. 172 1.1 kamil if (__msan_default_options) 173 1.1 kamil parser.ParseString(__msan_default_options()); 174 1.1 kamil #if MSAN_CONTAINS_UBSAN 175 1.1 kamil const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions(); 176 1.1 kamil ubsan_parser.ParseString(ubsan_default_options); 177 1.1 kamil #endif 178 1.1 kamil 179 1.1 kamil const char *msan_options = GetEnv("MSAN_OPTIONS"); 180 1.1 kamil parser.ParseString(msan_options); 181 1.1 kamil #if MSAN_CONTAINS_UBSAN 182 1.1 kamil ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); 183 1.1 kamil #endif 184 1.1 kamil VPrintf(1, "MSAN_OPTIONS: %s\n", msan_options ? msan_options : "<empty>"); 185 1.1 kamil 186 1.1 kamil InitializeCommonFlags(); 187 1.1 kamil 188 1.1 kamil if (Verbosity()) ReportUnrecognizedFlags(); 189 1.1 kamil 190 1.1 kamil if (common_flags()->help) parser.PrintFlagDescriptions(); 191 1.1 kamil 192 1.1 kamil // Check if deprecated exit_code MSan flag is set. 193 1.1 kamil if (f->exit_code != -1) { 194 1.1 kamil if (Verbosity()) 195 1.1 kamil Printf("MSAN_OPTIONS=exit_code is deprecated! " 196 1.1 kamil "Please use MSAN_OPTIONS=exitcode instead.\n"); 197 1.1 kamil CommonFlags cf; 198 1.1 kamil cf.CopyFrom(*common_flags()); 199 1.1 kamil cf.exitcode = f->exit_code; 200 1.1 kamil OverrideCommonFlags(cf); 201 1.1 kamil } 202 1.1 kamil 203 1.1 kamil // Check flag values: 204 1.1 kamil if (f->origin_history_size < 0 || 205 1.1 kamil f->origin_history_size > Origin::kMaxDepth) { 206 1.1 kamil Printf( 207 1.1 kamil "Origin history size invalid: %d. Must be 0 (unlimited) or in [1, %d] " 208 1.1 kamil "range.\n", 209 1.1 kamil f->origin_history_size, Origin::kMaxDepth); 210 1.1 kamil Die(); 211 1.1 kamil } 212 1.1 kamil // Limiting to kStackDepotMaxUseCount / 2 to avoid overflow in 213 1.1 kamil // StackDepotHandle::inc_use_count_unsafe. 214 1.1 kamil if (f->origin_history_per_stack_limit < 0 || 215 1.1 kamil f->origin_history_per_stack_limit > kStackDepotMaxUseCount / 2) { 216 1.1 kamil Printf( 217 1.1 kamil "Origin per-stack limit invalid: %d. Must be 0 (unlimited) or in [1, " 218 1.1 kamil "%d] range.\n", 219 1.1 kamil f->origin_history_per_stack_limit, kStackDepotMaxUseCount / 2); 220 1.1 kamil Die(); 221 1.1 kamil } 222 1.1 kamil if (f->store_context_size < 1) f->store_context_size = 1; 223 1.1 kamil } 224 1.1 kamil 225 1.1 kamil void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp, 226 1.1 kamil void *context, bool request_fast_unwind) { 227 1.1 kamil MsanThread *t = GetCurrentThread(); 228 1.1 kamil if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) { 229 1.1 kamil // Block reports from our interceptors during _Unwind_Backtrace. 230 1.1 kamil SymbolizerScope sym_scope; 231 1.1 kamil return stack->Unwind(max_s, pc, bp, context, 0, 0, request_fast_unwind); 232 1.1 kamil } 233 1.1 kamil stack->Unwind(max_s, pc, bp, context, t->stack_top(), t->stack_bottom(), 234 1.1 kamil request_fast_unwind); 235 1.1 kamil } 236 1.1 kamil 237 1.1 kamil void PrintWarning(uptr pc, uptr bp) { 238 1.1 kamil PrintWarningWithOrigin(pc, bp, __msan_origin_tls); 239 1.1 kamil } 240 1.1 kamil 241 1.1 kamil void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) { 242 1.1 kamil if (msan_expect_umr) { 243 1.1 kamil // Printf("Expected UMR\n"); 244 1.1 kamil __msan_origin_tls = origin; 245 1.1 kamil msan_expected_umr_found = 1; 246 1.1 kamil return; 247 1.1 kamil } 248 1.1 kamil 249 1.1 kamil ++msan_report_count; 250 1.1 kamil 251 1.1 kamil GET_FATAL_STACK_TRACE_PC_BP(pc, bp); 252 1.1 kamil 253 1.1 kamil u32 report_origin = 254 1.1 kamil (__msan_get_track_origins() && Origin::isValidId(origin)) ? origin : 0; 255 1.1 kamil ReportUMR(&stack, report_origin); 256 1.1 kamil 257 1.1 kamil if (__msan_get_track_origins() && !Origin::isValidId(origin)) { 258 1.1 kamil Printf( 259 1.1 kamil " ORIGIN: invalid (%x). Might be a bug in MemorySanitizer origin " 260 1.1 kamil "tracking.\n This could still be a bug in your code, too!\n", 261 1.1 kamil origin); 262 1.1 kamil } 263 1.1 kamil } 264 1.1 kamil 265 1.1 kamil void UnpoisonParam(uptr n) { 266 1.1 kamil internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls)); 267 1.1 kamil } 268 1.1 kamil 269 1.1 kamil // Backup MSan runtime TLS state. 270 1.1 kamil // Implementation must be async-signal-safe. 271 1.1 kamil // Instances of this class may live on the signal handler stack, and data size 272 1.1 kamil // may be an issue. 273 1.1 kamil void ScopedThreadLocalStateBackup::Backup() { 274 1.1 kamil va_arg_overflow_size_tls = __msan_va_arg_overflow_size_tls; 275 1.1 kamil } 276 1.1 kamil 277 1.1 kamil void ScopedThreadLocalStateBackup::Restore() { 278 1.1 kamil // A lame implementation that only keeps essential state and resets the rest. 279 1.1 kamil __msan_va_arg_overflow_size_tls = va_arg_overflow_size_tls; 280 1.1 kamil 281 1.1 kamil internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls)); 282 1.1 kamil internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls)); 283 1.1 kamil internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls)); 284 1.1 kamil internal_memset(__msan_va_arg_origin_tls, 0, 285 1.1 kamil sizeof(__msan_va_arg_origin_tls)); 286 1.1 kamil 287 1.1 kamil if (__msan_get_track_origins()) { 288 1.1 kamil internal_memset(&__msan_retval_origin_tls, 0, 289 1.1 kamil sizeof(__msan_retval_origin_tls)); 290 1.1 kamil internal_memset(__msan_param_origin_tls, 0, 291 1.1 kamil sizeof(__msan_param_origin_tls)); 292 1.1 kamil } 293 1.1 kamil } 294 1.1 kamil 295 1.1 kamil void UnpoisonThreadLocalState() { 296 1.1 kamil } 297 1.1 kamil 298 1.1 kamil const char *GetStackOriginDescr(u32 id, uptr *pc) { 299 1.1 kamil CHECK_LT(id, kNumStackOriginDescrs); 300 1.1 kamil if (pc) *pc = StackOriginPC[id]; 301 1.1 kamil return StackOriginDescr[id]; 302 1.1 kamil } 303 1.1 kamil 304 1.1 kamil u32 ChainOrigin(u32 id, StackTrace *stack) { 305 1.1 kamil MsanThread *t = GetCurrentThread(); 306 1.1 kamil if (t && t->InSignalHandler()) 307 1.1 kamil return id; 308 1.1 kamil 309 1.1 kamil Origin o = Origin::FromRawId(id); 310 1.1 kamil stack->tag = StackTrace::TAG_UNKNOWN; 311 1.1 kamil Origin chained = Origin::CreateChainedOrigin(o, stack); 312 1.1 kamil return chained.raw_id(); 313 1.1 kamil } 314 1.1 kamil 315 1.1 kamil } // namespace __msan 316 1.1 kamil 317 1.1 kamil // Interface. 318 1.1 kamil 319 1.1 kamil using namespace __msan; 320 1.1 kamil 321 1.1 kamil #define MSAN_MAYBE_WARNING(type, size) \ 322 1.1 kamil void __msan_maybe_warning_##size(type s, u32 o) { \ 323 1.1 kamil GET_CALLER_PC_BP_SP; \ 324 1.1 kamil (void) sp; \ 325 1.1 kamil if (UNLIKELY(s)) { \ 326 1.1 kamil PrintWarningWithOrigin(pc, bp, o); \ 327 1.1 kamil if (__msan::flags()->halt_on_error) { \ 328 1.1 kamil Printf("Exiting\n"); \ 329 1.1 kamil Die(); \ 330 1.1 kamil } \ 331 1.1 kamil } \ 332 1.1 kamil } 333 1.1 kamil 334 1.1 kamil MSAN_MAYBE_WARNING(u8, 1) 335 1.1 kamil MSAN_MAYBE_WARNING(u16, 2) 336 1.1 kamil MSAN_MAYBE_WARNING(u32, 4) 337 1.1 kamil MSAN_MAYBE_WARNING(u64, 8) 338 1.1 kamil 339 1.1 kamil #define MSAN_MAYBE_STORE_ORIGIN(type, size) \ 340 1.1 kamil void __msan_maybe_store_origin_##size(type s, void *p, u32 o) { \ 341 1.1 kamil if (UNLIKELY(s)) { \ 342 1.1 kamil if (__msan_get_track_origins() > 1) { \ 343 1.1 kamil GET_CALLER_PC_BP_SP; \ 344 1.1 kamil (void) sp; \ 345 1.1 kamil GET_STORE_STACK_TRACE_PC_BP(pc, bp); \ 346 1.1 kamil o = ChainOrigin(o, &stack); \ 347 1.1 kamil } \ 348 1.1 kamil *(u32 *)MEM_TO_ORIGIN((uptr)p & ~3UL) = o; \ 349 1.1 kamil } \ 350 1.1 kamil } 351 1.1 kamil 352 1.1 kamil MSAN_MAYBE_STORE_ORIGIN(u8, 1) 353 1.1 kamil MSAN_MAYBE_STORE_ORIGIN(u16, 2) 354 1.1 kamil MSAN_MAYBE_STORE_ORIGIN(u32, 4) 355 1.1 kamil MSAN_MAYBE_STORE_ORIGIN(u64, 8) 356 1.1 kamil 357 1.1 kamil void __msan_warning() { 358 1.1 kamil GET_CALLER_PC_BP_SP; 359 1.1 kamil (void)sp; 360 1.1 kamil PrintWarning(pc, bp); 361 1.1 kamil if (__msan::flags()->halt_on_error) { 362 1.1 kamil if (__msan::flags()->print_stats) 363 1.1 kamil ReportStats(); 364 1.1 kamil Printf("Exiting\n"); 365 1.1 kamil Die(); 366 1.1 kamil } 367 1.1 kamil } 368 1.1 kamil 369 1.1 kamil void __msan_warning_noreturn() { 370 1.1 kamil GET_CALLER_PC_BP_SP; 371 1.1 kamil (void)sp; 372 1.1 kamil PrintWarning(pc, bp); 373 1.1 kamil if (__msan::flags()->print_stats) 374 1.1 kamil ReportStats(); 375 1.1 kamil Printf("Exiting\n"); 376 1.1 kamil Die(); 377 1.1 kamil } 378 1.1 kamil 379 1.1 kamil static void OnStackUnwind(const SignalContext &sig, const void *, 380 1.1 kamil BufferedStackTrace *stack) { 381 1.1 kamil GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, 382 1.1 kamil common_flags()->fast_unwind_on_fatal); 383 1.1 kamil } 384 1.1 kamil 385 1.1 kamil static void MsanOnDeadlySignal(int signo, void *siginfo, void *context) { 386 1.1 kamil HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr); 387 1.1 kamil } 388 1.1 kamil 389 1.1 kamil static void MsanCheckFailed(const char *file, int line, const char *cond, 390 1.1 kamil u64 v1, u64 v2) { 391 1.1 kamil Report("MemorySanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file, 392 1.1 kamil line, cond, (uptr)v1, (uptr)v2); 393 1.1 kamil PRINT_CURRENT_STACK_CHECK(); 394 1.1 kamil Die(); 395 1.1 kamil } 396 1.1 kamil 397 1.1 kamil void __msan_init() { 398 1.1 kamil CHECK(!msan_init_is_running); 399 1.1 kamil if (msan_inited) return; 400 1.1 kamil msan_init_is_running = 1; 401 1.1 kamil SanitizerToolName = "MemorySanitizer"; 402 1.1 kamil 403 1.1 kamil AvoidCVE_2016_2143(); 404 1.1 kamil 405 1.1 kamil CacheBinaryName(); 406 1.1 kamil CheckASLR(); 407 1.1 kamil InitializeFlags(); 408 1.1 kamil 409 1.1 kamil // Install tool-specific callbacks in sanitizer_common. 410 1.1 kamil SetCheckFailedCallback(MsanCheckFailed); 411 1.1 kamil 412 1.1 kamil __sanitizer_set_report_path(common_flags()->log_path); 413 1.1 kamil 414 1.1 kamil InitializeInterceptors(); 415 1.1 kamil InitTlsSize(); 416 1.1 kamil InstallDeadlySignalHandlers(MsanOnDeadlySignal); 417 1.1 kamil InstallAtExitHandler(); // Needs __cxa_atexit interceptor. 418 1.1 kamil 419 1.1 kamil DisableCoreDumperIfNecessary(); 420 1.1 kamil if (StackSizeIsUnlimited()) { 421 1.1 kamil VPrintf(1, "Unlimited stack, doing reexec\n"); 422 1.1 kamil // A reasonably large stack size. It is bigger than the usual 8Mb, because, 423 1.1 kamil // well, the program could have been run with unlimited stack for a reason. 424 1.1 kamil SetStackSizeLimitInBytes(32 * 1024 * 1024); 425 1.1 kamil ReExec(); 426 1.1 kamil } 427 1.1 kamil 428 1.1 kamil __msan_clear_on_return(); 429 1.1 kamil if (__msan_get_track_origins()) 430 1.1 kamil VPrintf(1, "msan_track_origins\n"); 431 1.1 kamil if (!InitShadow(__msan_get_track_origins())) { 432 1.1 kamil Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n"); 433 1.1 kamil Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); 434 1.1 kamil Printf("FATAL: Disabling ASLR is known to cause this error.\n"); 435 1.1 kamil Printf("FATAL: If running under GDB, try " 436 1.1 kamil "'set disable-randomization off'.\n"); 437 1.1 kamil DumpProcessMap(); 438 1.1 kamil Die(); 439 1.1 kamil } 440 1.1 kamil 441 1.1 kamil Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); 442 1.1 kamil 443 1.1 kamil InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); 444 1.1 kamil 445 1.1 kamil MsanTSDInit(MsanTSDDtor); 446 1.1 kamil 447 1.1 kamil MsanAllocatorInit(); 448 1.1 kamil 449 1.1 kamil MsanThread *main_thread = MsanThread::Create(nullptr, nullptr); 450 1.1 kamil SetCurrentThread(main_thread); 451 1.1 kamil main_thread->ThreadStart(); 452 1.1 kamil 453 1.1 kamil #if MSAN_CONTAINS_UBSAN 454 1.1 kamil __ubsan::InitAsPlugin(); 455 1.1 kamil #endif 456 1.1 kamil 457 1.1 kamil VPrintf(1, "MemorySanitizer init done\n"); 458 1.1 kamil 459 1.1 kamil msan_init_is_running = 0; 460 1.1 kamil msan_inited = 1; 461 1.1 kamil } 462 1.1 kamil 463 1.1 kamil void __msan_set_keep_going(int keep_going) { 464 1.1 kamil flags()->halt_on_error = !keep_going; 465 1.1 kamil } 466 1.1 kamil 467 1.1 kamil void __msan_set_expect_umr(int expect_umr) { 468 1.1 kamil if (expect_umr) { 469 1.1 kamil msan_expected_umr_found = 0; 470 1.1 kamil } else if (!msan_expected_umr_found) { 471 1.1 kamil GET_CALLER_PC_BP_SP; 472 1.1 kamil (void)sp; 473 1.1 kamil GET_FATAL_STACK_TRACE_PC_BP(pc, bp); 474 1.1 kamil ReportExpectedUMRNotFound(&stack); 475 1.1 kamil Die(); 476 1.1 kamil } 477 1.1 kamil msan_expect_umr = expect_umr; 478 1.1 kamil } 479 1.1 kamil 480 1.1 kamil void __msan_print_shadow(const void *x, uptr size) { 481 1.1 kamil if (!MEM_IS_APP(x)) { 482 1.1 kamil Printf("Not a valid application address: %p\n", x); 483 1.1 kamil return; 484 1.1 kamil } 485 1.1 kamil 486 1.1 kamil DescribeMemoryRange(x, size); 487 1.1 kamil } 488 1.1 kamil 489 1.1 kamil void __msan_dump_shadow(const void *x, uptr size) { 490 1.1 kamil if (!MEM_IS_APP(x)) { 491 1.1 kamil Printf("Not a valid application address: %p\n", x); 492 1.1 kamil return; 493 1.1 kamil } 494 1.1 kamil 495 1.1 kamil unsigned char *s = (unsigned char*)MEM_TO_SHADOW(x); 496 1.1 kamil for (uptr i = 0; i < size; i++) 497 1.1 kamil Printf("%x%x ", s[i] >> 4, s[i] & 0xf); 498 1.1 kamil Printf("\n"); 499 1.1 kamil } 500 1.1 kamil 501 1.1 kamil sptr __msan_test_shadow(const void *x, uptr size) { 502 1.1 kamil if (!MEM_IS_APP(x)) return -1; 503 1.1 kamil unsigned char *s = (unsigned char *)MEM_TO_SHADOW((uptr)x); 504 1.1 kamil for (uptr i = 0; i < size; ++i) 505 1.1 kamil if (s[i]) 506 1.1 kamil return i; 507 1.1 kamil return -1; 508 1.1 kamil } 509 1.1 kamil 510 1.1 kamil void __msan_check_mem_is_initialized(const void *x, uptr size) { 511 1.1 kamil if (!__msan::flags()->report_umrs) return; 512 1.1 kamil sptr offset = __msan_test_shadow(x, size); 513 1.1 kamil if (offset < 0) 514 1.1 kamil return; 515 1.1 kamil 516 1.1 kamil GET_CALLER_PC_BP_SP; 517 1.1 kamil (void)sp; 518 1.1 kamil ReportUMRInsideAddressRange(__func__, x, size, offset); 519 1.1 kamil __msan::PrintWarningWithOrigin(pc, bp, 520 1.1 kamil __msan_get_origin(((const char *)x) + offset)); 521 1.1 kamil if (__msan::flags()->halt_on_error) { 522 1.1 kamil Printf("Exiting\n"); 523 1.1 kamil Die(); 524 1.1 kamil } 525 1.1 kamil } 526 1.1 kamil 527 1.1 kamil int __msan_set_poison_in_malloc(int do_poison) { 528 1.1 kamil int old = flags()->poison_in_malloc; 529 1.1 kamil flags()->poison_in_malloc = do_poison; 530 1.1 kamil return old; 531 1.1 kamil } 532 1.1 kamil 533 1.1 kamil int __msan_has_dynamic_component() { return false; } 534 1.1 kamil 535 1.1 kamil NOINLINE 536 1.1 kamil void __msan_clear_on_return() { 537 1.1 kamil __msan_param_tls[0] = 0; 538 1.1 kamil } 539 1.1 kamil 540 1.1 kamil void __msan_partial_poison(const void* data, void* shadow, uptr size) { 541 1.1 kamil internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size); 542 1.1 kamil } 543 1.1 kamil 544 1.1 kamil void __msan_load_unpoisoned(const void *src, uptr size, void *dst) { 545 1.1 kamil internal_memcpy(dst, src, size); 546 1.1 kamil __msan_unpoison(dst, size); 547 1.1 kamil } 548 1.1 kamil 549 1.1 kamil void __msan_set_origin(const void *a, uptr size, u32 origin) { 550 1.1 kamil if (__msan_get_track_origins()) SetOrigin(a, size, origin); 551 1.1 kamil } 552 1.1 kamil 553 1.1 kamil // 'descr' is created at compile time and contains '----' in the beginning. 554 1.1 kamil // When we see descr for the first time we replace '----' with a uniq id 555 1.1 kamil // and set the origin to (id | (31-th bit)). 556 1.1 kamil void __msan_set_alloca_origin(void *a, uptr size, char *descr) { 557 1.1 kamil __msan_set_alloca_origin4(a, size, descr, 0); 558 1.1 kamil } 559 1.1 kamil 560 1.1 kamil void __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc) { 561 1.1 kamil static const u32 dash = '-'; 562 1.1 kamil static const u32 first_timer = 563 1.1 kamil dash + (dash << 8) + (dash << 16) + (dash << 24); 564 1.1 kamil u32 *id_ptr = (u32*)descr; 565 1.1 kamil bool print = false; // internal_strstr(descr + 4, "AllocaTOTest") != 0; 566 1.1 kamil u32 id = *id_ptr; 567 1.1 kamil if (id == first_timer) { 568 1.1 kamil u32 idx = atomic_fetch_add(&NumStackOriginDescrs, 1, memory_order_relaxed); 569 1.1 kamil CHECK_LT(idx, kNumStackOriginDescrs); 570 1.1 kamil StackOriginDescr[idx] = descr + 4; 571 1.1 kamil #if SANITIZER_PPC64V1 572 1.1 kamil // On PowerPC64 ELFv1, the address of a function actually points to a 573 1.1 kamil // three-doubleword data structure with the first field containing 574 1.1 kamil // the address of the function's code. 575 1.1 kamil if (pc) 576 1.1 kamil pc = *reinterpret_cast<uptr*>(pc); 577 1.1 kamil #endif 578 1.1 kamil StackOriginPC[idx] = pc; 579 1.1 kamil id = Origin::CreateStackOrigin(idx).raw_id(); 580 1.1 kamil *id_ptr = id; 581 1.1 kamil if (print) 582 1.1 kamil Printf("First time: idx=%d id=%d %s %p \n", idx, id, descr + 4, pc); 583 1.1 kamil } 584 1.1 kamil if (print) 585 1.1 kamil Printf("__msan_set_alloca_origin: descr=%s id=%x\n", descr + 4, id); 586 1.1 kamil __msan_set_origin(a, size, id); 587 1.1 kamil } 588 1.1 kamil 589 1.1 kamil u32 __msan_chain_origin(u32 id) { 590 1.1 kamil GET_CALLER_PC_BP_SP; 591 1.1 kamil (void)sp; 592 1.1 kamil GET_STORE_STACK_TRACE_PC_BP(pc, bp); 593 1.1 kamil return ChainOrigin(id, &stack); 594 1.1 kamil } 595 1.1 kamil 596 1.1 kamil u32 __msan_get_origin(const void *a) { 597 1.1 kamil if (!__msan_get_track_origins()) return 0; 598 1.1 kamil uptr x = (uptr)a; 599 1.1 kamil uptr aligned = x & ~3ULL; 600 1.1 kamil uptr origin_ptr = MEM_TO_ORIGIN(aligned); 601 1.1 kamil return *(u32*)origin_ptr; 602 1.1 kamil } 603 1.1 kamil 604 1.1 kamil int __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id) { 605 1.1 kamil Origin o = Origin::FromRawId(this_id); 606 1.1 kamil while (o.raw_id() != prev_id && o.isChainedOrigin()) 607 1.1 kamil o = o.getNextChainedOrigin(nullptr); 608 1.1 kamil return o.raw_id() == prev_id; 609 1.1 kamil } 610 1.1 kamil 611 1.1 kamil u32 __msan_get_umr_origin() { 612 1.1 kamil return __msan_origin_tls; 613 1.1 kamil } 614 1.1 kamil 615 1.1 kamil u16 __sanitizer_unaligned_load16(const uu16 *p) { 616 1.1 kamil *(uu16 *)&__msan_retval_tls[0] = *(uu16 *)MEM_TO_SHADOW((uptr)p); 617 1.1 kamil if (__msan_get_track_origins()) 618 1.1 kamil __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); 619 1.1 kamil return *p; 620 1.1 kamil } 621 1.1 kamil u32 __sanitizer_unaligned_load32(const uu32 *p) { 622 1.1 kamil *(uu32 *)&__msan_retval_tls[0] = *(uu32 *)MEM_TO_SHADOW((uptr)p); 623 1.1 kamil if (__msan_get_track_origins()) 624 1.1 kamil __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); 625 1.1 kamil return *p; 626 1.1 kamil } 627 1.1 kamil u64 __sanitizer_unaligned_load64(const uu64 *p) { 628 1.1 kamil __msan_retval_tls[0] = *(uu64 *)MEM_TO_SHADOW((uptr)p); 629 1.1 kamil if (__msan_get_track_origins()) 630 1.1 kamil __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); 631 1.1 kamil return *p; 632 1.1 kamil } 633 1.1 kamil void __sanitizer_unaligned_store16(uu16 *p, u16 x) { 634 1.1 kamil u16 s = *(uu16 *)&__msan_param_tls[1]; 635 1.1 kamil *(uu16 *)MEM_TO_SHADOW((uptr)p) = s; 636 1.1 kamil if (s && __msan_get_track_origins()) 637 1.1 kamil if (uu32 o = __msan_param_origin_tls[2]) 638 1.1 kamil SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); 639 1.1 kamil *p = x; 640 1.1 kamil } 641 1.1 kamil void __sanitizer_unaligned_store32(uu32 *p, u32 x) { 642 1.1 kamil u32 s = *(uu32 *)&__msan_param_tls[1]; 643 1.1 kamil *(uu32 *)MEM_TO_SHADOW((uptr)p) = s; 644 1.1 kamil if (s && __msan_get_track_origins()) 645 1.1 kamil if (uu32 o = __msan_param_origin_tls[2]) 646 1.1 kamil SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); 647 1.1 kamil *p = x; 648 1.1 kamil } 649 1.1 kamil void __sanitizer_unaligned_store64(uu64 *p, u64 x) { 650 1.1 kamil u64 s = __msan_param_tls[1]; 651 1.1 kamil *(uu64 *)MEM_TO_SHADOW((uptr)p) = s; 652 1.1 kamil if (s && __msan_get_track_origins()) 653 1.1 kamil if (uu32 o = __msan_param_origin_tls[2]) 654 1.1 kamil SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); 655 1.1 kamil *p = x; 656 1.1 kamil } 657 1.1 kamil 658 1.1 kamil void __msan_set_death_callback(void (*callback)(void)) { 659 1.1 kamil SetUserDieCallback(callback); 660 1.1 kamil } 661 1.1 kamil 662 1.1 kamil #if !SANITIZER_SUPPORTS_WEAK_HOOKS 663 1.1 kamil extern "C" { 664 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 665 1.1 kamil const char* __msan_default_options() { return ""; } 666 1.1 kamil } // extern "C" 667 1.1 kamil #endif 668 1.1 kamil 669 1.1 kamil extern "C" { 670 1.1 kamil SANITIZER_INTERFACE_ATTRIBUTE 671 1.1 kamil void __sanitizer_print_stack_trace() { 672 1.1 kamil GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()); 673 1.1 kamil stack.Print(); 674 1.1 kamil } 675 1.1 kamil } // extern "C" 676