Currently we use RTTI objects to check type compatibility. To support non-unique RTTI objects, commit5745eccef5added a `checkTypeInfoEquality` string matching to the runtime. The scheme is inefficient. ``` _Z1fv: .long 846595819 # jmp .long .L__llvm_rtti_proxy-_Z3funv ... main: ... # Load the second word (pointer to the RTTI object) and dereference it. movslq 4(%rsi), %rax movq (%rax,%rsi), %rdx # Is it the desired typeinfo object? leaq _ZTIFvvE(%rip), %rax # If not, call __ubsan_handle_function_type_mismatch_v1, which may recover if checkTypeInfoEquality allows cmpq %rax, %rdx jne .LBB1_2 ... .section .data.rel.ro,"aw",@progbits .p2align 3, 0x0 .L__llvm_rtti_proxy: .quad _ZTIFvvE ``` Let's replace the indirect `_ZTI` pointer with a type hash similar to `-fsanitize=kcfi`. ``` _Z1fv: .long 3238382334 .long 2772461324 # type hash main: ... # Load the second word (callee type hash) and check whether it is expected cmpl $-1522505972, -4(%rax) # If not, fail: call __ubsan_handle_function_type_mismatch jne .LBB2_2 ``` The RTTI object derives its name from `clang::MangleContext::mangleCXXRTTI`, which uses `mangleType`. `mangleTypeName` uses `mangleType` as well. So the type compatibility change is high-fidelity. Since we no longer need RTTI pointers in `__ubsan::__ubsan_handle_function_type_mismatch_v1`, let's switch it back to version 0, the original signature beforee215996a29(2019). `__ubsan::__ubsan_handle_function_type_mismatch_abort` is not recoverable, so we can revert some changes frome215996a29. Reviewed By: samitolvanen Differential Revision: https://reviews.llvm.org/D148785
39 lines
1.4 KiB
C++
39 lines
1.4 KiB
C++
//===-- ubsan_handlers_cxx.h ------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Entry points to the runtime library for Clang's undefined behavior sanitizer,
|
|
// for C++-specific checks. This code is not linked into C binaries.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef UBSAN_HANDLERS_CXX_H
|
|
#define UBSAN_HANDLERS_CXX_H
|
|
|
|
#include "ubsan_value.h"
|
|
|
|
namespace __ubsan {
|
|
|
|
struct DynamicTypeCacheMissData {
|
|
SourceLocation Loc;
|
|
const TypeDescriptor &Type;
|
|
void *TypeInfo;
|
|
unsigned char TypeCheckKind;
|
|
};
|
|
|
|
/// \brief Handle a runtime type check failure, caused by an incorrect vptr.
|
|
/// When this handler is called, all we know is that the type was not in the
|
|
/// cache; this does not necessarily imply the existence of a bug.
|
|
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
|
void __ubsan_handle_dynamic_type_cache_miss(
|
|
DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
|
|
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
|
|
void __ubsan_handle_dynamic_type_cache_miss_abort(
|
|
DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
|
|
}
|
|
|
|
#endif // UBSAN_HANDLERS_CXX_H
|