This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [PATCH] Add AddressSanitizer annotations to std::vector
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Cc: Martin Liška <mliska at suse dot cz>, Jakub Jelinek <jakub at redhat dot com>
- Date: Wed, 5 Jul 2017 20:17:48 +0100
- Subject: Re: [PATCH] Add AddressSanitizer annotations to std::vector
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jwakely at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 48FC4A0218
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 48FC4A0218
- References: <20170705190010.GA19143@redhat.com>
On 05/07/17 20:00 +0100, Jonathan Wakely wrote:
We can probably do similar annotations for std::deque, so that
partially filled pages are annotated. I also have a patch for
shared_ptr so that objects created by make_shared can be marked as
invalid after they're destroyed.
This is the make_shared annotation patch. This allows ASan to give an
error for:
auto p = std::make_shared<int>();
std::weak_ptr<int> w = p;
int* pi = p.get();
p = nullptr;
return *pi;
The error isn't ideal, because ASan thinks we're using a container,
because that's what the annotations are intended for:
==4525==ERROR: AddressSanitizer: container-overflow
commit d0478d9fbd17b9e9d165b4893f784ae897531713
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue Jun 27 13:31:12 2017 +0100
Add AddressSanitizer annotations to std::make_shared
* include/bits/shared_ptr_base.h [_GLIBCXX_SANITIZE_STD_ALLOCATOR]
(__asan_annotate): Add.
(_Sp_counted_ptr_inplace::_M_dispose): Call __asan_annotate.
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
index 7e6766b..a720018 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -57,6 +57,12 @@
#include <bits/stl_function.h>
#include <ext/aligned_buffer.h>
+#if _GLIBCXX_SANITIZE_STD_ALLOCATOR
+extern "C" void
+__sanitizer_annotate_contiguous_container(const void*, const void*,
+ const void*, const void*);
+#endif
+
namespace std _GLIBCXX_VISIBILITY(default)
{
#if !__cpp_rtti
@@ -522,6 +528,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
};
+#if _GLIBCXX_SANITIZE_STD_ALLOCATOR
+ template<typename _Tp>
+ inline void
+ __asan_annotate(const void* __beg, const void* __mid, const void* __end,
+ const allocator<_Tp>&)
+ { __sanitizer_annotate_contiguous_container(__beg, __end, __end, __mid); }
+
+ template<typename _Alloc>
+ inline void
+ __asan_annotate(const void*, const void*, const void*, const _Alloc&)
+ { }
+#endif
+
template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
{
@@ -556,6 +575,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_dispose() noexcept
{
allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
+#if _GLIBCXX_SANITIZE_STD_ALLOCATOR
+ __asan_annotate(this, &_M_impl._M_storage, this + 1, _M_impl._M_alloc());
+#endif
}
// Override because the allocator needs to know the dynamic type