summaryrefslogtreecommitdiff
path: root/test/ubsan
diff options
context:
space:
mode:
authorIvan Krasin <krasin@chromium.org>2016-06-02 18:36:12 +0000
committerIvan Krasin <krasin@chromium.org>2016-06-02 18:36:12 +0000
commit4deefb03523c51ca2eba3fabff692a47f24e1bfa (patch)
treee50a8e561e9ffb94226b6a69ab4cfa88b63b0bb3 /test/ubsan
parente151fbe8a11f85f4b0577ab3d27ef5254c3c4f74 (diff)
UBSan: crash less often on corrupted Vtables.
Summary: This CL adds a weak check for a Vtable prefix: for a well-formed Vtable, we require the prefix to be within [-1<<20; 1<<20]. Practically, this solves most of the known cases when UBSan segfaults without providing any useful diagnostics. Reviewers: pcc Subscribers: kubabrecka Differential Revision: http://reviews.llvm.org/D19750 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@271560 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/ubsan')
-rw-r--r--test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp b/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp
new file mode 100644
index 000000000..37ffe5b70
--- /dev/null
+++ b/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp
@@ -0,0 +1,41 @@
+// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-CORRUPTED-VTABLE --strict-whitespace
+
+// UNSUPPORTED: win32
+// REQUIRES: stable-runtime, cxxabi
+#include <cstddef>
+
+#include <typeinfo>
+
+struct S {
+ S() {}
+ ~S() {}
+ virtual int v() { return 0; }
+};
+
+// See the proper definition in ubsan_type_hash_itanium.cc
+struct VtablePrefix {
+ signed long Offset;
+ std::type_info *TypeInfo;
+};
+
+int main(int argc, char **argv) {
+ // Test that we don't crash on corrupted vtable when
+ // offset is too large or too small.
+ S Obj;
+ void *Ptr = &Obj;
+ VtablePrefix* RealPrefix = reinterpret_cast<VtablePrefix*>(
+ *reinterpret_cast<void**>(Ptr)) - 1;
+
+ VtablePrefix Prefix[2];
+ Prefix[0].Offset = 1<<21; // Greater than VptrMaxOffset
+ Prefix[0].TypeInfo = RealPrefix->TypeInfo;
+
+ // Hack Vtable ptr for Obj.
+ *reinterpret_cast<void**>(Ptr) = static_cast<void*>(&Prefix[1]);
+
+ // CHECK-CORRUPTED-VTABLE: vptr-corrupted-vtable-itanium.cpp:[[@LINE+3]]:16: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'S'
+ // CHECK-CORRUPTED-VTABLE-NEXT: [[PTR]]: note: object has a possibly invalid vptr: abs(offset to top) too big
+ S* Ptr2 = reinterpret_cast<S*>(Ptr);
+ return Ptr2->v();
+}