71 lines · cpp
1// RUN: %clangxx_cfi_dso_diag -std=c++11 %s -o %t2// RUN: %t zero 2>&1 | FileCheck --check-prefix=CHECK-ZERO %s3// RUN: %t unaddressable 2>&1 | FileCheck --check-prefix=CHECK-UNADDR %s4// RUN: %t 2>&1 | FileCheck --check-prefix=CHECK-TYPEINFO %s5 6// RUN: %clangxx_cfi_diag -std=c++11 %s -o %t27// RUN: %t2 zero 2>&1 | FileCheck --check-prefix=CHECK-ZERO %s8// RUN: %t2 unaddressable 2>&1 | FileCheck --check-prefix=CHECK-UNADDR %s9// RUN: %t2 2>&1 | FileCheck --check-prefix=CHECK-TYPEINFO %s10 11// REQUIRES: cxxabi12 13// These checks are unsupported on newer versions of Android due to the14// following patch that makes it harder to defeat ASLR by not mapping unused15// shadow regions:16// https://android-review.googlesource.com/c/platform/bionic/+/133396017// UNSUPPORTED: android18 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(argv[1], "unaddressable") == 0) {34 void *vtable = mmap(nullptr, 4096, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 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 cast38 // CHECK-UNADDR: note: invalid vtable39 // CHECK-UNADDR: <memory cannot be printed>40 // CHECK-UNADDR: runtime error: control flow integrity check for type 'A' failed during cast41 // CHECK-UNADDR: note: invalid vtable42 // CHECK-UNADDR: <memory cannot be printed>43 } else if (argc > 1 && strcmp(argv[1], "zero") == 0) {44 // Create an object with a vtable outside of any known DSO, but still in an45 // addressable area.46 void *vtable = calloc(1, 128);47 *(uintptr_t *)p = (uintptr_t)vtable + 64;48 // CHECK-ZERO: runtime error: control flow integrity check for type 'A' failed during cast49 // CHECK-ZERO: note: invalid vtable50 // CHECK-ZERO: 00 00 00 00 00 00 00 0051 // CHECK-ZERO: runtime error: control flow integrity check for type 'A' failed during cast52 // CHECK-ZERO: note: invalid vtable53 // CHECK-ZERO: 00 00 00 00 00 00 00 0054 } else {55 // Create an object with a seemingly fine vtable, but with an unaddressable56 // typeinfo pointer.57 void *vtable = calloc(1, 128);58 memset(vtable, 0xFE, 128);59 *(uintptr_t *)p = (uintptr_t)vtable + 64;60 // CHECK-TYPEINFO: runtime error: control flow integrity check for type 'A' failed during cast61 // CHECK-TYPEINFO: note: invalid vtable62 // CHECK-TYPEINFO: fe fe fe fe fe fe fe fe63 // CHECK-TYPEINFO: runtime error: control flow integrity check for type 'A' failed during cast64 // CHECK-TYPEINFO: note: invalid vtable65 // CHECK-TYPEINFO: fe fe fe fe fe fe fe fe66 }67 68 A *volatile pa = reinterpret_cast<A *>(p);69 pa = reinterpret_cast<A *>(p);70}71