[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