[compiler-rt] r359759 - Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO

Stephan Bergmann via llvm-commits llvm-commits at lists.llvm.org
Wed May 1 23:40:34 PDT 2019


Author: sberg
Date: Wed May  1 23:40:33 2019
New Revision: 359759

URL: http://llvm.org/viewvc/llvm-project?rev=359759&view=rev
Log:
Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO

This follows up after b7692bc3e9ad2691fc07261904b88fb15f30696b "[UBSan] Fix
isDerivedFromAtOffset on iOS ARM64" fixed the RTTI comparison in
isDerivedFromAtOffset on just one platform and then
a25a2c7c9a7e1e328a5bd8274d2d86b1fadc4692 "Always compare C++ typeinfo (based on
libstdc++ implementation)" extended that fix to more platforms.

But there is another RTTI comparison for -fsanitize=function generated in
clang's CodeGenFunction::EmitCall as just a pointer comparison.  For
SANITIZER_NON_UNIQUE_TYPEINFO platforms this needs to be extended to also do
string comparison.  For that, __ubsan_handle_function_type_mismatch[_abort]
takes the two std::type_info pointers as additional parameters now, checks them
internally for potential equivalence, and returns without reporting failure if
they turn out to be equivalent after all.  (NORETURN needed to be dropped from
the _abort variant for that.)  Also these functions depend on ABI-specific RTTI
now, so needed to be moved from plain UBSAN_SOURCES (ubsan_handlers.h/cc) to
UBSAN_CXXABI_SOURCES (ubsan_handlers_cxx.h/cc), but as -fsanitize=function is
only supported in C++ mode that's not a problem.

Differential Revision: https://reviews.llvm.org/D60760

Modified:
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
    compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
    compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h
    compiler-rt/trunk/lib/ubsan/ubsan_type_hash.h
    compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc
    compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc?rev=359759&r1=359758&r2=359759&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc Wed May  1 23:40:33 2019
@@ -598,42 +598,6 @@ void __ubsan::__ubsan_handle_invalid_bui
   Die();
 }
 
-static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
-                                       ValueHandle Function,
-                                       ReportOptions Opts) {
-  SourceLocation CallLoc = Data->Loc.acquire();
-  ErrorType ET = ErrorType::FunctionTypeMismatch;
-
-  if (ignoreReport(CallLoc, Opts, ET))
-    return;
-
-  ScopedReport R(Opts, CallLoc, ET);
-
-  SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));
-  const char *FName = FLoc.get()->info.function;
-  if (!FName)
-    FName = "(unknown)";
-
-  Diag(CallLoc, DL_Error, ET,
-       "call to function %0 through pointer to incorrect function type %1")
-      << FName << Data->Type;
-  Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
-}
-
-void
-__ubsan::__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data,
-                                               ValueHandle Function) {
-  GET_REPORT_OPTIONS(false);
-  handleFunctionTypeMismatch(Data, Function, Opts);
-}
-
-void __ubsan::__ubsan_handle_function_type_mismatch_abort(
-    FunctionTypeMismatchData *Data, ValueHandle Function) {
-  GET_REPORT_OPTIONS(true);
-  handleFunctionTypeMismatch(Data, Function, Opts);
-  Die();
-}
-
 static void handleNonNullReturn(NonNullReturnData *Data, SourceLocation *LocPtr,
                                 ReportOptions Opts, bool IsAttr) {
   if (!LocPtr)

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers.h?rev=359759&r1=359758&r2=359759&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.h Wed May  1 23:40:33 2019
@@ -168,15 +168,6 @@ struct InvalidBuiltinData {
 /// Handle a builtin called in an invalid way.
 RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data)
 
-struct FunctionTypeMismatchData {
-  SourceLocation Loc;
-  const TypeDescriptor &Type;
-};
-
-RECOVERABLE(function_type_mismatch,
-            FunctionTypeMismatchData *Data,
-            ValueHandle Val)
-
 struct NonNullReturnData {
   SourceLocation AttrLoc;
 };

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc?rev=359759&r1=359758&r2=359759&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc Wed May  1 23:40:33 2019
@@ -156,6 +156,51 @@ void __ubsan_handle_cfi_bad_type(CFIChec
     Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1")
         << SrcModule << DstModule;
 }
+
+static bool handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
+                                       ValueHandle Function,
+                                       ValueHandle calleeRTTI,
+                                       ValueHandle fnRTTI, ReportOptions Opts) {
+  if (checkTypeInfoEquality(reinterpret_cast<void *>(calleeRTTI),
+                            reinterpret_cast<void *>(fnRTTI)))
+    return false;
+
+  SourceLocation CallLoc = Data->Loc.acquire();
+  ErrorType ET = ErrorType::FunctionTypeMismatch;
+
+  if (ignoreReport(CallLoc, Opts, ET))
+    return true;
+
+  ScopedReport R(Opts, CallLoc, ET);
+
+  SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));
+  const char *FName = FLoc.get()->info.function;
+  if (!FName)
+    FName = "(unknown)";
+
+  Diag(CallLoc, DL_Error, ET,
+       "call to function %0 through pointer to incorrect function type %1")
+      << FName << Data->Type;
+  Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
+  return true;
+}
+
+void __ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data,
+                                           ValueHandle Function,
+                                           ValueHandle calleeRTTI,
+                                           ValueHandle fnRTTI) {
+  GET_REPORT_OPTIONS(false);
+  handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts);
+}
+
+void __ubsan_handle_function_type_mismatch_abort(FunctionTypeMismatchData *Data,
+                                                 ValueHandle Function,
+                                                 ValueHandle calleeRTTI,
+                                                 ValueHandle fnRTTI) {
+  GET_REPORT_OPTIONS(true);
+  if (handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts))
+    Die();
+}
 }  // namespace __ubsan
 
 #endif // CAN_SANITIZE_UB

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h?rev=359759&r1=359758&r2=359759&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h Wed May  1 23:40:33 2019
@@ -33,6 +33,21 @@ void __ubsan_handle_dynamic_type_cache_m
 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
 void __ubsan_handle_dynamic_type_cache_miss_abort(
   DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
+
+struct FunctionTypeMismatchData {
+  SourceLocation Loc;
+  const TypeDescriptor &Type;
+};
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
+__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data,
+                                      ValueHandle Val, ValueHandle calleeRTTI,
+                                      ValueHandle fnRTTI);
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
+__ubsan_handle_function_type_mismatch_abort(FunctionTypeMismatchData *Data,
+                                            ValueHandle Val,
+                                            ValueHandle calleeRTTI,
+                                            ValueHandle fnRTTI);
 }
 
 #endif // UBSAN_HANDLERS_H

Modified: compiler-rt/trunk/lib/ubsan/ubsan_type_hash.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash.h?rev=359759&r1=359758&r2=359759&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash.h Wed May  1 23:40:33 2019
@@ -64,6 +64,10 @@ const int VptrMaxOffsetToTop = 1<<20;
 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
 HashValue __ubsan_vptr_type_cache[VptrTypeCacheSize];
 
+/// \brief Do whatever is required by the ABI to check for std::type_info
+/// equivalence beyond simple pointer comparison.
+bool checkTypeInfoEquality(const void *TypeInfo1, const void *TypeInfo2);
+
 } // namespace __ubsan
 
 #endif // UBSAN_TYPE_HASH_H

Modified: compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc?rev=359759&r1=359758&r2=359759&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc Wed May  1 23:40:33 2019
@@ -117,9 +117,7 @@ static bool isDerivedFromAtOffset(const
                                   const abi::__class_type_info *Base,
                                   sptr Offset) {
   if (Derived->__type_name == Base->__type_name ||
-      (SANITIZER_NON_UNIQUE_TYPEINFO &&
-       Derived->__type_name[0] != '*' &&
-       !internal_strcmp(Derived->__type_name, Base->__type_name)))
+      __ubsan::checkTypeInfoEquality(Derived, Base))
     return Offset == 0;
 
   if (const abi::__si_class_type_info *SI =
@@ -258,4 +256,13 @@ __ubsan::getDynamicTypeInfoFromVtable(vo
                          ObjectType ? ObjectType->__type_name : "<unknown>");
 }
 
+bool __ubsan::checkTypeInfoEquality(const void *TypeInfo1,
+                                    const void *TypeInfo2) {
+  auto TI1 = static_cast<const std::type_info *>(TypeInfo1);
+  auto TI2 = static_cast<const std::type_info *>(TypeInfo2);
+  return SANITIZER_NON_UNIQUE_TYPEINFO && TI1->__type_name[0] != '*' &&
+         TI2->__type_name[0] != '*' &&
+         !internal_strcmp(TI1->__type_name, TI2->__type_name);
+}
+
 #endif  // CAN_SANITIZE_UB && !SANITIZER_WINDOWS

Modified: compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc?rev=359759&r1=359758&r2=359759&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc Wed May  1 23:40:33 2019
@@ -77,4 +77,9 @@ __ubsan::getDynamicTypeInfoFromVtable(vo
                          "<unknown>");
 }
 
+bool __ubsan::checkTypeInfoEquality(const std::type_info *,
+                                    const std::type_info *) {
+  return false;
+}
+
 #endif  // CAN_SANITIZE_UB && SANITIZER_WINDOWS




More information about the llvm-commits mailing list