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