summaryrefslogtreecommitdiff
path: root/lib/scudo/scudo_flags.cpp
blob: 90f0cbf4bb86424c2a965bec28c9e274e4557c28 (plain)
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
//===-- scudo_flags.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// Hardened Allocator flag parsing logic.
///
//===----------------------------------------------------------------------===//

#include "scudo_flags.h"
#include "scudo_utils.h"

#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_flag_parser.h"

extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
const char* __scudo_default_options();

namespace __scudo {

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 *callGetScudoDefaultOptions() {
  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 user-specified string.
  const char *ScudoDefaultOptions = callGetScudoDefaultOptions();
  ScudoParser.ParseString(ScudoDefaultOptions);

  // Override from environment.
  ScudoParser.ParseString(GetEnv("SCUDO_OPTIONS"));

  InitializeCommonFlags();

  // Sanity checks and default settings for the Quarantine parameters.

  if (f->QuarantineSizeMb < 0) {
    const int DefaultQuarantineSizeMb = FIRST_32_SECOND_64(4, 16);
    f->QuarantineSizeMb = DefaultQuarantineSizeMb;
  }
  // We enforce an upper limit for the quarantine size of 4Gb.
  if (f->QuarantineSizeMb > (4 * 1024)) {
    dieWithMessage("ERROR: the quarantine size is too large\n");
  }
  if (f->ThreadLocalQuarantineSizeKb < 0) {
    const int DefaultThreadLocalQuarantineSizeKb =
        FIRST_32_SECOND_64(64, 256);
    f->ThreadLocalQuarantineSizeKb = DefaultThreadLocalQuarantineSizeKb;
  }
  // And an upper limit of 128Mb for the thread quarantine cache.
  if (f->ThreadLocalQuarantineSizeKb > (128 * 1024)) {
    dieWithMessage("ERROR: the per thread quarantine cache size is too "
                   "large\n");
  }
  if (f->ThreadLocalQuarantineSizeKb == 0 && f->QuarantineSizeMb > 0) {
    dieWithMessage("ERROR: ThreadLocalQuarantineSizeKb can be set to 0 only "
                   "when QuarantineSizeMb is set to 0\n");
  }
}

Flags *getFlags() {
  return &ScudoFlags;
}

}  // namespace __scudo