Skip to content

Commit

Permalink
[ubsan] Add preinit initializer for ubsan
Browse files Browse the repository at this point in the history
Summary:
Now that ubsan does function interception (for signals), we
need to ensure that ubsan is initialized before any library
constructors are called. Otherwise, if a constructor calls
sigaction, ubsan will intercept in an unitialized state, which
will cause a crash.

This patch is a partial revert of r317757, which removed
preinit arrays for ubsan.

Reviewers: vitalybuka, eugenis, pcc

Subscribers: kubamracek, mgorny, llvm-commits, #sanitizers

Differential Revision: https://reviews.llvm.org/D42389

llvm-svn: 323249
  • Loading branch information
fjricci committed Jan 23, 2018
1 parent 1b55f1f commit 564f845
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
1 change: 1 addition & 0 deletions compiler-rt/lib/ubsan/CMakeLists.txt
Expand Up @@ -151,6 +151,7 @@ else()
add_compiler_rt_runtime(clang_rt.ubsan_standalone
STATIC
ARCHS ${UBSAN_SUPPORTED_ARCH}
SOURCES ubsan_init_standalone_preinit.cc
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
RTUbsan
Expand Down
13 changes: 11 additions & 2 deletions compiler-rt/lib/ubsan/ubsan_flags.cc
Expand Up @@ -26,6 +26,15 @@ const char *MaybeCallUbsanDefaultOptions() {
return (&__ubsan_default_options) ? __ubsan_default_options() : "";
}

static const char *GetFlag(const char *flag) {
// We cannot call getenv() from inside a preinit array initializer
if (SANITIZER_CAN_USE_PREINIT_ARRAY) {
return GetEnv(flag);
} else {
return getenv(flag);
}
}

Flags ubsan_flags;

void Flags::SetDefaults() {
Expand All @@ -47,7 +56,7 @@ void InitializeFlags() {
CommonFlags cf;
cf.CopyFrom(*common_flags());
cf.print_summary = false;
cf.external_symbolizer_path = getenv("UBSAN_SYMBOLIZER_PATH");
cf.external_symbolizer_path = GetFlag("UBSAN_SYMBOLIZER_PATH");
OverrideCommonFlags(cf);
}

Expand All @@ -61,7 +70,7 @@ void InitializeFlags() {
// Override from user-specified string.
parser.ParseString(MaybeCallUbsanDefaultOptions());
// Override from environment variable.
parser.ParseString(getenv("UBSAN_OPTIONS"));
parser.ParseString(GetFlag("UBSAN_OPTIONS"));
InitializeCommonFlags();
if (Verbosity()) ReportUnrecognizedFlags();

Expand Down
36 changes: 36 additions & 0 deletions compiler-rt/lib/ubsan/ubsan_init_standalone_preinit.cc
@@ -0,0 +1,36 @@
//===-- ubsan_init_standalone_preinit.cc ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Initialization of standalone UBSan runtime.
//
//===----------------------------------------------------------------------===//

#include "ubsan_platform.h"
#if !CAN_SANITIZE_UB
#error "UBSan is not supported on this platform!"
#endif

#include "sanitizer_common/sanitizer_internal_defs.h"
#include "ubsan_init.h"
#include "ubsan_signals_standalone.h"

#if SANITIZER_CAN_USE_PREINIT_ARRAY

namespace __ubsan {

static void PreInitAsStandalone() {
InitAsStandalone();
InitializeDeadlySignals();
}

} // namespace __ubsan

__attribute__((section(".preinit_array"), used)) void (*__local_ubsan_preinit)(
void) = __ubsan::PreInitAsStandalone;
#endif // SANITIZER_CAN_USE_PREINIT_ARRAY

0 comments on commit 564f845

Please sign in to comment.