[PATCH] D11502: [UBSan] Fix isDerivedFromAtOffset on iOS ARM64

Filipe Cabecinhas filcab+llvm.phabricator at gmail.com
Fri Jul 24 23:57:41 PDT 2015


filcab created this revision.
filcab added reviewers: kubabrecka, samsonov, eugenis, rsmith.
filcab added a subscriber: llvm-commits.
Herald added subscribers: rengolin, aemerson.

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 still work, since Apple ships with one prepared
for this, but we can't rely on it by simply comparing the type names for
pointer-equality.

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’

Compilation is fairly straightforward (be sure to pass -isysroot,
-mios-min-version, etc). I ended up looking at what Xcode did to compile
and built a script.

No test since it doesn't seem we support anything related to running on
iOS devices. I couldn't even figure out a nice way to do it from the
command line.

http://reviews.llvm.org/D11502

Files:
  lib/sanitizer_common/sanitizer_platform.h
  lib/ubsan/ubsan_type_hash_itanium.cc

Index: lib/ubsan/ubsan_type_hash_itanium.cc
===================================================================
--- lib/ubsan/ubsan_type_hash_itanium.cc
+++ lib/ubsan/ubsan_type_hash_itanium.cc
@@ -115,7 +115,9 @@
 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 =
Index: lib/sanitizer_common/sanitizer_platform.h
===================================================================
--- lib/sanitizer_common/sanitizer_platform.h
+++ lib/sanitizer_common/sanitizer_platform.h
@@ -142,4 +142,10 @@
 # define HAVE_TIRPC_RPC_XDR_H 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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11502.30632.patch
Type: text/x-patch
Size: 1139 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150725/041cba9a/attachment.bin>


More information about the llvm-commits mailing list