[libcxxabi] Delay adjustment of pointer to prevent referencing invalid memory.
Summary: This patch delays the dereference adjustment until we are sure the thrown type is a pointer type. It is possible the thrown type is not a pointer and is smaller than `sizeof(void*)`. If the thrown type is is smaller than `sizeof(void*)` the deference adjustment will result in a heap buffer overflow. I audited all the call sites of `can_catch(...)` and there are no places where `adjustedPtr` is used if `can_catch(...)` returns false. For this reason the patch should not introduce any functionality change. This patch fixes the following tests when using ASAN: * unwind_01.cpp * unwind_02.cpp * unwind_04.cpp Reviewers: danalbert, jroelofs, mclow.lists Reviewed By: mclow.lists Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D6353 llvm-svn: 222674
This commit is contained in:
parent
909deebfc8
commit
90c138ea6d
|
@ -347,30 +347,34 @@ bool
|
|||
__pbase_type_info::can_catch(const __shim_type_info* thrown_type,
|
||||
void*&) const
|
||||
{
|
||||
if (is_equal(this, thrown_type, false))
|
||||
return true;
|
||||
return is_equal(thrown_type, &typeid(std::nullptr_t), false);
|
||||
return is_equal(this, thrown_type, false) ||
|
||||
is_equal(thrown_type, &typeid(std::nullptr_t), false);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
|
||||
// Handles bullets 1, 3 and 4
|
||||
// NOTE: It might not be safe to adjust the pointer if it is not not a pointer
|
||||
// type. Only adjust the pointer after we know it is safe to do so.
|
||||
bool
|
||||
__pointer_type_info::can_catch(const __shim_type_info* thrown_type,
|
||||
void*& adjustedPtr) const
|
||||
{
|
||||
// Do the dereference adjustment
|
||||
if (adjustedPtr != NULL)
|
||||
adjustedPtr = *static_cast<void**>(adjustedPtr);
|
||||
// bullets 1 and 4
|
||||
if (__pbase_type_info::can_catch(thrown_type, adjustedPtr))
|
||||
if (__pbase_type_info::can_catch(thrown_type, adjustedPtr)) {
|
||||
if (adjustedPtr != NULL)
|
||||
adjustedPtr = *static_cast<void**>(adjustedPtr);
|
||||
return true;
|
||||
}
|
||||
// bullet 3
|
||||
const __pointer_type_info* thrown_pointer_type =
|
||||
dynamic_cast<const __pointer_type_info*>(thrown_type);
|
||||
if (thrown_pointer_type == 0)
|
||||
return false;
|
||||
// Do the dereference adjustment
|
||||
if (adjustedPtr != NULL)
|
||||
adjustedPtr = *static_cast<void**>(adjustedPtr);
|
||||
// bullet 3B
|
||||
if (thrown_pointer_type->__flags & ~__flags)
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue