summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipe Cabecinhas <me@filcab.net>2016-02-27 19:57:44 +0000
committerFilipe Cabecinhas <me@filcab.net>2016-02-27 19:57:44 +0000
commitb7692bc3e9ad2691fc07261904b88fb15f30696b (patch)
tree9d736b0af062008f795da5b1a86adb5ba3012082
parentd3a746722145571d94123b9886deee7922e7083c (diff)
downloadbcm5719-llvm-b7692bc3e9ad2691fc07261904b88fb15f30696b.tar.gz
bcm5719-llvm-b7692bc3e9ad2691fc07261904b88fb15f30696b.zip
[UBSan] Fix isDerivedFromAtOffset on iOS ARM64
Summary: iOS on ARM64 doesn't unique RTTI. Ref: clang's iOS64CXXABI::shouldRTTIBeUnique() Due to this, pointer-equality will not necessarily work in this architecture, across dylib boundaries. dynamic_cast<>() will (as expected) still work, since Apple ships with one prepared for this, but we can't rely on the type names being pointer-equal. I've limited the expensive strcmp check to the specific architecture which needs it. Example which triggers this bug: lib.h: struct X { virtual ~X() {} }; X *libCall(); lib.mm: X *libCall() { return new X; } prog.mm: int main() { X *px = libCall(); delete px; } Expected output: Nothing Actual output: <unknown>: runtime error: member call on address 0x00017001ef50 which does not point to an object of type 'X' 0x00017001ef50: note: object is of type 'X' 00 00 00 00 60 00 0f 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^~~~~~~~~~~~~~~~~~~~~~~ vptr for ‘X’ Reviewers: kubabrecka, samsonov, eugenis, rsmith Subscribers: aemerson, llvm-commits, rengolin Differential Revision: http://reviews.llvm.org/D11502 llvm-svn: 262147
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform.h6
-rw-r--r--compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc4
-rw-r--r--compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/lit.local.cfg3
-rw-r--r--compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/vptr-non-unique-typeinfo-lib.cpp5
-rw-r--r--compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/vptr-non-unique-typeinfo-lib.h4
-rw-r--r--compiler-rt/test/ubsan/TestCases/TypeCheck/vptr-non-unique-typeinfo.cpp10
6 files changed, 31 insertions, 1 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
index 2925583efa2..c95c8f49791 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -162,4 +162,10 @@
# define MSC_PREREQ(version) 0
#endif
+#if defined(__arm64__) && SANITIZER_IOS
+# define SANITIZER_NON_UNIQUE_TYPEINFO 1
+#else
+# define SANITIZER_NON_UNIQUE_TYPEINFO 0
+#endif
+
#endif // SANITIZER_PLATFORM_H
diff --git a/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc b/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
index b84e88d4c71..c152eb88584 100644
--- a/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
+++ b/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
@@ -115,7 +115,9 @@ static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
const abi::__class_type_info *Base,
sptr Offset) {
- if (Derived->__type_name == Base->__type_name)
+ if (Derived->__type_name == Base->__type_name ||
+ (SANITIZER_NON_UNIQUE_TYPEINFO &&
+ !internal_strcmp(Derived->__type_name, Base->__type_name)))
return Offset == 0;
if (const abi::__si_class_type_info *SI =
diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/lit.local.cfg b/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/lit.local.cfg
new file mode 100644
index 00000000000..2fc4d99456b
--- /dev/null
+++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/lit.local.cfg
@@ -0,0 +1,3 @@
+# Sources in this directory are helper files for tests which test functionality
+# involving multiple translation units.
+config.suffixes = []
diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/vptr-non-unique-typeinfo-lib.cpp b/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/vptr-non-unique-typeinfo-lib.cpp
new file mode 100644
index 00000000000..f76ee0d79ab
--- /dev/null
+++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/vptr-non-unique-typeinfo-lib.cpp
@@ -0,0 +1,5 @@
+#include "vptr-non-unique-typeinfo-lib.h"
+
+X *libCall() {
+ return new X;
+}
diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/vptr-non-unique-typeinfo-lib.h b/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/vptr-non-unique-typeinfo-lib.h
new file mode 100644
index 00000000000..2fc173e61d0
--- /dev/null
+++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/Helpers/vptr-non-unique-typeinfo-lib.h
@@ -0,0 +1,4 @@
+struct X {
+ virtual ~X() {}
+};
+X *libCall();
diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr-non-unique-typeinfo.cpp b/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr-non-unique-typeinfo.cpp
new file mode 100644
index 00000000000..79acfe2ecf4
--- /dev/null
+++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr-non-unique-typeinfo.cpp
@@ -0,0 +1,10 @@
+// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -I%p/Helpers %p/Helpers/vptr-non-unique-typeinfo-lib.cpp -fPIC -shared -o %t-lib.so
+// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -I%p/Helpers -g %s -O3 -o %t %t-lib.so
+// RUN: %run %t
+
+#include "vptr-non-unique-typeinfo-lib.h"
+
+int main() {
+ X *px = libCall();
+ delete px;
+}
OpenPOWER on IntegriCloud