Path: blob/main/contrib/llvm-project/compiler-rt/lib/asan/asan_flags.cpp
35233 views
//===-- asan_flags.cpp ------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of AddressSanitizer, an address sanity checker.9//10// ASan flag parsing logic.11//===----------------------------------------------------------------------===//1213#include "asan_activation.h"14#include "asan_flags.h"15#include "asan_interface_internal.h"16#include "asan_stack.h"17#include "lsan/lsan_common.h"18#include "sanitizer_common/sanitizer_common.h"19#include "sanitizer_common/sanitizer_flags.h"20#include "sanitizer_common/sanitizer_flag_parser.h"21#include "ubsan/ubsan_flags.h"22#include "ubsan/ubsan_platform.h"2324namespace __asan {2526Flags asan_flags_dont_use_directly; // use via flags().2728static const char *MaybeUseAsanDefaultOptionsCompileDefinition() {29#ifdef ASAN_DEFAULT_OPTIONS30return SANITIZER_STRINGIFY(ASAN_DEFAULT_OPTIONS);31#else32return "";33#endif34}3536void Flags::SetDefaults() {37#define ASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;38#include "asan_flags.inc"39#undef ASAN_FLAG40}4142static void RegisterAsanFlags(FlagParser *parser, Flags *f) {43#define ASAN_FLAG(Type, Name, DefaultValue, Description) \44RegisterFlag(parser, #Name, Description, &f->Name);45#include "asan_flags.inc"46#undef ASAN_FLAG47}4849void InitializeFlags() {50// Set the default values and prepare for parsing ASan and common flags.51SetCommonFlagsDefaults();52{53CommonFlags cf;54cf.CopyFrom(*common_flags());55cf.detect_leaks = cf.detect_leaks && CAN_SANITIZE_LEAKS;56cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");57cf.malloc_context_size = kDefaultMallocContextSize;58cf.intercept_tls_get_addr = true;59cf.exitcode = 1;60OverrideCommonFlags(cf);61}62Flags *f = flags();63f->SetDefaults();6465FlagParser asan_parser;66RegisterAsanFlags(&asan_parser, f);67RegisterCommonFlags(&asan_parser);6869// Set the default values and prepare for parsing LSan and UBSan flags70// (which can also overwrite common flags).71#if CAN_SANITIZE_LEAKS72__lsan::Flags *lf = __lsan::flags();73lf->SetDefaults();7475FlagParser lsan_parser;76__lsan::RegisterLsanFlags(&lsan_parser, lf);77RegisterCommonFlags(&lsan_parser);78#endif7980#if CAN_SANITIZE_UB81__ubsan::Flags *uf = __ubsan::flags();82uf->SetDefaults();8384FlagParser ubsan_parser;85__ubsan::RegisterUbsanFlags(&ubsan_parser, uf);86RegisterCommonFlags(&ubsan_parser);87#endif8889if (SANITIZER_APPLE) {90// Support macOS MallocScribble and MallocPreScribble:91// <https://developer.apple.com/library/content/documentation/Performance/92// Conceptual/ManagingMemory/Articles/MallocDebug.html>93if (GetEnv("MallocScribble")) {94f->max_free_fill_size = 0x1000;95}96if (GetEnv("MallocPreScribble")) {97f->malloc_fill_byte = 0xaa;98}99}100101// Override from ASan compile definition.102const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();103asan_parser.ParseString(asan_compile_def);104105// Override from user-specified string.106const char *asan_default_options = __asan_default_options();107asan_parser.ParseString(asan_default_options);108#if CAN_SANITIZE_UB109const char *ubsan_default_options = __ubsan_default_options();110ubsan_parser.ParseString(ubsan_default_options);111#endif112#if CAN_SANITIZE_LEAKS113const char *lsan_default_options = __lsan_default_options();114lsan_parser.ParseString(lsan_default_options);115#endif116117// Override from command line.118asan_parser.ParseStringFromEnv("ASAN_OPTIONS");119#if CAN_SANITIZE_LEAKS120lsan_parser.ParseStringFromEnv("LSAN_OPTIONS");121#endif122#if CAN_SANITIZE_UB123ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");124#endif125126InitializeCommonFlags();127128// TODO(eugenis): dump all flags at verbosity>=2?129if (Verbosity()) ReportUnrecognizedFlags();130131if (common_flags()->help) {132// TODO(samsonov): print all of the flags (ASan, LSan, common).133asan_parser.PrintFlagDescriptions();134}135136// Flag validation:137if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {138Report("%s: detect_leaks is not supported on this platform.\n",139SanitizerToolName);140Die();141}142// Ensure that redzone is at least ASAN_SHADOW_GRANULARITY.143if (f->redzone < (int)ASAN_SHADOW_GRANULARITY)144f->redzone = ASAN_SHADOW_GRANULARITY;145// Make "strict_init_order" imply "check_initialization_order".146// TODO(samsonov): Use a single runtime flag for an init-order checker.147if (f->strict_init_order) {148f->check_initialization_order = true;149}150CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax);151CHECK_LE(f->min_uar_stack_size_log, f->max_uar_stack_size_log);152CHECK_GE(f->redzone, 16);153CHECK_GE(f->max_redzone, f->redzone);154CHECK_LE(f->max_redzone, 2048);155CHECK(IsPowerOfTwo(f->redzone));156CHECK(IsPowerOfTwo(f->max_redzone));157158// quarantine_size is deprecated but we still honor it.159// quarantine_size can not be used together with quarantine_size_mb.160if (f->quarantine_size >= 0 && f->quarantine_size_mb >= 0) {161Report("%s: please use either 'quarantine_size' (deprecated) or "162"quarantine_size_mb, but not both\n", SanitizerToolName);163Die();164}165if (f->quarantine_size >= 0)166f->quarantine_size_mb = f->quarantine_size >> 20;167if (f->quarantine_size_mb < 0) {168const int kDefaultQuarantineSizeMb =169(ASAN_LOW_MEMORY) ? 1UL << 4 : 1UL << 8;170f->quarantine_size_mb = kDefaultQuarantineSizeMb;171}172if (f->thread_local_quarantine_size_kb < 0) {173const u32 kDefaultThreadLocalQuarantineSizeKb =174// It is not advised to go lower than 64Kb, otherwise quarantine batches175// pushed from thread local quarantine to global one will create too176// much overhead. One quarantine batch size is 8Kb and it holds up to177// 1021 chunk, which amounts to 1/8 memory overhead per batch when178// thread local quarantine is set to 64Kb.179(ASAN_LOW_MEMORY) ? 1 << 6 : FIRST_32_SECOND_64(1 << 8, 1 << 10);180f->thread_local_quarantine_size_kb = kDefaultThreadLocalQuarantineSizeKb;181}182if (f->thread_local_quarantine_size_kb == 0 && f->quarantine_size_mb > 0) {183Report("%s: thread_local_quarantine_size_kb can be set to 0 only when "184"quarantine_size_mb is set to 0\n", SanitizerToolName);185Die();186}187if (!f->replace_str && common_flags()->intercept_strlen) {188Report("WARNING: strlen interceptor is enabled even though replace_str=0. "189"Use intercept_strlen=0 to disable it.");190}191if (!f->replace_str && common_flags()->intercept_strchr) {192Report("WARNING: strchr* interceptors are enabled even though "193"replace_str=0. Use intercept_strchr=0 to disable them.");194}195if (!f->replace_str && common_flags()->intercept_strndup) {196Report("WARNING: strndup* interceptors are enabled even though "197"replace_str=0. Use intercept_strndup=0 to disable them.");198}199}200201} // namespace __asan202203SANITIZER_INTERFACE_WEAK_DEF(const char*, __asan_default_options, void) {204return "";205}206207208