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 extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
21 const char* __scudo_default_options();
22 
23 namespace __scudo {
24 
25 Flags ScudoFlags;  // Use via getFlags().
26 
27 void Flags::setDefaults() {
28 #define SCUDO_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
29 #include "scudo_flags.inc"
30 #undef SCUDO_FLAG
31 }
32 
33 static void RegisterScudoFlags(FlagParser *parser, Flags *f) {
34 #define SCUDO_FLAG(Type, Name, DefaultValue, Description) \
35   RegisterFlag(parser, #Name, Description, &f->Name);
36 #include "scudo_flags.inc"
37 #undef SCUDO_FLAG
38 }
39 
40 static const char *callGetScudoDefaultOptions() {
41   return (&__scudo_default_options) ? __scudo_default_options() : "";
42 }
43 
44 void initFlags() {
45   SetCommonFlagsDefaults();
46   {
47     CommonFlags cf;
48     cf.CopyFrom(*common_flags());
49     cf.exitcode = 1;
50     OverrideCommonFlags(cf);
51   }
52   Flags *f = getFlags();
53   f->setDefaults();
54 
55   FlagParser ScudoParser;
56   RegisterScudoFlags(&ScudoParser, f);
57   RegisterCommonFlags(&ScudoParser);
58 
59   // Override from user-specified string.
60   const char *ScudoDefaultOptions = callGetScudoDefaultOptions();
61   ScudoParser.ParseString(ScudoDefaultOptions);
62 
63   // Override from environment.
64   ScudoParser.ParseString(GetEnv("SCUDO_OPTIONS"));
65 
66   InitializeCommonFlags();
67 
68   // Sanity checks and default settings for the Quarantine parameters.
69 
70   if (f->QuarantineSizeMb < 0) {
71     const int DefaultQuarantineSizeMb = 64;
72     f->QuarantineSizeMb = DefaultQuarantineSizeMb;
73   }
74   // We enforce an upper limit for the quarantine size of 4Gb.
75   if (f->QuarantineSizeMb > (4 * 1024)) {
76     dieWithMessage("ERROR: the quarantine size is too large\n");
77   }
78   if (f->ThreadLocalQuarantineSizeKb < 0) {
79     const int DefaultThreadLocalQuarantineSizeKb = 1024;
80     f->ThreadLocalQuarantineSizeKb = DefaultThreadLocalQuarantineSizeKb;
81   }
82   // And an upper limit of 128Mb for the thread quarantine cache.
83   if (f->ThreadLocalQuarantineSizeKb > (128 * 1024)) {
84     dieWithMessage("ERROR: the per thread quarantine cache size is too "
85                    "large\n");
86   }
87 }
88 
89 Flags *getFlags() {
90   return &ScudoFlags;
91 }
92 
93 }  // namespace __scudo
94