1 // RUN: %clangxx_cfi -o %t1 %s 2 // RUN: %expect_crash %run %t1 2>&1 | FileCheck --check-prefix=CFI %s 3 4 // RUN: %clangxx_cfi -DB32 -o %t2 %s 5 // RUN: %expect_crash %run %t2 2>&1 | FileCheck --check-prefix=CFI %s 6 7 // RUN: %clangxx_cfi -DB64 -o %t3 %s 8 // RUN: %expect_crash %run %t3 2>&1 | FileCheck --check-prefix=CFI %s 9 10 // RUN: %clangxx_cfi -DBM -o %t4 %s 11 // RUN: %expect_crash %run %t4 2>&1 | FileCheck --check-prefix=CFI %s 12 13 // RUN: %clangxx_cfi -O1 -o %t5 %s 14 // RUN: %expect_crash %run %t5 2>&1 | FileCheck --check-prefix=CFI %s 15 16 // RUN: %clangxx_cfi -O1 -DB32 -o %t6 %s 17 // RUN: %expect_crash %run %t6 2>&1 | FileCheck --check-prefix=CFI %s 18 19 // RUN: %clangxx_cfi -O1 -DB64 -o %t7 %s 20 // RUN: %expect_crash %run %t7 2>&1 | FileCheck --check-prefix=CFI %s 21 22 // RUN: %clangxx_cfi -O1 -DBM -o %t8 %s 23 // RUN: %expect_crash %run %t8 2>&1 | FileCheck --check-prefix=CFI %s 24 25 // RUN: %clangxx_cfi -O2 -o %t9 %s 26 // RUN: %expect_crash %run %t9 2>&1 | FileCheck --check-prefix=CFI %s 27 28 // RUN: %clangxx_cfi -O2 -DB32 -o %t10 %s 29 // RUN: %expect_crash %run %t10 2>&1 | FileCheck --check-prefix=CFI %s 30 31 // RUN: %clangxx_cfi -O2 -DB64 -o %t11 %s 32 // RUN: %expect_crash %run %t11 2>&1 | FileCheck --check-prefix=CFI %s 33 34 // RUN: %clangxx_cfi -O2 -DBM -o %t12 %s 35 // RUN: %expect_crash %run %t12 2>&1 | FileCheck --check-prefix=CFI %s 36 37 // RUN: %clangxx_cfi -O3 -o %t13 %s 38 // RUN: %expect_crash %run %t13 2>&1 | FileCheck --check-prefix=CFI %s 39 40 // RUN: %clangxx_cfi -O3 -DB32 -o %t14 %s 41 // RUN: %expect_crash %run %t14 2>&1 | FileCheck --check-prefix=CFI %s 42 43 // RUN: %clangxx_cfi -O3 -DB64 -o %t15 %s 44 // RUN: %expect_crash %run %t15 2>&1 | FileCheck --check-prefix=CFI %s 45 46 // RUN: %clangxx_cfi -O3 -DBM -o %t16 %s 47 // RUN: %expect_crash %run %t16 2>&1 | FileCheck --check-prefix=CFI %s 48 49 // RUN: %clangxx_cfi_diag -o %t17 %s 50 // RUN: %run %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s 51 52 // RUN: %clangxx -o %t18 %s 53 // RUN: %run %t18 2>&1 | FileCheck --check-prefix=NCFI %s 54 55 // RUN: %clangxx_cfi -DCHECK_NO_SANITIZE_CFI -o %t19 %s 56 // RUN: %run %t19 2>&1 | FileCheck --check-prefix=NCFI %s 57 58 // Tests that the CFI mechanism crashes the program when making a virtual call 59 // to an object of the wrong class but with a compatible vtable, by casting a 60 // pointer to such an object and attempting to make a call through it. 61 62 // REQUIRES: cxxabi 63 64 #include <stdio.h> 65 #include "utils.h" 66 67 struct A { 68 virtual void f(); 69 }; 70 71 void A::f() {} 72 73 struct B { 74 virtual void f(); 75 }; 76 77 void B::f() {} 78 79 #if defined(CHECK_NO_SANITIZE_CFI) 80 __attribute__((no_sanitize("cfi"))) 81 #endif 82 int main() { 83 create_derivers<B>(); 84 85 A *a = new A; 86 break_optimization(a); 87 88 // CFI: 1 89 // NCFI: 1 90 fprintf(stderr, "1\n"); 91 92 // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type 93 // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A' 94 // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during virtual call 95 // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A' 96 ((B *)a)->f(); // UB here 97 98 // CFI-NOT: {{^2$}} 99 // NCFI: {{^2$}} 100 fprintf(stderr, "2\n"); 101 } 102