1 //===-- scudo_flags.cpp -----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// Hardened Allocator flag parsing logic. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "scudo_flags.h" 15 #include "scudo_utils.h" 16 17 #include "sanitizer_common/sanitizer_flags.h" 18 #include "sanitizer_common/sanitizer_flag_parser.h" 19 20 SANITIZER_INTERFACE_WEAK_DEF(const char*, __scudo_default_options, void); 21 22 namespace __scudo { 23 24 static Flags ScudoFlags; // Use via getFlags(). 25 26 void Flags::setDefaults() { 27 #define SCUDO_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 28 #include "scudo_flags.inc" 29 #undef SCUDO_FLAG 30 } 31 32 static void RegisterScudoFlags(FlagParser *parser, Flags *f) { 33 #define SCUDO_FLAG(Type, Name, DefaultValue, Description) \ 34 RegisterFlag(parser, #Name, Description, &f->Name); 35 #include "scudo_flags.inc" 36 #undef SCUDO_FLAG 37 } 38 39 static const char *getScudoDefaultOptions() { 40 return (&__scudo_default_options) ? __scudo_default_options() : ""; 41 } 42 43 void initFlags() { 44 SetCommonFlagsDefaults(); 45 { 46 CommonFlags cf; 47 cf.CopyFrom(*common_flags()); 48 cf.exitcode = 1; 49 OverrideCommonFlags(cf); 50 } 51 Flags *f = getFlags(); 52 f->setDefaults(); 53 54 FlagParser ScudoParser; 55 RegisterScudoFlags(&ScudoParser, f); 56 RegisterCommonFlags(&ScudoParser); 57 58 // Override from user-specified string. 59 ScudoParser.ParseString(getScudoDefaultOptions()); 60 61 // Override from environment. 62 ScudoParser.ParseString(GetEnv("SCUDO_OPTIONS")); 63 64 InitializeCommonFlags(); 65 66 // Sanity checks and default settings for the Quarantine parameters. 67 68 if (f->QuarantineSizeMb >= 0) { 69 // Backward compatible logic if QuarantineSizeMb is set. 70 if (f->QuarantineSizeKb >= 0) { 71 dieWithMessage("ERROR: please use either QuarantineSizeMb (deprecated) " 72 "or QuarantineSizeKb, but not both\n"); 73 } 74 if (f->QuarantineChunksUpToSize >= 0) { 75 dieWithMessage("ERROR: QuarantineChunksUpToSize cannot be used in " 76 " conjunction with the deprecated QuarantineSizeMb option\n"); 77 } 78 // If everything is in order, update QuarantineSizeKb accordingly. 79 f->QuarantineSizeKb = f->QuarantineSizeMb * 1024; 80 } else { 81 // Otherwise proceed with the new options. 82 if (f->QuarantineSizeKb < 0) { 83 const int DefaultQuarantineSizeKb = FIRST_32_SECOND_64(64, 256); 84 f->QuarantineSizeKb = DefaultQuarantineSizeKb; 85 } 86 if (f->QuarantineChunksUpToSize < 0) { 87 const int DefaultQuarantineChunksUpToSize = FIRST_32_SECOND_64(512, 2048); 88 f->QuarantineChunksUpToSize = DefaultQuarantineChunksUpToSize; 89 } 90 } 91 92 // We enforce an upper limit for the chunk quarantine threshold of 4Mb. 93 if (f->QuarantineChunksUpToSize > (4 * 1024 * 1024)) { 94 dieWithMessage("ERROR: the chunk quarantine threshold is too large\n"); 95 } 96 97 // We enforce an upper limit for the quarantine size of 32Mb. 98 if (f->QuarantineSizeKb > (32 * 1024)) { 99 dieWithMessage("ERROR: the quarantine size is too large\n"); 100 } 101 102 if (f->ThreadLocalQuarantineSizeKb < 0) { 103 const int DefaultThreadLocalQuarantineSizeKb = FIRST_32_SECOND_64(16, 64); 104 f->ThreadLocalQuarantineSizeKb = DefaultThreadLocalQuarantineSizeKb; 105 } 106 // And an upper limit of 8Mb for the thread quarantine cache. 107 if (f->ThreadLocalQuarantineSizeKb > (8 * 1024)) { 108 dieWithMessage("ERROR: the per thread quarantine cache size is too " 109 "large\n"); 110 } 111 if (f->ThreadLocalQuarantineSizeKb == 0 && f->QuarantineSizeKb > 0) { 112 dieWithMessage("ERROR: ThreadLocalQuarantineSizeKb can be set to 0 only " 113 "when QuarantineSizeKb is set to 0\n"); 114 } 115 } 116 117 Flags *getFlags() { 118 return &ScudoFlags; 119 } 120 121 } // namespace __scudo 122