blob: c012471a83687f5c0d3c372bb93fc25f5b03f5e9 [file] [log] [blame]
Kostya Serebryany712fc982016-06-07 01:20:26 +00001//===-- 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"
Kostya Kortchinsky4223af42018-01-30 17:59:49 +000015#include "scudo_interface_internal.h"
Kostya Serebryany712fc982016-06-07 01:20:26 +000016#include "scudo_utils.h"
17
18#include "sanitizer_common/sanitizer_flags.h"
19#include "sanitizer_common/sanitizer_flag_parser.h"
20
21namespace __scudo {
22
Kostya Kortchinskya2b715f2017-11-14 16:14:53 +000023static Flags ScudoFlags; // Use via getFlags().
Kostya Serebryany712fc982016-06-07 01:20:26 +000024
25void Flags::setDefaults() {
26#define SCUDO_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
27#include "scudo_flags.inc"
28#undef SCUDO_FLAG
29}
30
31static void RegisterScudoFlags(FlagParser *parser, Flags *f) {
32#define SCUDO_FLAG(Type, Name, DefaultValue, Description) \
33 RegisterFlag(parser, #Name, Description, &f->Name);
34#include "scudo_flags.inc"
35#undef SCUDO_FLAG
36}
37
Kostya Kortchinsky28333832018-02-08 16:29:48 +000038static const char *getCompileDefinitionScudoDefaultOptions() {
39#ifdef SCUDO_DEFAULT_OPTIONS
40 return SANITIZER_STRINGIFY(SCUDO_DEFAULT_OPTIONS);
41#else
42 return "";
43#endif
44}
45
Kostya Kortchinskya2b715f2017-11-14 16:14:53 +000046static const char *getScudoDefaultOptions() {
Kostya Serebryany707894b2016-08-02 22:25:38 +000047 return (&__scudo_default_options) ? __scudo_default_options() : "";
48}
49
Kostya Serebryany712fc982016-06-07 01:20:26 +000050void initFlags() {
51 SetCommonFlagsDefaults();
52 {
53 CommonFlags cf;
54 cf.CopyFrom(*common_flags());
55 cf.exitcode = 1;
56 OverrideCommonFlags(cf);
57 }
58 Flags *f = getFlags();
59 f->setDefaults();
60
Kostya Serebryany707894b2016-08-02 22:25:38 +000061 FlagParser ScudoParser;
62 RegisterScudoFlags(&ScudoParser, f);
63 RegisterCommonFlags(&ScudoParser);
Kostya Serebryany712fc982016-06-07 01:20:26 +000064
Kostya Kortchinsky28333832018-02-08 16:29:48 +000065 // Override from compile definition.
66 ScudoParser.ParseString(getCompileDefinitionScudoDefaultOptions());
67
Kostya Serebryany707894b2016-08-02 22:25:38 +000068 // Override from user-specified string.
Kostya Kortchinskya2b715f2017-11-14 16:14:53 +000069 ScudoParser.ParseString(getScudoDefaultOptions());
Kostya Serebryany707894b2016-08-02 22:25:38 +000070
71 // Override from environment.
72 ScudoParser.ParseString(GetEnv("SCUDO_OPTIONS"));
Kostya Serebryany712fc982016-06-07 01:20:26 +000073
74 InitializeCommonFlags();
75
76 // Sanity checks and default settings for the Quarantine parameters.
77
Kostya Kortchinsky2d944052017-07-24 15:29:38 +000078 if (f->QuarantineSizeMb >= 0) {
79 // Backward compatible logic if QuarantineSizeMb is set.
80 if (f->QuarantineSizeKb >= 0) {
81 dieWithMessage("ERROR: please use either QuarantineSizeMb (deprecated) "
82 "or QuarantineSizeKb, but not both\n");
83 }
84 if (f->QuarantineChunksUpToSize >= 0) {
85 dieWithMessage("ERROR: QuarantineChunksUpToSize cannot be used in "
86 " conjunction with the deprecated QuarantineSizeMb option\n");
87 }
88 // If everything is in order, update QuarantineSizeKb accordingly.
89 f->QuarantineSizeKb = f->QuarantineSizeMb * 1024;
90 } else {
91 // Otherwise proceed with the new options.
92 if (f->QuarantineSizeKb < 0) {
93 const int DefaultQuarantineSizeKb = FIRST_32_SECOND_64(64, 256);
94 f->QuarantineSizeKb = DefaultQuarantineSizeKb;
95 }
96 if (f->QuarantineChunksUpToSize < 0) {
97 const int DefaultQuarantineChunksUpToSize = FIRST_32_SECOND_64(512, 2048);
98 f->QuarantineChunksUpToSize = DefaultQuarantineChunksUpToSize;
99 }
Kostya Serebryany712fc982016-06-07 01:20:26 +0000100 }
Kostya Kortchinsky2d944052017-07-24 15:29:38 +0000101
102 // We enforce an upper limit for the chunk quarantine threshold of 4Mb.
103 if (f->QuarantineChunksUpToSize > (4 * 1024 * 1024)) {
104 dieWithMessage("ERROR: the chunk quarantine threshold is too large\n");
105 }
106
107 // We enforce an upper limit for the quarantine size of 32Mb.
108 if (f->QuarantineSizeKb > (32 * 1024)) {
Kostya Serebryany712fc982016-06-07 01:20:26 +0000109 dieWithMessage("ERROR: the quarantine size is too large\n");
110 }
Kostya Kortchinsky2d944052017-07-24 15:29:38 +0000111
Kostya Serebryany712fc982016-06-07 01:20:26 +0000112 if (f->ThreadLocalQuarantineSizeKb < 0) {
Kostya Kortchinsky2d944052017-07-24 15:29:38 +0000113 const int DefaultThreadLocalQuarantineSizeKb = FIRST_32_SECOND_64(16, 64);
Kostya Serebryany712fc982016-06-07 01:20:26 +0000114 f->ThreadLocalQuarantineSizeKb = DefaultThreadLocalQuarantineSizeKb;
115 }
Kostya Kortchinsky2d944052017-07-24 15:29:38 +0000116 // And an upper limit of 8Mb for the thread quarantine cache.
117 if (f->ThreadLocalQuarantineSizeKb > (8 * 1024)) {
Kostya Serebryany712fc982016-06-07 01:20:26 +0000118 dieWithMessage("ERROR: the per thread quarantine cache size is too "
Kostya Kortchinsky2d944052017-07-24 15:29:38 +0000119 "large\n");
Kostya Serebryany712fc982016-06-07 01:20:26 +0000120 }
Kostya Kortchinsky2d944052017-07-24 15:29:38 +0000121 if (f->ThreadLocalQuarantineSizeKb == 0 && f->QuarantineSizeKb > 0) {
Kostya Kortchinsky8d6257b2017-02-03 20:49:42 +0000122 dieWithMessage("ERROR: ThreadLocalQuarantineSizeKb can be set to 0 only "
Kostya Kortchinsky2d944052017-07-24 15:29:38 +0000123 "when QuarantineSizeKb is set to 0\n");
Kostya Kortchinsky8d6257b2017-02-03 20:49:42 +0000124 }
Kostya Serebryany712fc982016-06-07 01:20:26 +0000125}
126
127Flags *getFlags() {
Kostya Serebryany707894b2016-08-02 22:25:38 +0000128 return &ScudoFlags;
Kostya Serebryany712fc982016-06-07 01:20:26 +0000129}
130
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +0000131} // namespace __scudo
Kostya Kortchinsky4223af42018-01-30 17:59:49 +0000132
133#if !SANITIZER_SUPPORTS_WEAK_HOOKS
134SANITIZER_INTERFACE_WEAK_DEF(const char*, __scudo_default_options, void) {
135 return "";
136}
137#endif