diff options
author | chefmax <chefmax@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-08 22:04:09 +0000 |
---|---|---|
committer | chefmax <chefmax@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-08 22:04:09 +0000 |
commit | 23e394371c5e8f4e51306c8e890a6707b782eb9d (patch) | |
tree | 9c1a8b279416b5f379d7631c1b7f36ab18797212 /libsanitizer/ubsan/ubsan_handlers_cxx.cc | |
parent | 23c2e114ba136dcbbc00435ec2c70a7f2a50bfef (diff) |
libsanitizer/
* All source files: Merge from upstream 285547.
* configure.tgt (SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS): New
variable.
* configure.ac (SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS): Handle it.
* asan/Makefile.am (asan_files): Add new files.
* asan/Makefile.in: Regenerate.
* ubsan/Makefile.in: Likewise.
* lsan/Makefile.in: Likewise.
* tsan/Makefile.am (tsan_files): Add new files.
* tsan/Makefile.in: Regenerate.
* sanitizer_common/Makefile.am (sanitizer_common_files): Add new files.
(EXTRA_libsanitizer_common_la_SOURCES): Define.
(libsanitizer_common_la_LIBADD): Likewise.
(libsanitizer_common_la_DEPENDENCIES): Likewise.
* sanitizer_common/Makefile.in: Regenerate.
* interception/Makefile.in: Likewise.
* libbacktace/Makefile.in: Likewise.
* Makefile.in: Likewise.
* configure: Likewise.
* merge.sh: Handle builtins/assembly.h merging.
* builtins/assembly.h: New file.
* asan/libtool-version: Bump the libasan SONAME.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241977 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer/ubsan/ubsan_handlers_cxx.cc')
-rw-r--r-- | libsanitizer/ubsan/ubsan_handlers_cxx.cc | 105 |
1 files changed, 65 insertions, 40 deletions
diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.cc b/libsanitizer/ubsan/ubsan_handlers_cxx.cc index b50b4d4636dc..015a9ffee022 100644 --- a/libsanitizer/ubsan/ubsan_handlers_cxx.cc +++ b/libsanitizer/ubsan/ubsan_handlers_cxx.cc @@ -13,6 +13,7 @@ #include "ubsan_platform.h" #if CAN_SANITIZE_UB +#include "ubsan_handlers.h" #include "ubsan_handlers_cxx.h" #include "ubsan_diag.h" #include "ubsan_type_hash.h" @@ -27,34 +28,42 @@ namespace __ubsan { extern const char *TypeCheckKinds[]; } -static void HandleDynamicTypeCacheMiss( +// Returns true if UBSan has printed an error report. +static bool HandleDynamicTypeCacheMiss( DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash, ReportOptions Opts) { if (checkDynamicType((void*)Pointer, Data->TypeInfo, Hash)) // Just a cache miss. The type matches after all. - return; + return false; // Check if error report should be suppressed. DynamicTypeInfo DTI = getDynamicTypeInfoFromObject((void*)Pointer); if (DTI.isValid() && IsVptrCheckSuppressed(DTI.getMostDerivedTypeName())) - return; + return false; SourceLocation Loc = Data->Loc.acquire(); - if (Loc.isDisabled()) - return; + ErrorType ET = ErrorType::DynamicTypeMismatch; + if (ignoreReport(Loc, Opts, ET)) + return false; - ScopedReport R(Opts, Loc, ErrorType::DynamicTypeMismatch); + ScopedReport R(Opts, Loc, ET); Diag(Loc, DL_Error, "%0 address %1 which does not point to an object of type %2") << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type; // If possible, say what type it actually points to. - if (!DTI.isValid()) - Diag(Pointer, DL_Note, "object has invalid vptr") - << TypeName(DTI.getMostDerivedTypeName()) - << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr"); - else if (!DTI.getOffset()) + if (!DTI.isValid()) { + if (DTI.getOffset() < -VptrMaxOffsetToTop || DTI.getOffset() > VptrMaxOffsetToTop) { + Diag(Pointer, DL_Note, "object has a possibly invalid vptr: abs(offset to top) too big") + << TypeName(DTI.getMostDerivedTypeName()) + << Range(Pointer, Pointer + sizeof(uptr), "possibly invalid vptr"); + } else { + Diag(Pointer, DL_Note, "object has invalid vptr") + << TypeName(DTI.getMostDerivedTypeName()) + << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr"); + } + } else if (!DTI.getOffset()) Diag(Pointer, DL_Note, "object is of type %0") << TypeName(DTI.getMostDerivedTypeName()) << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0"); @@ -67,6 +76,7 @@ static void HandleDynamicTypeCacheMiss( << TypeName(DTI.getSubobjectTypeName()) << Range(Pointer, Pointer + sizeof(uptr), "vptr for %2 base class of %1"); + return true; } void __ubsan::__ubsan_handle_dynamic_type_cache_miss( @@ -76,45 +86,60 @@ void __ubsan::__ubsan_handle_dynamic_type_cache_miss( } void __ubsan::__ubsan_handle_dynamic_type_cache_miss_abort( DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) { - GET_REPORT_OPTIONS(true); - HandleDynamicTypeCacheMiss(Data, Pointer, Hash, Opts); + // Note: -fsanitize=vptr is always recoverable. + GET_REPORT_OPTIONS(false); + if (HandleDynamicTypeCacheMiss(Data, Pointer, Hash, Opts)) + Die(); } -static void HandleCFIBadType(CFIBadTypeData *Data, ValueHandle Vtable, - ReportOptions Opts) { +namespace __ubsan { +void HandleCFIBadType(CFICheckFailData *Data, ValueHandle Vtable, + bool ValidVtable, ReportOptions Opts) { SourceLocation Loc = Data->Loc.acquire(); - ScopedReport R(Opts, Loc, ErrorType::CFIBadType); - DynamicTypeInfo DTI = getDynamicTypeInfoFromVtable((void*)Vtable); + ErrorType ET = ErrorType::CFIBadType; - static const char *TypeCheckKinds[] = { - "virtual call", - "non-virtual call", - "base-to-derived cast", - "cast to unrelated type", - }; + if (ignoreReport(Loc, Opts, ET)) + return; + + ScopedReport R(Opts, Loc, ET); + DynamicTypeInfo DTI = ValidVtable + ? getDynamicTypeInfoFromVtable((void *)Vtable) + : DynamicTypeInfo(0, 0, 0); + + const char *CheckKindStr; + switch (Data->CheckKind) { + case CFITCK_VCall: + CheckKindStr = "virtual call"; + break; + case CFITCK_NVCall: + CheckKindStr = "non-virtual call"; + break; + case CFITCK_DerivedCast: + CheckKindStr = "base-to-derived cast"; + break; + case CFITCK_UnrelatedCast: + CheckKindStr = "cast to unrelated type"; + break; + case CFITCK_ICall: + Die(); + } Diag(Loc, DL_Error, "control flow integrity check for type %0 failed during " "%1 (vtable address %2)") - << Data->Type << TypeCheckKinds[Data->TypeCheckKind] << (void *)Vtable; + << Data->Type << CheckKindStr << (void *)Vtable; // If possible, say what type it actually points to. - if (!DTI.isValid()) - Diag(Vtable, DL_Note, "invalid vtable"); - else + if (!DTI.isValid()) { + const char *module = Symbolizer::GetOrInit()->GetModuleNameForPc(Vtable); + if (module) + Diag(Vtable, DL_Note, "invalid vtable in module %0") << module; + else + Diag(Vtable, DL_Note, "invalid vtable"); + } else { Diag(Vtable, DL_Note, "vtable is of type %0") << TypeName(DTI.getMostDerivedTypeName()); + } } +} // namespace __ubsan -void __ubsan::__ubsan_handle_cfi_bad_type(CFIBadTypeData *Data, - ValueHandle Vtable) { - GET_REPORT_OPTIONS(false); - HandleCFIBadType(Data, Vtable, Opts); -} - -void __ubsan::__ubsan_handle_cfi_bad_type_abort(CFIBadTypeData *Data, - ValueHandle Vtable) { - GET_REPORT_OPTIONS(true); - HandleCFIBadType(Data, Vtable, Opts); -} - -#endif // CAN_SANITIZE_UB +#endif // CAN_SANITIZE_UB |