Home | History | Annotate | Download | only in cfi
      1 // RUN: %clangxx_cfi -o %t1 %s
      2 // RUN: %expect_crash %t1 a 2>&1 | FileCheck --check-prefix=FAIL %s
      3 // RUN: %expect_crash %t1 b 2>&1 | FileCheck --check-prefix=FAIL %s
      4 // RUN: %expect_crash %t1 c 2>&1 | FileCheck --check-prefix=FAIL %s
      5 // RUN: %t1 d 2>&1 | FileCheck --check-prefix=PASS %s
      6 // RUN: %t1 e 2>&1 | FileCheck --check-prefix=PASS %s
      7 // RUN: %t1 f 2>&1 | FileCheck --check-prefix=PASS %s
      8 // RUN: %expect_crash %t1 g 2>&1 | FileCheck --check-prefix=FAIL %s
      9 // RUN: %t1 h 2>&1 | FileCheck --check-prefix=PASS %s
     10 
     11 // RUN: %clangxx_cfi -DB32 -o %t2 %s
     12 // RUN: %expect_crash %t2 a 2>&1 | FileCheck --check-prefix=FAIL %s
     13 // RUN: %expect_crash %t2 b 2>&1 | FileCheck --check-prefix=FAIL %s
     14 // RUN: %expect_crash %t2 c 2>&1 | FileCheck --check-prefix=FAIL %s
     15 // RUN: %t2 d 2>&1 | FileCheck --check-prefix=PASS %s
     16 // RUN: %t2 e 2>&1 | FileCheck --check-prefix=PASS %s
     17 // RUN: %t2 f 2>&1 | FileCheck --check-prefix=PASS %s
     18 // RUN: %expect_crash %t2 g 2>&1 | FileCheck --check-prefix=FAIL %s
     19 // RUN: %t2 h 2>&1 | FileCheck --check-prefix=PASS %s
     20 
     21 // RUN: %clangxx_cfi -DB64 -o %t3 %s
     22 // RUN: %expect_crash %t3 a 2>&1 | FileCheck --check-prefix=FAIL %s
     23 // RUN: %expect_crash %t3 b 2>&1 | FileCheck --check-prefix=FAIL %s
     24 // RUN: %expect_crash %t3 c 2>&1 | FileCheck --check-prefix=FAIL %s
     25 // RUN: %t3 d 2>&1 | FileCheck --check-prefix=PASS %s
     26 // RUN: %t3 e 2>&1 | FileCheck --check-prefix=PASS %s
     27 // RUN: %t3 f 2>&1 | FileCheck --check-prefix=PASS %s
     28 // RUN: %expect_crash %t3 g 2>&1 | FileCheck --check-prefix=FAIL %s
     29 // RUN: %t3 h 2>&1 | FileCheck --check-prefix=PASS %s
     30 
     31 // RUN: %clangxx_cfi -DBM -o %t4 %s
     32 // RUN: %expect_crash %t4 a 2>&1 | FileCheck --check-prefix=FAIL %s
     33 // RUN: %expect_crash %t4 b 2>&1 | FileCheck --check-prefix=FAIL %s
     34 // RUN: %expect_crash %t4 c 2>&1 | FileCheck --check-prefix=FAIL %s
     35 // RUN: %t4 d 2>&1 | FileCheck --check-prefix=PASS %s
     36 // RUN: %t4 e 2>&1 | FileCheck --check-prefix=PASS %s
     37 // RUN: %t4 f 2>&1 | FileCheck --check-prefix=PASS %s
     38 // RUN: %expect_crash %t4 g 2>&1 | FileCheck --check-prefix=FAIL %s
     39 // RUN: %t4 h 2>&1 | FileCheck --check-prefix=PASS %s
     40 
     41 // RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t5 %s
     42 // RUN: %expect_crash %t5 a 2>&1 | FileCheck --check-prefix=FAIL %s
     43 // RUN: %expect_crash %t5 b 2>&1 | FileCheck --check-prefix=FAIL %s
     44 // RUN: %expect_crash %t5 c 2>&1 | FileCheck --check-prefix=FAIL %s
     45 // RUN: %expect_crash %t5 d 2>&1 | FileCheck --check-prefix=FAIL %s
     46 // RUN: %expect_crash %t5 e 2>&1 | FileCheck --check-prefix=FAIL %s
     47 // RUN: %expect_crash %t5 f 2>&1 | FileCheck --check-prefix=FAIL %s
     48 // RUN: %expect_crash %t5 g 2>&1 | FileCheck --check-prefix=FAIL %s
     49 // RUN: %expect_crash %t5 h 2>&1 | FileCheck --check-prefix=FAIL %s
     50 
     51 // RUN: %clangxx -o %t6 %s
     52 // RUN: %t6 a 2>&1 | FileCheck --check-prefix=PASS %s
     53 // RUN: %t6 b 2>&1 | FileCheck --check-prefix=PASS %s
     54 // RUN: %t6 c 2>&1 | FileCheck --check-prefix=PASS %s
     55 // RUN: %t6 d 2>&1 | FileCheck --check-prefix=PASS %s
     56 // RUN: %t6 e 2>&1 | FileCheck --check-prefix=PASS %s
     57 // RUN: %t6 f 2>&1 | FileCheck --check-prefix=PASS %s
     58 // RUN: %t6 g 2>&1 | FileCheck --check-prefix=PASS %s
     59 // RUN: %t6 h 2>&1 | FileCheck --check-prefix=PASS %s
     60 
     61 // RUN: %clangxx_cfi_diag -o %t7 %s
     62 // RUN: %t7 a 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
     63 // RUN: %t7 b 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
     64 // RUN: %t7 c 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s
     65 // RUN: %t7 g 2>&1 | FileCheck --check-prefix=CFI-DIAG-U %s
     66 
     67 // Tests that the CFI enforcement detects bad casts.
     68 
     69 // REQUIRES: cxxabi
     70 
     71 #include <stdio.h>
     72 #include "utils.h"
     73 
     74 struct A {
     75   virtual void f();
     76 };
     77 
     78 void A::f() {}
     79 
     80 struct B : A {
     81   virtual void f();
     82 };
     83 
     84 void B::f() {}
     85 
     86 struct C : A {
     87 };
     88 
     89 int main(int argc, char **argv) {
     90   create_derivers<B>();
     91 
     92   B *b = new B;
     93   break_optimization(b);
     94 
     95   // FAIL: 1
     96   // PASS: 1
     97   fprintf(stderr, "1\n");
     98 
     99   A a;
    100 
    101   // CFI-DIAG-D: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast
    102   // CFI-DIAG-D-NEXT: note: vtable is of type '{{(struct )?}}A'
    103 
    104   // CFI-DIAG-U: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type
    105   // CFI-DIAG-U-NEXT: note: vtable is of type '{{(struct )?}}A'
    106 
    107   switch (argv[1][0]) {
    108     case 'a':
    109       static_cast<B *>(&a); // UB
    110       break;
    111     case 'b':
    112       static_cast<B &>(a); // UB
    113       break;
    114     case 'c':
    115       static_cast<B &&>(a); // UB
    116       break;
    117     case 'd':
    118       static_cast<C *>(&a); // UB, strict only
    119       break;
    120     case 'e':
    121       static_cast<C &>(a); // UB, strict only
    122       break;
    123     case 'f':
    124       static_cast<C &&>(a); // UB, strict only
    125       break;
    126     case 'g':
    127       static_cast<B *>(static_cast<void *>(&a)); // Non-UB bad cast
    128       break;
    129     case 'h':
    130       static_cast<C *>(static_cast<void *>(&a)); // Non-UB bad cast, strict only
    131       break;
    132   }
    133 
    134   // FAIL-NOT: {{^2$}}
    135   // PASS: {{^2$}}
    136   fprintf(stderr, "2\n");
    137 }
    138