<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/146106>146106</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[asan] Clarify how __sanitizer_annotate_contiguous_container works
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc++,
compiler-rt:asan
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ldionne
</td>
</tr>
</table>
<pre>
I was looking at libc++'s implementation of container ASAN annotations and I couldn't understand how `__sanitizer_annotate_contiguous_container` works. The documentation [here](https://github.com/llvm/llvm-project/blob/main/compiler-rt/include/sanitizer/common_interface_defs.h#L113-L159) says:
```
// This annotation tells the Sanitizer tool about the current state of the
/// container so that the tool can report errors when memory from
/// [mid, end) is accessed. Insert this annotation into methods like
/// push_back() or pop_back(). Supply the old and new values of
/// mid(old_mid and new_mid). In the initial
/// state mid == end, so that should be the final state when the
/// container is destroyed or when the container reallocates the storage.
```
This says that `[mid, end)` is the range considered invalid to access, which makes sense. However it also says that the initial state is `mid == end`, which means that the whole range `[begin, mid) == [begin, end)` is considered valid to access. Shouldn't the initial state be that `mid == begin` instead, so that the range `[mid, end) == the whole vector` be considered invalid to access?
This also ties into a question I have about our usage in libc++ (CC @AdvenamTacet):
```c++
template <class _Tp, class _Allocator>
void vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) {
__annotate_delete();
auto __new_begin = __v.__begin_ - (__end_ - __begin_);
std::__uninitialized_allocator_relocate(__alloc_, __begin_, __end_, __new_begin);
__v.__begin_ = __new_begin;
__end_ = __begin_; // All the objects have been destroyed by relocating them.
std::swap(this->__begin_, __v.__begin_);
std::swap(this->__end_, __v.__end_);
std::swap(this->__cap_, __v.__cap_);
__v.__first_ = __v.__begin_;
__annotate_new(size());
}
```
`__annotate_delete()` basically calls
```
__sanitizer_annotate_contiguous_container(data(), data() + capacity(),
data() + size(), data() + capacity());
```
If I understand correctly, this sets the sanitizer state to this (using the `beg` `end` `mid` terminology from the sanitizer documentation, not the terminology inside `std::vector`):
- `beg == data()`
- `end == data() + capacity()`
- `mid == data() + capacity()`
This means that after calling `__annotate_delete()`, ASAN would consider the range `[mid, end) == [data() + capacity(), data() + capacity) == empty-range` as invalid. Is that intended? Is the goal to mark the whole range as accessible so we can then touch it (in `__uninitialized_allocator_relocate`) without triggering an ASAN violation?
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyUV1Fv4roS_jXmZVSUOEDhgQdKD7qVju7L7nvkOAPxrWPn2g6I_fVXYycQ2t3bngrtJo7n8zffjMdj4b06GcQtW76w5etM9KGxbqtrZY3BWWXr6_YNLsKDtvZdmROIAFpVkvGX-Hv2oNpOY4smiKCsAXsEaU0QyqCD3Y_dv0EYY9NHD8LU8AbS9ro2jD8H6E2Nzgcab-wF2CorSy-MCuoXunIwxZIg1am3vS9v6GyVwcW6dz-Hnw1CbWV_p8GWLw06ZMtXxtdNCJ1nxY7xA-OHkwpNX82lbRk_aH0e_3vqnP0PysD4odK2YvzQCmUYP0jbdkqje3L0TRmp-xoZP9x4pjmtNaUyAd1RSCxrPPp5w3jxd54XT3_nyw3jG_DiGolk8bfKhl82UIOfjfITwSCg1h5Cg_BjXAyCtRpEZfsQP8jeOTQBPAlF8ocGb4CEeQ-HtxAakcwiihQGHHbWBUDnrPNwadBAi611Vzg62z4gseVLq2rG94CmJneIrJToPdZzeDMeHYE_uqBMsNBiaGztQav3R3Jd75uyEvKd8TUhWged7SYjc_jRd52-RtJW1zGFDF7gLHSPHuzxAS_yW1tdl626zS3j6IYoRhhFUgr9YJjkIyNWvLLiNbm4v2nmG0paqDAiHJURerCJkv1ZdOWhRh-cvWJN7o3TJ1McCq2tFAFTrH2wTpxw_jFHsl3MD0qiRIrGP8SEdoVKME6YU1zGqxod1qDMWWhVQ7BD2Mjs0ijZQCve0YNH43EO_7IXPBP1AEJ7O1lwot7gvfLE4oNuq2yCjMJMrC-N1SO1RL_CE22zfYrdZsSZfnlwbeLQB3fm8KO5l5bPXGPwkmwTwmkVwjY-oHiI-l3G30g9AtzdOqMMNham6gvhi8MkoFHkoNCnzSLgvz36uHneoBFnHHa77R30XpzIrUkVBsbX-z2wRbarz2hE-1NIDKTXp0Iz1u1sF7DtNGnCir3Uwnsof3bk2vCySwlpHSv-YtnubFU9elfsh6mPk4odK3Zl6S-iK20fSqmc7LVwZdUfj1Qj12XpO63COFDs4xYuw7VDghMj2jCyIlS-grI8R7GfiTdAeT8VatQYMNUJVqTPog8WypJ2fQwsBYkg5mV6L-EJIhc0NT2Pw3cIH-rRmd4MCaR-YV3eCTpM2zUCxeEyCnLDomdaID3dyEx4PlBKHO_TbnMiyfSX5gwLFBT1WGh2WqfSWNHZ5VO-VIhmUnWqKwyM6QgPDbbzB0cpZoyvqXI_seKvRzfuNCfs_2x695oM09s3zKToJmbp7YNWR-V8KD_F8z7plhcGL4yvvfo15sYIxZ5fP9fU2HP8PqdoIwuvpND6CvSv_3xyf79f4etaBDFS2sP9DWgbS9EJqcL1NiG69d2_D2BT579caVTnUZe3I7xN-zNpnUMZ9JUQ4ynvMQwH1q05SYU22DSB8XXvh5yjClrhiTRlqyydEkMlpqeArlXGantKjccH3IfujggYO_QxEzsVCy6B3hLtVpFv9fBpIDJW70lMoudPA73P33-n3d1kcqJ8w2Qs_ZPTURwDuphlpNj_zUoSIPbWl9iUjCfN944rtnz5KvP-7MENBdsuXJ_iYhQ-4cdDbg5vg0PUDJsaa1Yc0hjCyQpN2dEK9_6pHRBjN6kqjXQEXzB2qCF2TLaXDXUkjK-pqpM8X5bnGHa4qNDEbtmp0wldvMaYpN9ZWZ1SqjjM6m1Rb4qNmOE2f17m2SJfLFezZrvEilebYsF5zXnBBZcoNnmxlhKzrBD5TG15xpfZij_nK77IV_PnZS5WiJjnVS4KLtkiw1YoPad7xty600x53-M2X6zybDXTokLt4yWM8-n1ilMV4Hx6ASl2wgtDn5avM7eNF5eqP3m2yLTywd-XCCroeLOLBstX2Gvh1PEaL1rfrlrpijXrnd7-42tUdNIzfhj8PG_5_wIAAP__lMSazg">