diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-09-06 18:41:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-09-06 18:41:23 +0000 |
commit | f31bcc68c72371a2bf63aead9f3373a1ff2053b6 (patch) | |
tree | b259e5d585da0f8cde9579939a74d5ef44c72abd /test/safestack | |
parent | cd2dd3df15523e2be8d2bbace27641d6ac9fa40d (diff) | |
download | src-test2-f31bcc68c72371a2bf63aead9f3373a1ff2053b6.tar.gz src-test2-f31bcc68c72371a2bf63aead9f3373a1ff2053b6.zip |
Notes
Diffstat (limited to 'test/safestack')
-rw-r--r-- | test/safestack/CMakeLists.txt | 29 | ||||
-rw-r--r-- | test/safestack/buffer-copy-vla.c | 26 | ||||
-rw-r--r-- | test/safestack/buffer-copy.c | 25 | ||||
-rw-r--r-- | test/safestack/init.c | 9 | ||||
-rw-r--r-- | test/safestack/lit.cfg | 24 | ||||
-rw-r--r-- | test/safestack/lit.site.cfg.in | 8 | ||||
-rw-r--r-- | test/safestack/lto.c | 12 | ||||
-rw-r--r-- | test/safestack/overflow.c | 23 | ||||
-rw-r--r-- | test/safestack/pthread-cleanup.c | 31 | ||||
-rw-r--r-- | test/safestack/pthread.c | 42 | ||||
-rw-r--r-- | test/safestack/utils.h | 8 |
11 files changed, 237 insertions, 0 deletions
diff --git a/test/safestack/CMakeLists.txt b/test/safestack/CMakeLists.txt new file mode 100644 index 000000000000..6f5c2f9b0af4 --- /dev/null +++ b/test/safestack/CMakeLists.txt @@ -0,0 +1,29 @@ +set(SAFESTACK_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(SAFESTACK_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) + +set(SAFESTACK_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) +if(NOT COMPILER_RT_STANDALONE_BUILD) + list(APPEND SAFESTACK_TEST_DEPS safestack) + + # Some tests require LTO, so add a dependency on the relevant LTO plugin. + if(LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR) + list(APPEND SAFESTACK_TEST_DEPS + LLVMgold + ) + endif() + if(APPLE) + list(APPEND SAFESTACK_TEST_DEPS + LTO + ) + endif() +endif() + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ) + +add_lit_testsuite(check-safestack "Running the SafeStack tests" + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${SAFESTACK_TEST_DEPS}) +set_target_properties(check-safestack PROPERTIES FOLDER "SafeStack tests") diff --git a/test/safestack/buffer-copy-vla.c b/test/safestack/buffer-copy-vla.c new file mode 100644 index 000000000000..356a1ac5c65c --- /dev/null +++ b/test/safestack/buffer-copy-vla.c @@ -0,0 +1,26 @@ +// RUN: %clang_safestack %s -o %t +// RUN: %run %t + +#include "utils.h" + +// Test that loads/stores work correctly for VLAs on the unsafe stack. + +int main(int argc, char **argv) +{ + int i = 128; + break_optimization(&i); + char buffer[i]; + + // check that we can write to a buffer + for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i) + buffer[i] = argv[0][i]; + buffer[i] = '\0'; + + break_optimization(buffer); + + // check that we can read from a buffer + for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i) + if (buffer[i] != argv[0][i]) + return 1; + return 0; +} diff --git a/test/safestack/buffer-copy.c b/test/safestack/buffer-copy.c new file mode 100644 index 000000000000..96b2302be1b1 --- /dev/null +++ b/test/safestack/buffer-copy.c @@ -0,0 +1,25 @@ +// RUN: %clang_safestack %s -o %t +// RUN: %run %t + +#include "utils.h" + +// Test that loads/stores work correctly for variables on the unsafe stack. + +int main(int argc, char **argv) +{ + int i; + char buffer[128]; + + // check that we can write to a buffer + for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i) + buffer[i] = argv[0][i]; + buffer[i] = '\0'; + + break_optimization(buffer); + + // check that we can read from a buffer + for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i) + if (buffer[i] != argv[0][i]) + return 1; + return 0; +} diff --git a/test/safestack/init.c b/test/safestack/init.c new file mode 100644 index 000000000000..cff75f5f8939 --- /dev/null +++ b/test/safestack/init.c @@ -0,0 +1,9 @@ +// RUN: %clang_safestack %s -o %t +// RUN: %run %t + +// Basic smoke test for the runtime library. + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/test/safestack/lit.cfg b/test/safestack/lit.cfg new file mode 100644 index 000000000000..13fc92fa4b2b --- /dev/null +++ b/test/safestack/lit.cfg @@ -0,0 +1,24 @@ +# -*- Python -*- + +import os + +# Setup config name. +config.name = 'SafeStack' + +# 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_nosafestack ", config.clang + " -O0 -fno-sanitize=safe-stack ") ) +config.substitutions.append( ("%clang_safestack ", config.clang + " -O0 -fsanitize=safe-stack ") ) + +if config.lto_supported: + config.available_features.add('lto') + config.substitutions.append((r"%clang_lto_safestack ", ' '.join(config.lto_launch + [config.clang] + config.lto_flags + ['-flto -fsanitize=safe-stack ']))) + +# SafeStack tests are currently supported on Linux, FreeBSD and Darwin only. +if config.host_os not in ['Linux', 'FreeBSD', 'Darwin']: + config.unsupported = True diff --git a/test/safestack/lit.site.cfg.in b/test/safestack/lit.site.cfg.in new file mode 100644 index 000000000000..cb1e7292e5f2 --- /dev/null +++ b/test/safestack/lit.site.cfg.in @@ -0,0 +1,8 @@ +## Autogenerated by LLVM/Clang configuration. +# Do not edit! + +# 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, "@SAFESTACK_LIT_SOURCE_DIR@/lit.cfg") diff --git a/test/safestack/lto.c b/test/safestack/lto.c new file mode 100644 index 000000000000..6ee23a1c72f2 --- /dev/null +++ b/test/safestack/lto.c @@ -0,0 +1,12 @@ +// REQUIRES: lto + +// RUN: %clang_lto_safestack %s -o %t +// RUN: %run %t + +// Test that safe stack works with LTO. + +int main() { + char c[] = "hello world"; + puts(c); + return 0; +} diff --git a/test/safestack/overflow.c b/test/safestack/overflow.c new file mode 100644 index 000000000000..14e29823cd99 --- /dev/null +++ b/test/safestack/overflow.c @@ -0,0 +1,23 @@ +// RUN: %clang_safestack %s -o %t +// RUN: %run %t + +// RUN: %clang_nosafestack -fno-stack-protector %s -o %t +// RUN: not %run %t + +// Test that buffer overflows on the unsafe stack do not affect variables on the +// safe stack. + +__attribute__((noinline)) +void fct(volatile int *buffer) +{ + memset(buffer - 1, 0, 7 * sizeof(int)); +} + +int main(int argc, char **argv) +{ + int value1 = 42; + int buffer[5]; + int value2 = 42; + fct(buffer); + return value1 != 42 || value2 != 42; +} diff --git a/test/safestack/pthread-cleanup.c b/test/safestack/pthread-cleanup.c new file mode 100644 index 000000000000..805366c9f1eb --- /dev/null +++ b/test/safestack/pthread-cleanup.c @@ -0,0 +1,31 @@ +// RUN: %clang_safestack %s -pthread -o %t +// RUN: not --crash %run %t + +// Test that unsafe stacks are deallocated correctly on thread exit. + +#include <stdlib.h> +#include <string.h> +#include <pthread.h> + +enum { kBufferSize = (1 << 15) }; + +void *t1_start(void *ptr) +{ + char buffer[kBufferSize]; + return buffer; +} + +int main(int argc, char **argv) +{ + pthread_t t1; + char *buffer = NULL; + + if (pthread_create(&t1, NULL, t1_start, NULL)) + abort(); + if (pthread_join(t1, &buffer)) + abort(); + + // should segfault here + memset(buffer, 0, kBufferSize); + return 0; +} diff --git a/test/safestack/pthread.c b/test/safestack/pthread.c new file mode 100644 index 000000000000..416586ee13e7 --- /dev/null +++ b/test/safestack/pthread.c @@ -0,0 +1,42 @@ +// RUN: %clang_safestack %s -pthread -o %t +// RUN: %run %t + +// XFAIL: darwin + +// Test that pthreads receive their own unsafe stack. + +#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include "utils.h" + +static int ptr_test = 42; + +void *t1_start(void *ptr) +{ + if (ptr != &ptr_test) + abort(); + + // safe stack + int val = ptr_test * 5; + + // unsafe stack + char buffer[8096]; // two pages + memset(buffer, val, sizeof (buffer)); + break_optimization(buffer); + + return ptr; +} + +int main(int argc, char **argv) +{ + pthread_t t1; + void *ptr = NULL; + if (pthread_create(&t1, NULL, t1_start, &ptr_test)) + abort(); + if (pthread_join(t1, &ptr)) + abort(); + if (ptr != &ptr_test) + abort(); + return 0; +} diff --git a/test/safestack/utils.h b/test/safestack/utils.h new file mode 100644 index 000000000000..b04e3bdc127e --- /dev/null +++ b/test/safestack/utils.h @@ -0,0 +1,8 @@ +#ifndef UTILS_H +#define UTILS_H + +static inline void break_optimization(void *arg) { + __asm__ __volatile__("" : : "r" (arg) : "memory"); +} + +#endif |