diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2015-06-19 01:51:54 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2015-06-19 01:51:54 +0000 |
commit | cbd703b159c95f7f4b7fa34071708aef6d3e5178 (patch) | |
tree | 88b4ebdc6a6ca8cfd5dc256cfeb20c0d1d2f7aa1 /test | |
parent | 683de155d77ede36b988847a171ddf8e66a4ac72 (diff) | |
download | clang-cbd703b159c95f7f4b7fa34071708aef6d3e5178.tar.gz |
Implement diagnostic mode for -fsanitize=cfi*, -fsanitize=cfi-diag.
This causes programs compiled with this flag to print a diagnostic when
a control flow integrity check fails instead of aborting. Diagnostics are
printed using UBSan's runtime library.
The main motivation of this feature over -fsanitize=vptr is fidelity with
the -fsanitize=cfi implementation: the diagnostics are printed under exactly
the same conditions as those which would cause -fsanitize=cfi to abort the
program. This means that the same restrictions apply regarding compiling
all translation units with -fsanitize=cfi, cross-DSO virtual calls are
forbidden, etc.
Differential Revision: http://reviews.llvm.org/D10268
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240109 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CodeGenCXX/cfi-cast.cpp | 18 | ||||
-rw-r--r-- | test/CodeGenCXX/cfi-vcall.cpp | 21 |
2 files changed, 25 insertions, 14 deletions
diff --git a/test/CodeGenCXX/cfi-cast.cpp b/test/CodeGenCXX/cfi-cast.cpp index c671bad7ef..0908963444 100644 --- a/test/CodeGenCXX/cfi-cast.cpp +++ b/test/CodeGenCXX/cfi-cast.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST-STRICT %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-derived-cast -fsanitize-trap=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast -fsanitize-trap=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast,cfi-cast-strict -fsanitize-trap=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST-STRICT %s // In this test the main thing we are searching for is something like // 'metadata !"1B"' where "1B" is the mangled name of the class we are @@ -19,7 +19,7 @@ struct C : A {}; // CHECK-DCAST-LABEL: define void @_Z3abpP1A void abp(A *a) { // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-DCAST: [[TRAPBB]] // CHECK-DCAST-NEXT: call void @llvm.trap() @@ -33,7 +33,7 @@ void abp(A *a) { // CHECK-DCAST-LABEL: define void @_Z3abrR1A void abr(A &a) { // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-DCAST: [[TRAPBB]] // CHECK-DCAST-NEXT: call void @llvm.trap() @@ -47,7 +47,7 @@ void abr(A &a) { // CHECK-DCAST-LABEL: define void @_Z4abrrO1A void abrr(A &&a) { // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-DCAST: [[TRAPBB]] // CHECK-DCAST-NEXT: call void @llvm.trap() @@ -61,7 +61,7 @@ void abrr(A &&a) { // CHECK-UCAST-LABEL: define void @_Z3vbpPv void vbp(void *p) { // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-UCAST: [[TRAPBB]] // CHECK-UCAST-NEXT: call void @llvm.trap() @@ -75,7 +75,7 @@ void vbp(void *p) { // CHECK-UCAST-LABEL: define void @_Z3vbrRc void vbr(char &r) { // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-UCAST: [[TRAPBB]] // CHECK-UCAST-NEXT: call void @llvm.trap() @@ -89,7 +89,7 @@ void vbr(char &r) { // CHECK-UCAST-LABEL: define void @_Z4vbrrOc void vbrr(char &&r) { // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") - // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ,]*]] // CHECK-UCAST: [[TRAPBB]] // CHECK-UCAST-NEXT: call void @llvm.trap() diff --git a/test/CodeGenCXX/cfi-vcall.cpp b/test/CodeGenCXX/cfi-vcall.cpp index b0f79d9ec0..ca5fe4104f 100644 --- a/test/CodeGenCXX/cfi-vcall.cpp +++ b/test/CodeGenCXX/cfi-vcall.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-trap=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NDIAG %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=DIAG --check-prefix=DIAG-ABORT %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -fsanitize-recover=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=DIAG --check-prefix=DIAG-RECOVER %s struct A { A(); @@ -33,14 +35,23 @@ void A::f() { void D::f() { } +// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}test/CodeGenCXX/cfi-vcall.cpp\00", align 1 +// DIAG: @[[TYPE:.*]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'A'\00" } +// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8 } { { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 58, i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]], i8 0 } + // CHECK: define void @_Z2afP1A void af(A *a) { - // CHECK: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1A") - // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + // CHECK: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* [[VT:%[^ ]*]], metadata !"1A") + // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ,]*]], label %[[TRAPBB:[^ ,]*]] // CHECK: [[TRAPBB]] - // CHECK-NEXT: call void @llvm.trap() - // CHECK-NEXT: unreachable + // NDIAG-NEXT: call void @llvm.trap() + // NDIAG-NEXT: unreachable + // DIAG-NEXT: [[VTINT:%[^ ]*]] = ptrtoint i8* [[VT]] to i64 + // DIAG-ABORT-NEXT: call void @__ubsan_handle_cfi_bad_type_abort(i8* bitcast ({{.*}} @[[BADTYPESTATIC]] to i8*), i64 [[VTINT]]) + // DIAG-ABORT-NEXT: unreachable + // DIAG-RECOVER-NEXT: call void @__ubsan_handle_cfi_bad_type(i8* bitcast ({{.*}} @[[BADTYPESTATIC]] to i8*), i64 [[VTINT]]) + // DIAG-RECOVER-NEXT: br label %[[CONTBB]] // CHECK: [[CONTBB]] // CHECK: call void % |