diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:48 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:48 +0000 |
commit | 93c1b73a09a52d4a265f683bf1954b08bb430049 (patch) | |
tree | 5543464d74945196cc890e9d9099e5d0660df7eb /test/cfi | |
parent | 0d8e7490d6e8a13a8f0977d9b7771803b9f64ea0 (diff) | |
download | src-93c1b73a09a52d4a265f683bf1954b08bb430049.tar.gz src-93c1b73a09a52d4a265f683bf1954b08bb430049.zip |
Vendor import of compiler-rt trunk r338150:vendor/compiler-rt/compiler-rt-trunk-r338150
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=336817
svn path=/vendor/compiler-rt/compiler-rt-trunk-r338150/; revision=336818; tag=vendor/compiler-rt/compiler-rt-trunk-r338150
Diffstat (limited to 'test/cfi')
-rw-r--r-- | test/cfi/CMakeLists.txt | 22 | ||||
-rw-r--r-- | test/cfi/create-derivers.test | 6 | ||||
-rw-r--r-- | test/cfi/cross-dso-diagnostic.cpp | 47 | ||||
-rw-r--r-- | test/cfi/cross-dso/icall/dlopen.cpp | 6 | ||||
-rw-r--r-- | test/cfi/lit.site.cfg.in | 1 | ||||
-rw-r--r-- | test/cfi/mfcall.cpp | 96 | ||||
-rw-r--r-- | test/cfi/simple-pass.cpp | 5 | ||||
-rw-r--r-- | test/cfi/target_uninstrumented.cpp | 6 |
8 files changed, 174 insertions, 15 deletions
diff --git a/test/cfi/CMakeLists.txt b/test/cfi/CMakeLists.txt index c7fadde53095..4dbbf1759fcc 100644 --- a/test/cfi/CMakeLists.txt +++ b/test/cfi/CMakeLists.txt @@ -1,6 +1,6 @@ set(CFI_TESTSUITES) -macro (add_cfi_test_suites lld thinlto) +macro (add_cfi_test_suites lld thinlto newpm) set(suffix) if (${lld}) set(suffix ${suffix}-lld) @@ -8,10 +8,14 @@ macro (add_cfi_test_suites lld thinlto) if (${thinlto}) set(suffix ${suffix}-thinlto) endif() + if (${newpm}) + set(suffix ${suffix}-newpm) + endif() set(suffix ${suffix}-${CFI_TEST_TARGET_ARCH}) set(CFI_TEST_USE_LLD ${lld}) set(CFI_TEST_USE_THINLTO ${thinlto}) + set(CFI_TEST_USE_NEWPM ${newpm}) set(CFI_LIT_TEST_MODE Standalone) set(CFI_TEST_CONFIG_SUFFIX -standalone${suffix}) @@ -40,16 +44,18 @@ foreach(arch ${CFI_TEST_ARCH}) get_test_cc_for_arch(${arch} CFI_TEST_TARGET_CC CFI_TEST_TARGET_CFLAGS) if (APPLE) # FIXME: enable ThinLTO tests after fixing http://llvm.org/pr32741 - add_cfi_test_suites(False False) + add_cfi_test_suites(False False False) elseif(WIN32) - add_cfi_test_suites(True False) - add_cfi_test_suites(True True) + add_cfi_test_suites(True False False) + add_cfi_test_suites(True True False) else() - add_cfi_test_suites(False False) - add_cfi_test_suites(False True) + add_cfi_test_suites(False False False) + add_cfi_test_suites(False True False) + add_cfi_test_suites(False False True) + add_cfi_test_suites(False True True) if (COMPILER_RT_HAS_LLD AND NOT arch STREQUAL "i386") - add_cfi_test_suites(True False) - add_cfi_test_suites(True True) + add_cfi_test_suites(True False False) + add_cfi_test_suites(True True False) endif() endif() endforeach() diff --git a/test/cfi/create-derivers.test b/test/cfi/create-derivers.test index 8b569d001d89..b651d9be6bd9 100644 --- a/test/cfi/create-derivers.test +++ b/test/cfi/create-derivers.test @@ -7,15 +7,15 @@ B0: {{1B|B@@}}: {{.*}} size 1 RUN: %clangxx_cfi -DB32 -flto -c -o %t2.o %S/simple-fail.cpp RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t2.o 2>&1 | FileCheck --check-prefix=B32 %s -B32: {{1B|B@@}}: {{.*}} size 24 +B32: {{1B|B@@}}: {{.*}} size 2{{3|4}} B32-NOT: all-ones RUN: %clangxx_cfi -DB64 -flto -c -o %t3.o %S/simple-fail.cpp RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t3.o 2>&1 | FileCheck --check-prefix=B64 %s -B64: {{1B|B@@}}: {{.*}} size 54 +B64: {{1B|B@@}}: {{.*}} size 5{{3|4}} B64-NOT: all-ones RUN: %clangxx_cfi -DBM -flto -c -o %t4.o %S/simple-fail.cpp RUN: opt -lowertypetests -debug-only=lowertypetests -o /dev/null %t4.o 2>&1 | FileCheck --check-prefix=BM %s -BM: {{1B|B@@}}: {{.*}} size 84 +BM: {{1B|B@@}}: {{.*}} size 8{{3|4}} BM-NOT: all-ones diff --git a/test/cfi/cross-dso-diagnostic.cpp b/test/cfi/cross-dso-diagnostic.cpp new file mode 100644 index 000000000000..f3782dae0272 --- /dev/null +++ b/test/cfi/cross-dso-diagnostic.cpp @@ -0,0 +1,47 @@ +// Check that cross-DSO diagnostics print the names of both modules + +// RUN: %clangxx_cfi_diag -g -DSHARED_LIB -fPIC -shared -o %dynamiclib %s %ld_flags_rpath_so +// RUN: %clangxx_cfi_diag -g -o %t_exe_suffix %s %ld_flags_rpath_exe +// RUN: %t_exe_suffix 2>&1 | FileCheck -DDSONAME=%xdynamiclib_namespec %s + +// UNSUPPORTED: win32 +// REQUIRES: cxxabi + +#include <dlfcn.h> +#include <stdio.h> + +struct S1 { + virtual void f1(); +}; + +#ifdef SHARED_LIB + +void S1::f1() {} + +__attribute__((visibility("default"))) extern "C" +void* dso_symbol() { return new S1(); } + +#else + +int main() { + void* (*fp)(void) = + reinterpret_cast<void*(*)(void)>(dlsym(RTLD_DEFAULT, "dso_symbol")); + if (!fp) { + perror("failed to resolve dso_symbol"); + return 1; + } + + // CHECK: runtime error: control flow integrity check for type 'void *()' failed during indirect function call + // CHECK: dso_symbol defined here + // CHECK: check failed in {{.*}}_exe_suffix, destination function located in {{.*}}[[DSONAME]] + void *S = fp(); // trigger cfi-icall failure + + // CHECK: runtime error: control flow integrity check for type 'S1' failed during cast to unrelated type + // CHECK: invalid vtable + // CHECK: check failed in {{.*}}_exe_suffix, vtable located in {{.*}}[[DSONAME]] + S1 *Scast = reinterpret_cast<S1*>(S); // trigger cfi-unrelated-cast failure + + return 0; +} + +#endif // SHARED_LIB diff --git a/test/cfi/cross-dso/icall/dlopen.cpp b/test/cfi/cross-dso/icall/dlopen.cpp index d238a7acec89..c9674c3fb412 100644 --- a/test/cfi/cross-dso/icall/dlopen.cpp +++ b/test/cfi/cross-dso/icall/dlopen.cpp @@ -83,10 +83,12 @@ static void save_code(char *p) { } static void restore_code() { - char *code = (char *)mmap(real_start, kCodeSize, PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0); + char *code = + (char *)mmap(real_start, kCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0); assert(code == real_start); memcpy(code, saved_code, kCodeSize); + __builtin___clear_cache(code, code + kCodeSize); } int main(int argc, char *argv[]) { diff --git a/test/cfi/lit.site.cfg.in b/test/cfi/lit.site.cfg.in index eb9b44137fdf..a735e8812acd 100644 --- a/test/cfi/lit.site.cfg.in +++ b/test/cfi/lit.site.cfg.in @@ -7,6 +7,7 @@ config.target_cflags = "@CFI_TEST_TARGET_CFLAGS@" config.use_lld = @CFI_TEST_USE_LLD@ config.use_lto = True # CFI *requires* LTO. config.use_thinlto = @CFI_TEST_USE_THINLTO@ +config.use_newpm = @CFI_TEST_USE_NEWPM@ lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg") diff --git a/test/cfi/mfcall.cpp b/test/cfi/mfcall.cpp new file mode 100644 index 000000000000..6e22e3f3d711 --- /dev/null +++ b/test/cfi/mfcall.cpp @@ -0,0 +1,96 @@ +// UNSUPPORTED: win32 + +// RUN: %clangxx_cfi -o %t %s +// RUN: %expect_crash %run %t a +// RUN: %expect_crash %run %t b +// RUN: %expect_crash %run %t c +// RUN: %expect_crash %run %t d +// RUN: %expect_crash %run %t e +// RUN: %run %t f +// RUN: %run %t g + +// RUN: %clangxx_cfi_diag -o %t2 %s +// RUN: %run %t2 a 2>&1 | FileCheck --check-prefix=A %s +// RUN: %run %t2 b 2>&1 | FileCheck --check-prefix=B %s +// RUN: %run %t2 c 2>&1 | FileCheck --check-prefix=C %s +// RUN: %run %t2 d 2>&1 | FileCheck --check-prefix=D %s +// RUN: %run %t2 e 2>&1 | FileCheck --check-prefix=E %s + +#include <assert.h> +#include <string.h> + +struct SBase1 { + void b1() {} +}; + +struct SBase2 { + void b2() {} +}; + +struct S : SBase1, SBase2 { + void f1() {} + int f2() { return 1; } + virtual void g1() {} + virtual int g2() { return 1; } + virtual int g3() { return 1; } +}; + +struct T { + void f1() {} + int f2() { return 2; } + virtual void g1() {} + virtual int g2() { return 2; } + virtual void g3() {} +}; + +typedef void (S::*S_void)(); + +typedef int (S::*S_int)(); +typedef int (T::*T_int)(); + +template <typename To, typename From> +To bitcast(From f) { + assert(sizeof(To) == sizeof(From)); + To t; + memcpy(&t, &f, sizeof(f)); + return t; +} + +int main(int argc, char **argv) { + S s; + T t; + + switch (argv[1][0]) { + case 'a': + // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call + // A: note: S::f1() defined here + (s.*bitcast<S_int>(&S::f1))(); + break; + case 'b': + // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call + // B: note: S::f2() defined here + (t.*bitcast<T_int>(&S::f2))(); + break; + case 'c': + // C: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call + // C: note: vtable is of type 'S' + (s.*bitcast<S_int>(&S::g1))(); + break; + case 'd': + // D: runtime error: control flow integrity check for type 'int (S::*)()' failed during virtual pointer to member function call + // D: note: vtable is of type 'T' + (reinterpret_cast<S &>(t).*&S::g2)(); + break; + case 'e': + // E: runtime error: control flow integrity check for type 'void (S::*)()' failed during virtual pointer to member function call + // E: note: vtable is of type 'S' + (s.*bitcast<S_void>(&T::g3))(); + break; + case 'f': + (s.*&SBase1::b1)(); + break; + case 'g': + (s.*&SBase2::b2)(); + break; + } +} diff --git a/test/cfi/simple-pass.cpp b/test/cfi/simple-pass.cpp index aba09be2d816..de791fc1073f 100644 --- a/test/cfi/simple-pass.cpp +++ b/test/cfi/simple-pass.cpp @@ -1,5 +1,10 @@ +// -mretpoline does not work yet on Darwin. +// XFAIL: darwin + // RUN: %clangxx_cfi -o %t %s // RUN: %run %t +// RUN: %clangxx_cfi -mretpoline -o %t2 %s +// RUN: %run %t2 // Tests that the CFI mechanism does not crash the program when making various // kinds of valid calls involving classes with various different linkages and diff --git a/test/cfi/target_uninstrumented.cpp b/test/cfi/target_uninstrumented.cpp index 5df0738c078b..6379b7e12f44 100644 --- a/test/cfi/target_uninstrumented.cpp +++ b/test/cfi/target_uninstrumented.cpp @@ -32,12 +32,14 @@ void A::f() {} int main(int argc, char *argv[]) { void *p = create_B(); // CHECK: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type - // CHECK: invalid vtable in module {{.*}}libtarget_uninstrumented.cpp.dynamic.so + // CHECK: invalid vtable + // CHECK: check failed in {{.*}}, vtable located in {{.*}}libtarget_uninstrumented.cpp.dynamic.so A *a = (A *)p; memset(p, 0, sizeof(A)); + // CHECK: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type - // CHECK-NOT: invalid vtable in module // CHECK: invalid vtable + // CHECK: check failed in {{.*}}, vtable located in (unknown) a = (A *)p; // CHECK: done fprintf(stderr, "done %p\n", a); |