Skip to content

Commit 2fa1bec

Browse files
Advenam Tacetphilnik777
Advenam Tacet
authored andcommitted
[ASan][libcxx] A way to turn off annotations for containers with a specific allocator
This revision is part of our efforts to support container annotations with (almost) every allocator. That patch is necessary to enable support for most annotations (D136765). Without a way to turn off annotations, it's hard to use ASan with area allocators (no calls to destructors). This is an answer to a request about it. This patch provides a solution to the aforementioned issue by introducing a new template structure `__asan_annotate_container_with_allocator`, which allows the disabling of container annotations for a specific allocator. This patch also introduces `_LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS` FTM. To turn off annotations, it is sufficient to create a template specialization with a false value using a [Unary Type Trait](https://en.cppreference.com/w/cpp/types/integral_constant). The proposed structure is being used in the code enabling annotations for all allocators in `std::vector`, `std::basic_string`, and `std::deque`. (D136765 D146214 D146815) Possibility to do it was added to ASan API in rGdd1b7b797a116eed588fd752fbe61d34deeb24e4 commit. For context on not calling a destructor, look at https://eel.is/c++draft/basic.life#5 and notes there, you may also read a discussion in D136765. Reviewed By: ldionne, philnik, #libc, hans Spies: EricWF, mikhail.ramalho, #sanitizers, libcxx-commits, hans, vitalybuka Differential Revision: https://reviews.llvm.org/D145628
1 parent bfbe137 commit 2fa1bec

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

libcxx/docs/UsingLibcxx.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,3 +523,32 @@ Standard. Libc++ retroactively updates the Unicode Standard in older C++
523523
versions. This allows the library to have better estimates for newly introduced
524524
Unicode code points, without requiring the user to use the latest C++ version
525525
in their code base.
526+
=======
527+
Turning off ASan annotation in containers
528+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
529+
530+
``__asan_annotate_container_with_allocator`` is a customization point to allow users to disable
531+
`Address Sanitizer annotations for containers <https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow>`_ for specific allocators. This may be necessary for allocators that access allocated memory.
532+
This customization point exists only when ``_LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS`` Feature Test Macro is defined.
533+
534+
For allocators not running destructors, it is also possible to `bulk-unpoison memory <https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning>`_ instead of disabling annotations altogether.
535+
536+
The struct may be specialized for user-defined allocators. It is a `Cpp17UnaryTypeTrait <http://eel.is/c++draft/type.traits#meta.rqmts>`_ with a base characteristic of ``true_type`` if the container is allowed to use annotations and ``false_type`` otherwise.
537+
538+
The annotations for a ``user_allocator`` can be disabled like this:
539+
540+
.. code-block:: cpp
541+
542+
#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
543+
template <class T>
544+
struct std::__asan_annotate_container_with_allocator<user_allocator<T>> : std::false_type {};
545+
#endif
546+
547+
Why may I want to turn it off?
548+
------------------------------
549+
550+
There are a few reasons why you may want to turn off annotations for an allocator.
551+
Unpoisoning may not be an option, if (for example) you are not maintaining the allocator.
552+
553+
* You are using allocator, which does not call destructor during deallocation.
554+
* You are aware that memory allocated with an allocator may be accessed, even when unused by container.

libcxx/include/__memory/allocator_traits.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,25 @@ struct __is_cpp17_copy_insertable<_Alloc, __enable_if_t<
401401
: __is_cpp17_move_insertable<_Alloc>
402402
{ };
403403

404+
// ASan choices
405+
#ifndef _LIBCPP_HAS_NO_ASAN
406+
# define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1
407+
#endif
408+
409+
#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
410+
template <class _Alloc>
411+
struct __asan_annotate_container_with_allocator
412+
# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1600
413+
: true_type {};
414+
# else
415+
// TODO LLVM18: Remove the special-casing
416+
: false_type {};
417+
# endif
418+
419+
template <class _Tp>
420+
struct __asan_annotate_container_with_allocator<allocator<_Tp> > : true_type {};
421+
#endif
422+
404423
#undef _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX
405424

406425
_LIBCPP_END_NAMESPACE_STD

0 commit comments

Comments
 (0)