[SanitizerCoverage] Clang crashes if user declares `__sancov_lowest_stack` variable
authorJulian Lettner <jlettner@apple.com>
Mon, 4 Feb 2019 22:06:30 +0000 (22:06 +0000)
committerJulian Lettner <jlettner@apple.com>
Mon, 4 Feb 2019 22:06:30 +0000 (22:06 +0000)
Summary:
If the user declares or defines `__sancov_lowest_stack` with an
unexpected type, then `getOrInsertGlobal` inserts a bitcast and the
following cast fails:
```
Constant *SanCovLowestStackConstant =
       M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
SanCovLowestStack = cast<GlobalVariable>(SanCovLowestStackConstant);
```

This variable is a SanitizerCoverage implementation detail and the user
should generally never have a need to access it, so we emit an error
now.

rdar://problem/44143130

Reviewers: morehouse

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

llvm-svn: 353100

llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
llvm/test/Instrumentation/SanitizerCoverage/stack-depth-variable-declared-by-user.ll [new file with mode: 0644]

index 18c6ceb..21ad41c 100644 (file)
@@ -377,7 +377,12 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
 
   Constant *SanCovLowestStackConstant =
       M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
-  SanCovLowestStack = cast<GlobalVariable>(SanCovLowestStackConstant);
+  SanCovLowestStack = dyn_cast<GlobalVariable>(SanCovLowestStackConstant);
+  if (!SanCovLowestStack) {
+    C->emitError(StringRef("'") + SanCovLowestStackName +
+                 "' should not be declared by the user");
+    return true;
+  }
   SanCovLowestStack->setThreadLocalMode(
       GlobalValue::ThreadLocalMode::InitialExecTLSModel);
   if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
diff --git a/llvm/test/Instrumentation/SanitizerCoverage/stack-depth-variable-declared-by-user.ll b/llvm/test/Instrumentation/SanitizerCoverage/stack-depth-variable-declared-by-user.ll
new file mode 100644 (file)
index 0000000..1ad96f8
--- /dev/null
@@ -0,0 +1,12 @@
+; Ensure that we terminate with a useful error message (instead of crash) if the
+; user declares `__sancov_lowest_stack` with an unexpected type.
+; RUN: not opt < %s -sancov -sanitizer-coverage-level=1 \
+; RUN:         -sanitizer-coverage-stack-depth -S 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Wrong type: i32 instead of expected i64
+@__sancov_lowest_stack = thread_local global i32 0
+
+; CHECK: error: '__sancov_lowest_stack' should not be declared by the user