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

Re-enable ASAN string annotations #3164

Merged
merged 33 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b1cfcde
initial attempt
strega-nil Oct 19, 2022
34bacc1
moar tests
strega-nil Oct 19, 2022
d51e580
CRs, plus some more minor work
strega-nil Oct 20, 2022
c62e749
minor code quality
strega-nil Oct 20, 2022
997f9b7
fix vector
strega-nil Oct 21, 2022
f108c24
fix stuff with testing
strega-nil Oct 24, 2022
86642d0
fixey fixey format
strega-nil Oct 24, 2022
277e68b
casey crs
strega-nil Oct 25, 2022
b76170a
fix comment
strega-nil Oct 25, 2022
99ea61a
moar fixin
strega-nil Oct 26, 2022
65dbe64
[ci skip] [wip] re-enable tests
strega-nil Oct 27, 2022
d869441
ooh, tests are passing!
strega-nil Nov 1, 2022
90ed742
oh okay, so you need to align both first and end
strega-nil Nov 1, 2022
7f52caa
CRs, plus fix vector test
strega-nil Nov 1, 2022
8afead5
add test for DevCom-10109507
strega-nil Nov 1, 2022
888cc8b
please tell me i actually fixed the tests this time
strega-nil Nov 1, 2022
dfaa6b1
ooh we can actually DO MORE
strega-nil Nov 1, 2022
42ef1a5
blampley blample more example
strega-nil Nov 2, 2022
9f503ca
remove noexcept from asan function
strega-nil Nov 2, 2022
f80f166
Amy CRs; force strings to be aligned on 4
strega-nil Nov 4, 2022
1641a6e
I dunno why this wasn't formatted
strega-nil Nov 4, 2022
f7cdbfb
Merge remote-tracking branch 'origin/main' into strega-nil/anno-asan01
strega-nil Nov 4, 2022
f12db09
Stephan CRs
strega-nil Nov 4, 2022
840cae1
misc cleanups
strega-nil Nov 4, 2022
6e37b5c
fix tests
strega-nil Nov 8, 2022
74f8320
forgot to format as I was copying back and forth
strega-nil Nov 8, 2022
cc418a3
zack's CRs
strega-nil Nov 8, 2022
f6984d8
xstring: remove memcpies in `_INSERT_STRING_ANNOTATION` mode
strega-nil Nov 14, 2022
13b122f
Merge remote-tracking branch 'origin/main' into strega-nil/anno-asan01
strega-nil Nov 21, 2022
ace0d8b
ughghghughuhughg
strega-nil Nov 21, 2022
b413060
Merge remote-tracking branch 'origin/main' into strega-nil/anno-asan01
strega-nil Dec 7, 2022
1f55a10
remove SBO annotations
strega-nil Dec 7, 2022
e38dd35
minor CRs
strega-nil Dec 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions stl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_format_ucd_tables.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_int128.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_iter_core.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_sanitizer_annotate_container.hpp
strega-nil-ms marked this conversation as resolved.
Show resolved Hide resolved
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_system_error_abi.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_tzdb.hpp
${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_xlocinfo_types.hpp
Expand Down
135 changes: 135 additions & 0 deletions stl/inc/__msvc_sanitizer_annotate_container.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// __msvc_sanitizer_annotate_container.hpp internal header

// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#pragma once
#ifndef __MSVC_SANITIZER_ANNOTATE_CONTAINER_HPP
#define __MSVC_SANITIZER_ANNOTATE_CONTAINER_HPP
#include <yvals_core.h>
#if _STL_COMPILER_PREPROCESSOR

strega-nil-ms marked this conversation as resolved.
Show resolved Hide resolved
#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new

#if !defined(_M_CEE_PURE) && !(defined(_DISABLE_STRING_ANNOTATION) && defined(_DISABLE_VECTOR_ANNOTATION))

#ifdef __SANITIZE_ADDRESS__

#define _ACTIVATE_STRING_ANNOTATION
#define _INSERT_STRING_ANNOTATION
#define _ACTIVATE_VECTOR_ANNOTATION
#define _INSERT_VECTOR_ANNOTATION

#elif defined(__clang__) // ^^^ __SANITIZE_ADDRESS__ / __clang__ vvv

#if __has_feature(address_sanitizer)
#define _ACTIVATE_STRING_ANNOTATION
#define _INSERT_STRING_ANNOTATION
#define _ACTIVATE_VECTOR_ANNOTATION
#define _INSERT_VECTOR_ANNOTATION
#pragma comment(linker, "/INFERASANLIBS")
#endif // __has_feature(address_sanitizer)

#else // ^^^ __clang__ / !__clang__ && !__SANITIZE_ADDRESS__ vvv

#ifdef _ANNOTATE_STRING
#define _INSERT_STRING_ANNOTATION
#endif // _ANNOTATE_STRING
#ifdef _ANNOTATE_VECTOR
#define _INSERT_VECTOR_ANNOTATION
#endif // _ANNOTATE_VECTOR

#endif // __SANITIZE_ADDRESS__

#ifdef _DISABLE_STRING_ANNOTATION
#undef _ACTIVATE_STRING_ANNOTATION
#undef _INSERT_STRING_ANNOTATION
#endif // _DISABLE_STRING_ANNOTATION
#ifdef _DISABLE_VECTOR_ANNOTATION
#undef _ACTIVATE_VECTOR_ANNOTATION
#undef _INSERT_VECTOR_ANNOTATION
#endif // _DISABLE_VECTOR_ANNOTATION

#ifndef _INSERT_STRING_ANNOTATION
#pragma detect_mismatch("annotate_string", "0")
#endif // !_INSERT_STRING_ANNOTATION
#ifndef _INSERT_VECTOR_ANNOTATION
#pragma detect_mismatch("annotate_vector", "0")
#endif // !_INSERT_VECTOR_ANNOTATION

#ifdef _ACTIVATE_STRING_ANNOTATION
#pragma comment(lib, "stl_asan")
#pragma detect_mismatch("annotate_string", "1")
#endif // _ACTIVATE_STRING_ANNOTATION
#ifdef _ACTIVATE_VECTOR_ANNOTATION
#pragma comment(lib, "stl_asan")
#pragma detect_mismatch("annotate_vector", "1")
#endif // _ACTIVATE_VECTOR_ANNOTATION

#undef _ACTIVATE_STRING_ANNOTATION
#undef _ACTIVATE_VECTOR_ANNOTATION

extern "C" {
#ifdef _INSERT_VECTOR_ANNOTATION
extern const bool _Asan_vector_should_annotate;
#endif

#ifdef _INSERT_STRING_ANNOTATION
extern const bool _Asan_string_should_annotate;
#endif
}

#if defined(_INSERT_VECTOR_ANNOTATION) || defined(_INSERT_STRING_ANNOTATION)
extern "C" {
void __cdecl __sanitizer_annotate_contiguous_container(
const void* _First, const void* _End, const void* _Old_last, const void* _New_last);
}

#ifdef _M_ARM64EC
#pragma comment(linker, \
"/alternatename:#__sanitizer_annotate_contiguous_container=#__sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, \
"/alternatename:__sanitizer_annotate_contiguous_container=__sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, "/alternatename:#_Asan_vector_should_annotate=#_Asan_vector_should_annotate_default")
#pragma comment(linker, "/alternatename:_Asan_vector_should_annotate=_Asan_vector_should_annotate_default")
#pragma comment(linker, "/alternatename:#_Asan_string_should_annotate=#_Asan_string_should_annotate_default")
#pragma comment(linker, "/alternatename:_Asan_string_should_annotate=_Asan_string_should_annotate_default")
#elif defined(_M_HYBRID)
#pragma comment(linker, \
"/alternatename:#__sanitizer_annotate_contiguous_container=#__sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, \
"/alternatename:___sanitizer_annotate_contiguous_container=___sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, "/alternatename:#_Asan_vector_should_annotate=#_Asan_vector_should_annotate_default")
#pragma comment(linker, "/alternatename:__Asan_vector_should_annotate=__Asan_vector_should_annotate_default")
#pragma comment(linker, "/alternatename:#_Asan_string_should_annotate=#_Asan_string_should_annotate_default")
#pragma comment(linker, "/alternatename:__Asan_string_should_annotate=__Asan_string_should_annotate_default")
#elif defined(_M_IX86)
#pragma comment(linker, \
"/alternatename:___sanitizer_annotate_contiguous_container=___sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, "/alternatename:__Asan_vector_should_annotate=__Asan_vector_should_annotate_default")
#pragma comment(linker, "/alternatename:__Asan_string_should_annotate=__Asan_string_should_annotate_default")
#elif defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64)
#pragma comment(linker, \
"/alternatename:__sanitizer_annotate_contiguous_container=__sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, "/alternatename:_Asan_vector_should_annotate=_Asan_vector_should_annotate_default")
#pragma comment(linker, "/alternatename:_Asan_string_should_annotate=_Asan_string_should_annotate_default")
#else // ^^^ known architecture / unknown architecture vvv
#error Unknown architecture
#endif // ^^^ unknown architecture ^^^

#endif // insert asan annotations

#endif // !_M_CEE_PURE && asan not disabled

#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma pack(pop)

#endif // _STL_COMPILER_PREPROCESSOR
#endif // __MSVC_SANITIZER_ANNOTATE_CONTAINER_HPP
1 change: 1 addition & 0 deletions stl/inc/header-units.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"__msvc_format_ucd_tables.hpp",
"__msvc_int128.hpp",
"__msvc_iter_core.hpp",
"__msvc_sanitizer_annotate_container.hpp",
"__msvc_system_error_abi.hpp",
"__msvc_tzdb.hpp",
"__msvc_xlocinfo_types.hpp",
Expand Down
131 changes: 30 additions & 101 deletions stl/inc/vector
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <xpolymorphic_allocator.h>
#endif // _HAS_CXX17

#include <__msvc_sanitizer_annotate_container.hpp>

#pragma pack(push, _CRT_PACKING)
#pragma warning(push, _STL_WARNING_LEVEL)
#pragma warning(disable : _STL_DISABLED_WARNINGS)
Expand Down Expand Up @@ -426,70 +428,6 @@ constexpr _Ty* _Unfancy_maybe_null(_Ty* _Ptr) noexcept { // do nothing for plain
return _Ptr;
}

#if !defined(_M_CEE_PURE) && !defined(_DISABLE_VECTOR_ANNOTATION)
#if defined(__SANITIZE_ADDRESS__)
#define _ACTIVATE_VECTOR_ANNOTATION
#define _INSERT_VECTOR_ANNOTATION
#elif defined(__clang__) && defined(__has_feature) // ^^^ __SANITIZE_ADDRESS__ / __clang__ vvv
#if __has_feature(address_sanitizer)
#define _ACTIVATE_VECTOR_ANNOTATION
#define _INSERT_VECTOR_ANNOTATION
#pragma comment(linker, "/INFERASANLIBS")
#endif // __has_feature(address_sanitizer)
#elif defined(_ANNOTATE_VECTOR) // ^^^ __clang__ / _ANNOTATE_VECTOR vvv
#define _INSERT_VECTOR_ANNOTATION
#endif // _ANNOTATE_VECTOR
#endif // !_M_CEE_PURE && !_DISABLE_VECTOR_ANNOTATION

#ifdef _ACTIVATE_VECTOR_ANNOTATION
#pragma comment(lib, "stl_asan")
#pragma detect_mismatch("annotate_vector", "1")
#endif // _ACTIVATE_VECTOR_ANNOTATION

#ifdef _INSERT_VECTOR_ANNOTATION
extern "C" {
void __cdecl __sanitizer_annotate_contiguous_container(
const void* _First, const void* _End, const void* _Old_last, const void* _New_last) noexcept;
extern const bool _Asan_vector_should_annotate;
}

#if defined(_M_ARM64EC)
#pragma comment(linker, \
"/alternatename:#__sanitizer_annotate_contiguous_container=#__sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, \
"/alternatename:__sanitizer_annotate_contiguous_container=__sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, "/alternatename:#_Asan_vector_should_annotate=#_Asan_vector_should_annotate_default")
#pragma comment(linker, "/alternatename:_Asan_vector_should_annotate=_Asan_vector_should_annotate_default")
#elif defined(_M_HYBRID)
#pragma comment(linker, \
"/alternatename:#__sanitizer_annotate_contiguous_container=#__sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, \
"/alternatename:___sanitizer_annotate_contiguous_container=___sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, "/alternatename:#_Asan_vector_should_annotate=#_Asan_vector_should_annotate_default")
#pragma comment(linker, "/alternatename:__Asan_vector_should_annotate=__Asan_vector_should_annotate_default")
#elif defined(_M_IX86)
#pragma comment(linker, \
"/alternatename:___sanitizer_annotate_contiguous_container=___sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, "/alternatename:__Asan_vector_should_annotate=__Asan_vector_should_annotate_default")
#elif defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64)
#pragma comment(linker, \
"/alternatename:__sanitizer_annotate_contiguous_container=__sanitizer_annotate_contiguous_container_default")
#pragma comment(linker, "/alternatename:_Asan_vector_should_annotate=_Asan_vector_should_annotate_default")
#else // ^^^ known architecture / unknown architecture vvv
#error Unknown architecture
#endif // ^^^ unknown architecture ^^^

template <class _Vec, class = void>
_INLINE_VAR constexpr bool _Has_minimum_allocation_alignment = alignof(typename _Vec::value_type) >= _Asan_granularity;

template <class _Vec>
_INLINE_VAR constexpr bool
_Has_minimum_allocation_alignment<_Vec, void_t<decltype(_Vec::allocator_type::_Minimum_allocation_alignment)>> =
_Vec::allocator_type::_Minimum_allocation_alignment >= _Asan_granularity;
#else // ^^^ _INSERT_VECTOR_ANNOTATION / !_INSERT_VECTOR_ANNOTATION vvv
#pragma detect_mismatch("annotate_vector", "0")
#endif // !_INSERT_VECTOR_ANNOTATION

_EXPORT_STD template <class _Ty, class _Alloc = allocator<_Ty>>
class vector { // varying size array of values
private:
Expand Down Expand Up @@ -539,29 +477,6 @@ private:
_Apply_annotation(_My_data._Myfirst, _My_data._Myend, _My_data._Mylast, _My_data._Mylast + _Count);
}

_NODISCARD static const void* _Get_aligned_first(const void* _First, const void* _End) noexcept {
const auto _CFirst = reinterpret_cast<const char*>(_First);
const auto _CEnd = reinterpret_cast<const char*>(_End);
const size_t _Capacity = static_cast<size_t>(_CEnd - _CFirst);

if (_Capacity >= _Asan_granularity) {
// We are guaranteed to have sufficient space to find an aligned address.
return reinterpret_cast<const void*>(
(reinterpret_cast<uintptr_t>(_CFirst) + (_Asan_granularity - 1)) & ~(_Asan_granularity - 1));
}

uintptr_t _Alignment_offset = reinterpret_cast<uintptr_t>(_CFirst) & (_Asan_granularity - 1);
if (_Alignment_offset != 0) {
_Alignment_offset = _Asan_granularity - _Alignment_offset;
}

if (_Capacity > _Alignment_offset) {
return _CFirst + _Alignment_offset;
}

return nullptr;
}

static _CONSTEXPR20 void _Apply_annotation(
pointer _First_, pointer _End_, pointer _Old_last_, pointer _New_last_) noexcept {
_STL_INTERNAL_CHECK(_First_ != nullptr);
Expand All @@ -579,24 +494,38 @@ private:
return;
}

const auto _First = reinterpret_cast<const char*>(_Unfancy(_First_));
const auto _End = reinterpret_cast<const char*>(_Unfancy(_End_));
const auto _Old_last = reinterpret_cast<const char*>(_Unfancy(_Old_last_));
const auto _New_last = reinterpret_cast<const char*>(_Unfancy(_New_last_));
if constexpr (_Has_minimum_allocation_alignment<vector>) {
__sanitizer_annotate_contiguous_container(_First, _End, _Old_last, _New_last);
const void* const _First = _STD _Unfancy(_First_);
const void* const _End = _STD _Unfancy(_End_);
const void* const _Old_last = _STD _Unfancy(_Old_last_);
const void* const _New_last = _STD _Unfancy(_New_last_);
if constexpr ((_Container_allocation_minimum_asan_alignment<vector>) >= _Asan_granularity) {
// old state:
// [_First, _Old_last) valid
// [_Old_last, _End) poison
// new state:
// [_First, _New_last) valid
// [_New_last, asan_aligned_after(_End)) poison
_CSTD __sanitizer_annotate_contiguous_container(
_First, _STD _Get_asan_aligned_after(_End), _Old_last, _New_last);
} else {
const void* const _Aligned_first = _Get_aligned_first(_First, _End);
if (!_Aligned_first) {
// There is no aligned address within the underlying buffer; nothing to do.
const auto _Aligned = _STD _Get_asan_aligned_first_end(_First, _End);
if (_Aligned._First == _Aligned._End) {
// The buffer does not end at least one shadow memory section; nothing to do.
return;
}

const void* const _Aligned_old_last = _Old_last < _Aligned_first ? _Aligned_first : _Old_last;
const void* const _Aligned_new_last = _New_last < _Aligned_first ? _Aligned_first : _New_last;
const void* const _Aligned_end = _End < _Aligned_first ? _Aligned_first : _End;
__sanitizer_annotate_contiguous_container(
_Aligned_first, _Aligned_end, _Aligned_old_last, _Aligned_new_last);
const void* const _Old_fixed = _Aligned._Clamp_to_end(_Old_last);
const void* const _New_fixed = _Aligned._Clamp_to_end(_New_last);

// old state:
// [_Aligned._First, _Old_fixed) valid
// [_Old_fixed, _Aligned._End) poison
// [_Aligned._End, _End) valid
// new state:
// [_Aligned._First, _New_fixed) valid
// [_New_fixed, _Aligned._End) poison
// [_Aligned._End, _End) valid
_CSTD __sanitizer_annotate_contiguous_container(_Aligned._First, _Aligned._End, _Old_fixed, _New_fixed);
strega-nil-ms marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
Loading