• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clangxx_cfi -o %t %s
2 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
3 
4 // RUN: %clangxx_cfi -DB32 -o %t %s
5 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
6 
7 // RUN: %clangxx_cfi -DB64 -o %t %s
8 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
9 
10 // RUN: %clangxx_cfi -DBM -o %t %s
11 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s
12 
13 // RUN: %clangxx -o %t %s
14 // RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s
15 
16 // Tests that the CFI mechanism crashes the program when a virtual table is
17 // replaced with a compatible table of function pointers that does not belong to
18 // any class, by manually overwriting the virtual table of an object and
19 // attempting to make a call through it.
20 
21 #include <stdio.h>
22 #include "utils.h"
23 
24 struct A {
25   virtual void f();
26 };
27 
f()28 void A::f() {}
29 
foo()30 void foo() {
31   fprintf(stderr, "foo\n");
32 }
33 
34 void *fake_vtable[] = { (void *)&foo };
35 
main()36 int main() {
37 #ifdef B32
38   break_optimization(new Deriver<A, 0>);
39 #endif
40 
41 #ifdef B64
42   break_optimization(new Deriver<A, 0>);
43   break_optimization(new Deriver<A, 1>);
44 #endif
45 
46 #ifdef BM
47   break_optimization(new Deriver<A, 0>);
48   break_optimization(new Deriver<A, 1>);
49   break_optimization(new Deriver<A, 2>);
50 #endif
51 
52   A *a = new A;
53   *((void **)a) = fake_vtable; // UB here
54   break_optimization(a);
55 
56   // CFI: 1
57   // NCFI: 1
58   fprintf(stderr, "1\n");
59 
60   // CFI-NOT: foo
61   // NCFI: foo
62   a->f();
63 
64   // CFI-NOT: 2
65   // NCFI: 2
66   fprintf(stderr, "2\n");
67 }
68