1// RUN: %clangxx_cfi_dso_diag -std=c++11 %s -o %t
2// RUN: %t zero 2>&1 | FileCheck --check-prefix=CHECK-ZERO %s
3// RUN: %t unaddressable 2>&1 | FileCheck --check-prefix=CHECK-UNADDR %s
4// RUN: %t 2>&1 | FileCheck --check-prefix=CHECK-TYPEINFO %s
5
6// RUN: %clangxx_cfi_diag -std=c++11 %s -o %t2
7// RUN: %t2 zero 2>&1 | FileCheck --check-prefix=CHECK-ZERO %s
8// RUN: %t2 unaddressable 2>&1 | FileCheck --check-prefix=CHECK-UNADDR %s
9// RUN: %t2 2>&1 | FileCheck --check-prefix=CHECK-TYPEINFO %s
10
11// REQUIRES: cxxabi
12
13// These checks are unsupported on newer versions of Android due to the
14// following patch that makes it harder to defeat ASLR by not mapping unused
15// shadow regions:
16// https://android-review.googlesource.com/c/platform/bionic/+/1333960
17// UNSUPPORTED: android
18
19#include <stdio.h>
20#include <stdint.h>
21#include <stdlib.h>
22#include <string.h>
23#include <sys/mman.h>
24
25struct A {
26 virtual void f();
27};
28
29void A::f() {}
30
31int main(int argc, char *argv[]) {
32 char *volatile p = reinterpret_cast<char *>(new A());
33 if (argc > 1 && strcmp(s1: argv[1], s2: "unaddressable") == 0) {
34 void *vtable = mmap(addr: nullptr, len: 4096, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, fd: 0, offset: 0);
35 // Create an object with a vtable in an unaddressable memory region.
36 *(uintptr_t *)p = (uintptr_t)vtable + 64;
37 // CHECK-UNADDR: runtime error: control flow integrity check for type 'A' failed during cast
38 // CHECK-UNADDR: note: invalid vtable
39 // CHECK-UNADDR: <memory cannot be printed>
40 // CHECK-UNADDR: runtime error: control flow integrity check for type 'A' failed during cast
41 // CHECK-UNADDR: note: invalid vtable
42 // CHECK-UNADDR: <memory cannot be printed>
43 } else if (argc > 1 && strcmp(s1: argv[1], s2: "zero") == 0) {
44 // Create an object with a vtable outside of any known DSO, but still in an
45 // addressable area.
46 void *vtable = calloc(nmemb: 1, size: 128);
47 *(uintptr_t *)p = (uintptr_t)vtable + 64;
48 // CHECK-ZERO: runtime error: control flow integrity check for type 'A' failed during cast
49 // CHECK-ZERO: note: invalid vtable
50 // CHECK-ZERO: 00 00 00 00 00 00 00 00
51 // CHECK-ZERO: runtime error: control flow integrity check for type 'A' failed during cast
52 // CHECK-ZERO: note: invalid vtable
53 // CHECK-ZERO: 00 00 00 00 00 00 00 00
54 } else {
55 // Create an object with a seemingly fine vtable, but with an unaddressable
56 // typeinfo pointer.
57 void *vtable = calloc(nmemb: 1, size: 128);
58 memset(s: vtable, c: 0xFE, n: 128);
59 *(uintptr_t *)p = (uintptr_t)vtable + 64;
60 // CHECK-TYPEINFO: runtime error: control flow integrity check for type 'A' failed during cast
61 // CHECK-TYPEINFO: note: invalid vtable
62 // CHECK-TYPEINFO: fe fe fe fe fe fe fe fe
63 // CHECK-TYPEINFO: runtime error: control flow integrity check for type 'A' failed during cast
64 // CHECK-TYPEINFO: note: invalid vtable
65 // CHECK-TYPEINFO: fe fe fe fe fe fe fe fe
66 }
67
68 A *volatile pa = reinterpret_cast<A *>(p);
69 pa = reinterpret_cast<A *>(p);
70}
71

source code of compiler-rt/test/cfi/cross-dso/target_out_of_bounds.cpp