Skip to content

Commit

Permalink
[ASan][libcxx] A way to turn off annotations for containers with a sp…
Browse files Browse the repository at this point in the history
…ecific 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
  • Loading branch information
Advenam Tacet authored and philnik777 committed May 4, 2023
1 parent bfbe137 commit 2fa1bec
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
29 changes: 29 additions & 0 deletions libcxx/docs/UsingLibcxx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -523,3 +523,32 @@ Standard. Libc++ retroactively updates the Unicode Standard in older C++
versions. This allows the library to have better estimates for newly introduced
Unicode code points, without requiring the user to use the latest C++ version
in their code base.
=======
Turning off ASan annotation in containers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``__asan_annotate_container_with_allocator`` is a customization point to allow users to disable
`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.
This customization point exists only when ``_LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS`` Feature Test Macro is defined.

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.

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.

The annotations for a ``user_allocator`` can be disabled like this:

.. code-block:: cpp
#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
template <class T>
struct std::__asan_annotate_container_with_allocator<user_allocator<T>> : std::false_type {};
#endif
Why may I want to turn it off?
------------------------------

There are a few reasons why you may want to turn off annotations for an allocator.
Unpoisoning may not be an option, if (for example) you are not maintaining the allocator.

* You are using allocator, which does not call destructor during deallocation.
* You are aware that memory allocated with an allocator may be accessed, even when unused by container.
19 changes: 19 additions & 0 deletions libcxx/include/__memory/allocator_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,25 @@ struct __is_cpp17_copy_insertable<_Alloc, __enable_if_t<
: __is_cpp17_move_insertable<_Alloc>
{ };

// ASan choices
#ifndef _LIBCPP_HAS_NO_ASAN
# define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1
#endif

#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS
template <class _Alloc>
struct __asan_annotate_container_with_allocator
# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1600
: true_type {};
# else
// TODO LLVM18: Remove the special-casing
: false_type {};
# endif

template <class _Tp>
struct __asan_annotate_container_with_allocator<allocator<_Tp> > : true_type {};
#endif

#undef _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX

_LIBCPP_END_NAMESPACE_STD
Expand Down

0 comments on commit 2fa1bec

Please sign in to comment.