xref: /aosp_15_r20/external/compiler-rt/test/cfi/cross-dso/simple-fail.cpp (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso -DSHARED_LIB %s -fPIC -shared -o %t1-so.so
2*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso %s -o %t1 %t1-so.so
3*7c3d14c8STreehugger Robot // RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s
4*7c3d14c8STreehugger Robot // RUN: %expect_crash %t1 x 2>&1 | FileCheck --check-prefix=CFI-CAST %s
5*7c3d14c8STreehugger Robot 
6*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso -DB32 -DSHARED_LIB %s -fPIC -shared -o %t2-so.so
7*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso -DB32 %s -o %t2 %t2-so.so
8*7c3d14c8STreehugger Robot // RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s
9*7c3d14c8STreehugger Robot // RUN: %expect_crash %t2 x 2>&1 | FileCheck --check-prefix=CFI-CAST %s
10*7c3d14c8STreehugger Robot 
11*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso -DB64 -DSHARED_LIB %s -fPIC -shared -o %t3-so.so
12*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso -DB64 %s -o %t3 %t3-so.so
13*7c3d14c8STreehugger Robot // RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s
14*7c3d14c8STreehugger Robot // RUN: %expect_crash %t3 x 2>&1 | FileCheck --check-prefix=CFI-CAST %s
15*7c3d14c8STreehugger Robot 
16*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso -DBM -DSHARED_LIB %s -fPIC -shared -o %t4-so.so
17*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso -DBM %s -o %t4 %t4-so.so
18*7c3d14c8STreehugger Robot // RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s
19*7c3d14c8STreehugger Robot // RUN: %expect_crash %t4 x 2>&1 | FileCheck --check-prefix=CFI-CAST %s
20*7c3d14c8STreehugger Robot 
21*7c3d14c8STreehugger Robot // RUN: %clangxx -DBM -DSHARED_LIB %s -fPIC -shared -o %t5-so.so
22*7c3d14c8STreehugger Robot // RUN: %clangxx -DBM %s -o %t5 %t5-so.so
23*7c3d14c8STreehugger Robot // RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s
24*7c3d14c8STreehugger Robot // RUN: %t5 x 2>&1 | FileCheck --check-prefix=NCFI %s
25*7c3d14c8STreehugger Robot 
26*7c3d14c8STreehugger Robot // RUN: %clangxx -DBM -DSHARED_LIB %s -fPIC -shared -o %t6-so.so
27*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso -DBM %s -o %t6 %t6-so.so
28*7c3d14c8STreehugger Robot // RUN: %t6 2>&1 | FileCheck --check-prefix=NCFI %s
29*7c3d14c8STreehugger Robot // RUN: %t6 x 2>&1 | FileCheck --check-prefix=NCFI %s
30*7c3d14c8STreehugger Robot 
31*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso_diag -DSHARED_LIB %s -fPIC -shared -o %t7-so.so
32*7c3d14c8STreehugger Robot // RUN: %clangxx_cfi_dso_diag %s -o %t7 %t7-so.so
33*7c3d14c8STreehugger Robot // RUN: %t7 2>&1 | FileCheck --check-prefix=CFI-DIAG-CALL %s
34*7c3d14c8STreehugger Robot // RUN: %t7 x 2>&1 | FileCheck --check-prefix=CFI-DIAG-CALL --check-prefix=CFI-DIAG-CAST %s
35*7c3d14c8STreehugger Robot 
36*7c3d14c8STreehugger Robot // Tests that the CFI mechanism crashes the program when making a virtual call
37*7c3d14c8STreehugger Robot // to an object of the wrong class but with a compatible vtable, by casting a
38*7c3d14c8STreehugger Robot // pointer to such an object and attempting to make a call through it.
39*7c3d14c8STreehugger Robot 
40*7c3d14c8STreehugger Robot // REQUIRES: cxxabi
41*7c3d14c8STreehugger Robot 
42*7c3d14c8STreehugger Robot #include <stdio.h>
43*7c3d14c8STreehugger Robot #include <string.h>
44*7c3d14c8STreehugger Robot 
45*7c3d14c8STreehugger Robot struct A {
46*7c3d14c8STreehugger Robot   virtual void f();
47*7c3d14c8STreehugger Robot };
48*7c3d14c8STreehugger Robot 
49*7c3d14c8STreehugger Robot void *create_B();
50*7c3d14c8STreehugger Robot 
51*7c3d14c8STreehugger Robot #ifdef SHARED_LIB
52*7c3d14c8STreehugger Robot 
53*7c3d14c8STreehugger Robot #include "../utils.h"
54*7c3d14c8STreehugger Robot struct B {
55*7c3d14c8STreehugger Robot   virtual void f();
56*7c3d14c8STreehugger Robot };
f()57*7c3d14c8STreehugger Robot void B::f() {}
58*7c3d14c8STreehugger Robot 
create_B()59*7c3d14c8STreehugger Robot void *create_B() {
60*7c3d14c8STreehugger Robot   create_derivers<B>();
61*7c3d14c8STreehugger Robot   return (void *)(new B());
62*7c3d14c8STreehugger Robot }
63*7c3d14c8STreehugger Robot 
64*7c3d14c8STreehugger Robot #else
65*7c3d14c8STreehugger Robot 
f()66*7c3d14c8STreehugger Robot void A::f() {}
67*7c3d14c8STreehugger Robot 
main(int argc,char * argv[])68*7c3d14c8STreehugger Robot int main(int argc, char *argv[]) {
69*7c3d14c8STreehugger Robot   void *p = create_B();
70*7c3d14c8STreehugger Robot   A *a;
71*7c3d14c8STreehugger Robot 
72*7c3d14c8STreehugger Robot   // CFI: =0=
73*7c3d14c8STreehugger Robot   // CFI-CAST: =0=
74*7c3d14c8STreehugger Robot   // NCFI: =0=
75*7c3d14c8STreehugger Robot   fprintf(stderr, "=0=\n");
76*7c3d14c8STreehugger Robot 
77*7c3d14c8STreehugger Robot   if (argc > 1 && argv[1][0] == 'x') {
78*7c3d14c8STreehugger Robot     // Test cast. BOOM.
79*7c3d14c8STreehugger Robot     // CFI-DIAG-CAST: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
80*7c3d14c8STreehugger Robot     // CFI-DIAG-CAST-NEXT: note: vtable is of type '{{(struct )?}}B'
81*7c3d14c8STreehugger Robot     a = (A*)p;
82*7c3d14c8STreehugger Robot   } else {
83*7c3d14c8STreehugger Robot     // Invisible to CFI. Test virtual call later.
84*7c3d14c8STreehugger Robot     memcpy(&a, &p, sizeof(a));
85*7c3d14c8STreehugger Robot   }
86*7c3d14c8STreehugger Robot 
87*7c3d14c8STreehugger Robot   // CFI: =1=
88*7c3d14c8STreehugger Robot   // CFI-CAST-NOT: =1=
89*7c3d14c8STreehugger Robot   // NCFI: =1=
90*7c3d14c8STreehugger Robot   fprintf(stderr, "=1=\n");
91*7c3d14c8STreehugger Robot 
92*7c3d14c8STreehugger Robot   // CFI-DIAG-CALL: runtime error: control flow integrity check for type 'A' failed during virtual call
93*7c3d14c8STreehugger Robot   // CFI-DIAG-CALL-NEXT: note: vtable is of type '{{(struct )?}}B'
94*7c3d14c8STreehugger Robot   a->f(); // UB here
95*7c3d14c8STreehugger Robot 
96*7c3d14c8STreehugger Robot   // CFI-NOT: =2=
97*7c3d14c8STreehugger Robot   // CFI-CAST-NOT: =2=
98*7c3d14c8STreehugger Robot   // NCFI: =2=
99*7c3d14c8STreehugger Robot   fprintf(stderr, "=2=\n");
100*7c3d14c8STreehugger Robot }
101*7c3d14c8STreehugger Robot #endif
102