Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<xmemory>: Investigate ASan annotation for overaligned "big" allocations #5007

Open
CaseyCarter opened this issue Oct 10, 2024 · 0 comments
Open
Labels
ASan Address Sanitizer enhancement Something can be improved

Comments

@CaseyCarter
Copy link
Member

CaseyCarter commented Oct 10, 2024

The implementation of std::allocator::allocate boosts the alignment of large allocations to help vectorization be more effective:

STL/stl/inc/xmemory

Lines 208 to 228 in faccf00

#ifdef __cpp_aligned_new
if constexpr (_Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
size_t _Passed_align = _Align;
#if defined(_M_IX86) || defined(_M_X64)
if (_Bytes >= _Big_allocation_threshold) {
// boost the alignment of big allocations to help autovectorization
_Passed_align = (_STD max)(_Align, _Big_allocation_alignment);
}
#endif // defined(_M_IX86) || defined(_M_X64)
return _Traits::_Allocate_aligned(_Bytes, _Passed_align);
} else
#endif // defined(__cpp_aligned_new)
{
#if defined(_M_IX86) || defined(_M_X64)
if (_Bytes >= _Big_allocation_threshold) {
// boost the alignment of big allocations to help autovectorization
return _Allocate_manually_vector_aligned<_Traits>(_Bytes);
}
#endif // defined(_M_IX86) || defined(_M_X64)
return _Traits::_Allocate(_Bytes);
}

For allocations whose nominal alignment is at most __STDCPP_DEFAULT_NEW_ALIGNMENT__, we ask operator new for extra memory in order to perform the alignment manually:

STL/stl/inc/xmemory

Lines 152 to 169 in faccf00

template <class _Traits>
__declspec(allocator) void* _Allocate_manually_vector_aligned(const size_t _Bytes) {
// allocate _Bytes manually aligned to at least _Big_allocation_alignment
const size_t _Block_size = _Non_user_size + _Bytes;
if (_Block_size <= _Bytes) {
_Throw_bad_array_new_length(); // add overflow
}
const uintptr_t _Ptr_container = reinterpret_cast<uintptr_t>(_Traits::_Allocate(_Block_size));
_STL_VERIFY(_Ptr_container != 0, "invalid argument"); // validate even in release since we're doing p[-1]
void* const _Ptr = reinterpret_cast<void*>((_Ptr_container + _Non_user_size) & ~(_Big_allocation_alignment - 1));
static_cast<uintptr_t*>(_Ptr)[-1] = _Ptr_container;
#ifdef _DEBUG
static_cast<uintptr_t*>(_Ptr)[-2] = _Big_allocation_sentinel;
#endif // defined(_DEBUG)
return _Ptr;
}

It would be nice to enhance our ASan experience by poisoning the non-user space in these allocations to detect under/overflow. Doing so will probably require adding more symbols from sanitizer/asan_interface.h or sanitizer/common_interface.h to __msvc_sanitizer_annotate_container.hpp, as well as a new opt-out macro and detect_mismatch pragma.

@CaseyCarter CaseyCarter added ASan Address Sanitizer enhancement Something can be improved labels Oct 10, 2024
@CaseyCarter CaseyCarter changed the title Investigate ASan annotation for overaligned "big" allocations <xmemory>: Investigate ASan annotation for overaligned "big" allocations Oct 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ASan Address Sanitizer enhancement Something can be improved
Projects
None yet
Development

No branches or pull requests

1 participant