diff options
author | Kostya Serebryany <kcc@google.com> | 2016-08-02 22:25:38 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2016-08-02 22:25:38 +0000 |
commit | 707894b09270dc072f734d2a28567db58bc36b34 (patch) | |
tree | bf3f73c3a537a22d2dca6dcbfc260992a142ba8c | |
parent | 979902b3ff9009b5909ae245baf43d15f470e22b (diff) | |
download | bcm5719-llvm-707894b09270dc072f734d2a28567db58bc36b34.tar.gz bcm5719-llvm-707894b09270dc072f734d2a28567db58bc36b34.zip |
[sanitizer] Implement a __asan_default_options() equivalent for Scudo
Summary:
Currently, the Scudo Hardened Allocator only gets its flags via the SCUDO_OPTIONS environment variable.
With this patch, we offer the opportunity for programs to define their own options via __scudo_default_options() which behaves like __asan_default_options() (weak symbol).
A relevant test has been added as well, and the documentation updated accordingly.
I also used this patch as an opportunity to rename a few variables to comply with the LLVM naming scheme, and replaced a use of Report with dieWithMessage for consistency (and to avoid a callback).
Reviewers: llvm-commits, kcc
Differential Revision: https://reviews.llvm.org/D23018
llvm-svn: 277536
-rw-r--r-- | compiler-rt/lib/scudo/scudo_allocator.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/scudo/scudo_flags.cpp | 24 | ||||
-rw-r--r-- | compiler-rt/lib/scudo/scudo_termination.cpp | 17 | ||||
-rw-r--r-- | compiler-rt/lib/scudo/scudo_utils.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/test/scudo/options.cpp | 25 | ||||
-rw-r--r-- | llvm/docs/ScudoHardenedAllocator.rst | 29 |
6 files changed, 80 insertions, 19 deletions
diff --git a/compiler-rt/lib/scudo/scudo_allocator.cpp b/compiler-rt/lib/scudo/scudo_allocator.cpp index 3ad499aed10..ceb7bbdd4d8 100644 --- a/compiler-rt/lib/scudo/scudo_allocator.cpp +++ b/compiler-rt/lib/scudo/scudo_allocator.cpp @@ -76,7 +76,7 @@ struct UnpackedHeader { u64 Offset : 20; // Offset from the beginning of the backend // allocation to the beginning chunk itself, in // multiples of MinAlignment. See comment about its - // maximum value and test in Initialize. + // maximum value and test in init(). u64 Unused_1_ : 28; u16 Salt : 16; }; diff --git a/compiler-rt/lib/scudo/scudo_flags.cpp b/compiler-rt/lib/scudo/scudo_flags.cpp index 430dcd2995d..f0d208863bc 100644 --- a/compiler-rt/lib/scudo/scudo_flags.cpp +++ b/compiler-rt/lib/scudo/scudo_flags.cpp @@ -17,9 +17,12 @@ #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 scudo_flags_dont_use_directly; // use via flags(). +Flags ScudoFlags; // Use via getFlags(). void Flags::setDefaults() { #define SCUDO_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; @@ -34,6 +37,10 @@ static void RegisterScudoFlags(FlagParser *parser, Flags *f) { #undef SCUDO_FLAG } +static const char *callGetScudoDefaultOptions() { + return (&__scudo_default_options) ? __scudo_default_options() : ""; +} + void initFlags() { SetCommonFlagsDefaults(); { @@ -45,11 +52,16 @@ void initFlags() { Flags *f = getFlags(); f->setDefaults(); - FlagParser scudo_parser; - RegisterScudoFlags(&scudo_parser, f); - RegisterCommonFlags(&scudo_parser); + FlagParser ScudoParser; + RegisterScudoFlags(&ScudoParser, f); + RegisterCommonFlags(&ScudoParser); + + // Override from user-specified string. + const char *ScudoDefaultOptions = callGetScudoDefaultOptions(); + ScudoParser.ParseString(ScudoDefaultOptions); - scudo_parser.ParseString(GetEnv("SCUDO_OPTIONS")); + // Override from environment. + ScudoParser.ParseString(GetEnv("SCUDO_OPTIONS")); InitializeCommonFlags(); @@ -75,7 +87,7 @@ void initFlags() { } Flags *getFlags() { - return &scudo_flags_dont_use_directly; + return &ScudoFlags; } } diff --git a/compiler-rt/lib/scudo/scudo_termination.cpp b/compiler-rt/lib/scudo/scudo_termination.cpp index 32421d3d810..a53338315c6 100644 --- a/compiler-rt/lib/scudo/scudo_termination.cpp +++ b/compiler-rt/lib/scudo/scudo_termination.cpp @@ -13,15 +13,17 @@ /// //===----------------------------------------------------------------------===// +#include "scudo_utils.h" + #include "sanitizer_common/sanitizer_common.h" namespace __sanitizer { -bool AddDieCallback(DieCallbackType callback) { return true; } +bool AddDieCallback(DieCallbackType Callback) { return true; } -bool RemoveDieCallback(DieCallbackType callback) { return true; } +bool RemoveDieCallback(DieCallbackType Callback) { return true; } -void SetUserDieCallback(DieCallbackType callback) {} +void SetUserDieCallback(DieCallbackType Callback) {} void NORETURN Die() { if (common_flags()->abort_on_error) @@ -31,11 +33,10 @@ void NORETURN Die() { void SetCheckFailedCallback(CheckFailedCallbackType callback) {} -void NORETURN CheckFailed(const char *file, int line, const char *cond, - u64 v1, u64 v2) { - Report("Sanitizer CHECK failed: %s:%d %s (%lld, %lld)\n", file, line, cond, - v1, v2); - Die(); +void NORETURN CheckFailed(const char *File, int Line, const char *Condition, + u64 Value1, u64 Value2) { + __scudo::dieWithMessage("Scudo CHECK failed: %s:%d %s (%lld, %lld)\n", + File, Line, Condition, Value1, Value2); } } // namespace __sanitizer diff --git a/compiler-rt/lib/scudo/scudo_utils.cpp b/compiler-rt/lib/scudo/scudo_utils.cpp index 6b96e84ee9d..f45569e03e0 100644 --- a/compiler-rt/lib/scudo/scudo_utils.cpp +++ b/compiler-rt/lib/scudo/scudo_utils.cpp @@ -33,7 +33,7 @@ extern int VSNPrintf(char *buff, int buff_length, const char *format, namespace __scudo { FORMAT(1, 2) -void dieWithMessage(const char *Format, ...) { +void NORETURN dieWithMessage(const char *Format, ...) { // Our messages are tiny, 128 characters is more than enough. char Message[128]; va_list Args; diff --git a/compiler-rt/test/scudo/options.cpp b/compiler-rt/test/scudo/options.cpp new file mode 100644 index 00000000000..bccf7c8fbd2 --- /dev/null +++ b/compiler-rt/test/scudo/options.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_scudo %s -o %t +// RUN: %run %t 2>&1 +// RUN: SCUDO_OPTIONS=DeallocationTypeMismatch=0 %run %t 2>&1 +// RUN: SCUDO_OPTIONS=DeallocationTypeMismatch=1 not %run %t 2>&1 | FileCheck %s + +// Tests that the options can be passed using getScudoDefaultOptions, and that +// the environment ones take precedence over them. + +#include <stdlib.h> +#include <malloc.h> + +extern "C" const char* __scudo_default_options() { + return "DeallocationTypeMismatch=0"; // Defaults to true in scudo_flags.inc. +} + +int main(int argc, char **argv) +{ + int *p = (int *)malloc(16); + if (!p) + return 1; + delete p; + return 0; +} + +// CHECK: ERROR: allocation type mismatch on address diff --git a/llvm/docs/ScudoHardenedAllocator.rst b/llvm/docs/ScudoHardenedAllocator.rst index 5bc390eadd5..2c8493a6c2b 100644 --- a/llvm/docs/ScudoHardenedAllocator.rst +++ b/llvm/docs/ScudoHardenedAllocator.rst @@ -89,10 +89,33 @@ functions. Options ------- -Several aspects of the allocator can be configured through environment options, -following the usual ASan options syntax, through the variable SCUDO_OPTIONS. +Several aspects of the allocator can be configured through the following ways: + +- by defining a __scudo_default_options function in one's program that returns + the options string to be parsed. Said function must have the following + prototype: ``extern "C" const char* __scudo_default_options()``. + +- through the environment variable SCUDO_OPTIONS, containing the options string + to be parsed. Options defined this way will override any definition made + through __scudo_default_options; + +The options string follows a syntax similar to ASan, where distinct options +can be assigned in the same string, separated by colons. + +For example, using the environment variable: + +.. code:: + + SCUDO_OPTIONS="DeleteSizeMismatch=1:QuarantineSizeMb=16" ./a.out + +Or using the function: + +.. code:: + + extern "C" const char *__scudo_default_options() { + return "DeleteSizeMismatch=1:QuarantineSizeMb=16"; + } -For example: SCUDO_OPTIONS="DeleteSizeMismatch=1:QuarantineSizeMb=16". The following options are available: |