https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97659

            Bug ID: 97659
           Summary: Invalid pointer subtraction in vector::insert()
                    (reported by pointer-subtract AddressSanitizer)
           Product: gcc
           Version: 10.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: chfast at gmail dot com
  Target Milestone: ---

When vector<uint8_t>::insert(iterator pos, InputIt first, InputIt last) is used
the AddressSanitizer additional check "pointer-subtract" reports invalid
pointer pair in c++/10/bits/vector.tcc:729.

The relevant code is this:

  template<typename _Tp, typename _Alloc>
    template<typename _ForwardIterator>
      void
      vector<_Tp, _Alloc>::
      _M_range_insert(iterator __position, _ForwardIterator __first,
                      _ForwardIterator __last, std::forward_iterator_tag)
      {
        if (__first != __last)
          {
            const size_type __n = std::distance(__first, __last);
            if (size_type(this->_M_impl._M_end_of_storage
                          - this->_M_impl._M_finish) >= __n)  // FAILS HERE!
              {


My core code causing the problem is this:

void push(std::vector<uint8_t>& b, uint32_t value)
{
    uint8_t storage[sizeof(value)];
    __builtin_memcpy(storage, &value, sizeof(value));
    b.insert(b.end(), std::begin(storage), std::end(storage));
}


My program is pushing single bytes and uint32_t value using the above helper to
a vector, without preallocation. But I was not able to reproduce this issues on
a side. I will need more time to reduce my code to a proper regression test.

gcc-10 (Ubuntu 10.2.0-5ubuntu1~20.04) 10.2.0
export ASAN_OPTIONS=detect_invalid_pointer_pairs=1 

=================================================================
==3327279==ERROR: AddressSanitizer: invalid-pointer-pair: 0x602000006e5c
0x602000006e5a
    #0 0x556e32bfecbf in void std::vector<unsigned char,
std::allocator<unsigned char> >::_M_range_insert<unsigned
char*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char,
std::allocator<unsigned char> > >, unsigned char*, unsigned char*,
std::forward_iterator_tag) /usr/include/c++/10/bits/vector.tcc:729
    #1 0x556e32bfecbf in void std::vector<unsigned char,
std::allocator<unsigned char> >::_M_insert_dispatch<unsigned
char*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char,
std::allocator<unsigned char> > >, unsigned char*, unsigned char*,
std::__false_type) /usr/include/c++/10/bits/stl_vector.h:1665
    #2 0x556e32bfecbf in __gnu_cxx::__normal_iterator<unsigned char*,
std::vector<unsigned char, std::allocator<unsigned char> > >
std::vector<unsigned char, std::allocator<unsigned char> >::insert<unsigned
char*, void>(__gnu_cxx::__normal_iterator<unsigned char const*,
std::vector<unsigned char, std::allocator<unsigned char> > >, unsigned char*,
unsigned char*) /usr/include/c++/10/bits/stl_vector.h:1383
    #3 0x556e32bfecbf in push
/home/chfast/Projects/wasmx/fizzy/lib/fizzy/parser_expr.cpp:26
...

0x602000006e5c is located 0 bytes to the right of 12-byte region
[0x602000006e50,0x602000006e5c)
allocated by thread T0 here:
    #0 0x7f0bfa861f17 in operator new(unsigned long)
(/lib/x86_64-linux-gnu/libasan.so.6+0xb1f17)
    #1 0x556e32bff1e1 in __gnu_cxx::new_allocator<unsigned
char>::allocate(unsigned long, void const*)
/usr/include/c++/10/ext/new_allocator.h:115
    #2 0x556e32bff1e1 in std::allocator_traits<std::allocator<unsigned char>
>::allocate(std::allocator<unsigned char>&, unsigned long)
/usr/include/c++/10/bits/alloc_traits.h:460
    #3 0x556e32bff1e1 in std::_Vector_base<unsigned char,
std::allocator<unsigned char> >::_M_allocate(unsigned long)
/usr/include/c++/10/bits/stl_vector.h:346
    #4 0x556e32bff1e1 in void std::vector<unsigned char,
std::allocator<unsigned char> >::_M_range_insert<unsigned
char*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char,
std::allocator<unsigned char> > >, unsigned char*, unsigned char*,
std::forward_iterator_tag) /usr/include/c++/10/bits/vector.tcc:769
    #5 0x556e32bff1e1 in void std::vector<unsigned char,
std::allocator<unsigned char> >::_M_insert_dispatch<unsigned
char*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char,
std::allocator<unsigned char> > >, unsigned char*, unsigned char*,
std::__false_type) /usr/include/c++/10/bits/stl_vector.h:1665
    #6 0x556e32bff1e1 in __gnu_cxx::__normal_iterator<unsigned char*,
std::vector<unsigned char, std::allocator<unsigned char> > >
std::vector<unsigned char, std::allocator<unsigned char> >::insert<unsigned
char*, void>(__gnu_cxx::__normal_iterator<unsigned char const*,
std::vector<unsigned char, std::allocator<unsigned char> > >, unsigned char*,
unsigned char*) /usr/include/c++/10/bits/stl_vector.h:1383
    #7 0x556e32bff1e1 in push
/home/chfast/Projects/wasmx/fizzy/lib/fizzy/parser_expr.cpp:26
...

0x602000006e5a is located 10 bytes inside of 12-byte region
[0x602000006e50,0x602000006e5c)
allocated by thread T0 here:
    #0 0x7f0bfa861f17 in operator new(unsigned long)
(/lib/x86_64-linux-gnu/libasan.so.6+0xb1f17)
    #1 0x556e32bff1e1 in __gnu_cxx::new_allocator<unsigned
char>::allocate(unsigned long, void const*)
/usr/include/c++/10/ext/new_allocator.h:115
    #2 0x556e32bff1e1 in std::allocator_traits<std::allocator<unsigned char>
>::allocate(std::allocator<unsigned char>&, unsigned long)
/usr/include/c++/10/bits/alloc_traits.h:460
    #3 0x556e32bff1e1 in std::_Vector_base<unsigned char,
std::allocator<unsigned char> >::_M_allocate(unsigned long)
/usr/include/c++/10/bits/stl_vector.h:346
    #4 0x556e32bff1e1 in void std::vector<unsigned char,
std::allocator<unsigned char> >::_M_range_insert<unsigned
char*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char,
std::allocator<unsigned char> > >, unsigned char*, unsigned char*,
std::forward_iterator_tag) /usr/include/c++/10/bits/vector.tcc:769
    #5 0x556e32bff1e1 in void std::vector<unsigned char,
std::allocator<unsigned char> >::_M_insert_dispatch<unsigned
char*>(__gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char,
std::allocator<unsigned char> > >, unsigned char*, unsigned char*,
std::__false_type) /usr/include/c++/10/bits/stl_vector.h:1665
    #6 0x556e32bff1e1 in __gnu_cxx::__normal_iterator<unsigned char*,
std::vector<unsigned char, std::allocator<unsigned char> > >
std::vector<unsigned char, std::allocator<unsigned char> >::insert<unsigned
char*, void>(__gnu_cxx::__normal_iterator<unsigned char const*,
std::vector<unsigned char, std::allocator<unsigned char> > >, unsigned char*,
unsigned char*) /usr/include/c++/10/bits/stl_vector.h:1383
    #7 0x556e32bff1e1 in push
/home/chfast/Projects/wasmx/fizzy/lib/fizzy/parser_expr.cpp:26

Reply via email to