summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVlad Tsyrklevich <vlad@tsyrklevich.net>2018-04-04 17:53:33 +0000
committerVlad Tsyrklevich <vlad@tsyrklevich.net>2018-04-04 17:53:33 +0000
commitf60f85afd0e280fa1beb723c1cb05a0d21e2a078 (patch)
tree4f99d5c90b72116c9aa32664461f377996b2934f
parent97c4d2222f7471e91d5017aaa5692c65e8fe1c74 (diff)
Add simple runtime tests for shadowcallstack
Summary: ShadowCallStack does not yet have a runtime provided by compiler-rt, but this change includes simple tests that make use of a very minimal runtime in test/shadowcallstack/minimal_runtime.h Reviewers: pcc, kcc, delcypher, eugenis, filcab Reviewed By: pcc Subscribers: kubamracek, mgorny, delcypher, llvm-commits, #sanitizers, kcc Differential Revision: https://reviews.llvm.org/D44803 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@329210 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--test/CMakeLists.txt3
-rw-r--r--test/shadowcallstack/CMakeLists.txt13
-rw-r--r--test/shadowcallstack/init.c16
-rw-r--r--test/shadowcallstack/lit.cfg19
-rw-r--r--test/shadowcallstack/lit.site.cfg.in7
-rw-r--r--test/shadowcallstack/minimal_runtime.h26
-rw-r--r--test/shadowcallstack/overflow.c36
7 files changed, 120 insertions, 0 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index ab16f42d3..fa2031a7b 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -78,6 +78,9 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
if(COMPILER_RT_BUILD_XRAY)
compiler_rt_test_runtime(xray)
endif()
+ # ShadowCallStack does not yet provide a runtime with compiler-rt, the tests
+ # include their own minimal runtime
+ add_subdirectory(shadowcallstack)
endif()
if(COMPILER_RT_STANDALONE_BUILD)
diff --git a/test/shadowcallstack/CMakeLists.txt b/test/shadowcallstack/CMakeLists.txt
new file mode 100644
index 000000000..f8fd835be
--- /dev/null
+++ b/test/shadowcallstack/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(SHADOWCALLSTACK_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(SHADOWCALLSTACK_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+set(SHADOWCALLSTACK_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+
+configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ )
+
+add_lit_testsuite(check-shadowcallstack "Running the ShadowCallStack tests"
+ ${CMAKE_CURRENT_BINARY_DIR})
+set_target_properties(check-shadowcallstack PROPERTIES FOLDER "Compiler-RT Misc")
diff --git a/test/shadowcallstack/init.c b/test/shadowcallstack/init.c
new file mode 100644
index 000000000..8dad6bdbb
--- /dev/null
+++ b/test/shadowcallstack/init.c
@@ -0,0 +1,16 @@
+// RUN: %clang_scs -D INCLUDE_RUNTIME %s -o %t
+// RUN: %run %t
+
+// RUN: %clang_scs %s -o %t
+// RUN: not --crash %run %t
+
+// Basic smoke test for the runtime
+
+#ifdef INCLUDE_RUNTIME
+#include "minimal_runtime.h"
+#endif
+
+int main(int argc, char **argv) {
+ printf("In main.\n");
+ return 0;
+}
diff --git a/test/shadowcallstack/lit.cfg b/test/shadowcallstack/lit.cfg
new file mode 100644
index 000000000..1642bdc10
--- /dev/null
+++ b/test/shadowcallstack/lit.cfg
@@ -0,0 +1,19 @@
+# -*- Python -*-
+
+import os
+
+# Setup config name.
+config.name = 'ShadowCallStack'
+
+# Setup source root.
+config.test_source_root = os.path.dirname(__file__)
+
+# Test suffixes.
+config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm', '.ll', '.test']
+
+# Add clang substitutions.
+config.substitutions.append( ("%clang_noscs ", config.clang + " -O0 -fno-sanitize=shadow-call-stack ") )
+config.substitutions.append( ("%clang_scs ", config.clang + " -O0 -fsanitize=shadow-call-stack ") )
+
+if config.host_os not in ['Linux'] or config.target_arch != 'x86_64':
+ config.unsupported = True
diff --git a/test/shadowcallstack/lit.site.cfg.in b/test/shadowcallstack/lit.site.cfg.in
new file mode 100644
index 000000000..4582f36d7
--- /dev/null
+++ b/test/shadowcallstack/lit.site.cfg.in
@@ -0,0 +1,7 @@
+@LIT_SITE_CFG_IN_HEADER@
+
+# Load common config for all compiler-rt lit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+
+# Load tool-specific config that would do the real work.
+lit_config.load_config(config, "@SHADOWCALLSTACK_LIT_SOURCE_DIR@/lit.cfg")
diff --git a/test/shadowcallstack/minimal_runtime.h b/test/shadowcallstack/minimal_runtime.h
new file mode 100644
index 000000000..75d95ec3c
--- /dev/null
+++ b/test/shadowcallstack/minimal_runtime.h
@@ -0,0 +1,26 @@
+// A shadow call stack runtime is not yet included with compiler-rt, provide a
+// minimal runtime to allocate a shadow call stack and assign %gs to point at
+// it.
+
+#pragma once
+
+#include <asm/prctl.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+
+int arch_prctl(int code, void *addr);
+
+__attribute__((no_sanitize("shadow-call-stack")))
+static void __shadowcallstack_init() {
+ void *stack = mmap(NULL, 8192, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (stack == MAP_FAILED)
+ abort();
+
+ if (arch_prctl(ARCH_SET_GS, stack))
+ abort();
+}
+
+__attribute__((section(".preinit_array"), used))
+ void (*__shadowcallstack_preinit)(void) = __shadowcallstack_init;
diff --git a/test/shadowcallstack/overflow.c b/test/shadowcallstack/overflow.c
new file mode 100644
index 000000000..b7b29a117
--- /dev/null
+++ b/test/shadowcallstack/overflow.c
@@ -0,0 +1,36 @@
+// RUN: %clang_noscs %s -o %t
+// RUN: %run %t 3 | FileCheck %s
+// RUN: %run %t 12 | FileCheck -check-prefix=OVERFLOW_SUCCESS %s
+
+// RUN: %clang_scs %s -o %t
+// RUN: %run %t 3 | FileCheck %s
+// RUN: not --crash %run %t 12
+
+// Test that a stack overflow fails as expected
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "minimal_runtime.h"
+
+void print_and_exit(void) {
+// CHECK-NOT: Stack overflow successful.
+// OVERFLOW_SUCCESS: Stack overflow successful.
+ printf("Stack overflow successful.\n");
+ exit(0);
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 2)
+ exit(1);
+
+ void *addrs[4];
+ const int iterations = atoi(argv[1]);
+ for (int i = 0; i < iterations; i++)
+ addrs[i] = &print_and_exit;
+
+ printf("Returning.\n");
+
+ return 0;
+}