Commit 32917686 by Jonathan Wakely Committed by Jonathan Wakely

PR 72847 Prevent double-free in std::vector<bool>

	PR libstdc++/72847
	* include/bits/stl_bvector.h (_Bvector_base::_M_deallocate): Zero
	pointers to start and end of storage.
	* testsuite/23_containers/vector/bool/72847.cc: New test.
	* include/bits/vector.tcc (vector<bool>::_M_reallocate): Only update
	_M_finish after deallocating.
	(vector<bool>::_M_fill_insert): Likewise.
	(vector<bool>::_M_insert_range): Likewise.
	(vector<bool>::_M_insert_aux): Likewise.

From-SVN: r239497
parent f4eec0a3
2016-08-16 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/72847
* include/bits/stl_bvector.h (_Bvector_base::_M_deallocate): Zero
pointers to start and end of storage.
* testsuite/23_containers/vector/bool/72847.cc: New test.
* include/bits/vector.tcc (vector<bool>::_M_reallocate): Only update
_M_finish after deallocating.
(vector<bool>::_M_fill_insert): Likewise.
(vector<bool>::_M_insert_range): Likewise.
(vector<bool>::_M_insert_aux): Likewise.
2016-08-15 Ville Voutilainen <ville.voutilainen@gmail.com> 2016-08-15 Ville Voutilainen <ville.voutilainen@gmail.com>
Implement LWG 2744 and LWG 2754. Implement LWG 2744 and LWG 2754.
......
...@@ -500,6 +500,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -500,6 +500,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_Bit_alloc_traits::deallocate(_M_impl, _Bit_alloc_traits::deallocate(_M_impl,
_M_impl._M_end_of_storage - __n, _M_impl._M_end_of_storage - __n,
__n); __n);
_M_impl._M_start = _M_impl._M_finish = _Bit_iterator();
_M_impl._M_end_of_storage = _Bit_pointer();
} }
} }
......
...@@ -708,9 +708,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -708,9 +708,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ {
_Bit_pointer __q = this->_M_allocate(__n); _Bit_pointer __q = this->_M_allocate(__n);
iterator __start(std::__addressof(*__q), 0); iterator __start(std::__addressof(*__q), 0);
this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), __start); iterator __finish(_M_copy_aligned(begin(), end(), __start));
this->_M_deallocate(); this->_M_deallocate();
this->_M_impl._M_start = __start; this->_M_impl._M_start = __start;
this->_M_impl._M_finish = __finish;
this->_M_impl._M_end_of_storage = __q + _S_nword(__n); this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
} }
...@@ -736,11 +737,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -736,11 +737,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __start(std::__addressof(*__q), 0); iterator __start(std::__addressof(*__q), 0);
iterator __i = _M_copy_aligned(begin(), __position, __start); iterator __i = _M_copy_aligned(begin(), __position, __start);
std::fill(__i, __i + difference_type(__n), __x); std::fill(__i, __i + difference_type(__n), __x);
this->_M_impl._M_finish = std::copy(__position, end(), iterator __finish = std::copy(__position, end(),
__i + difference_type(__n)); __i + difference_type(__n));
this->_M_deallocate(); this->_M_deallocate();
this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
this->_M_impl._M_start = __start; this->_M_impl._M_start = __start;
this->_M_impl._M_finish = __finish;
} }
} }
...@@ -770,10 +772,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -770,10 +772,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __start(std::__addressof(*__q), 0); iterator __start(std::__addressof(*__q), 0);
iterator __i = _M_copy_aligned(begin(), __position, __start); iterator __i = _M_copy_aligned(begin(), __position, __start);
__i = std::copy(__first, __last, __i); __i = std::copy(__first, __last, __i);
this->_M_impl._M_finish = std::copy(__position, end(), __i); iterator __finish = std::copy(__position, end(), __i);
this->_M_deallocate(); this->_M_deallocate();
this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
this->_M_impl._M_start = __start; this->_M_impl._M_start = __start;
this->_M_impl._M_finish = __finish;
} }
} }
} }
...@@ -798,10 +801,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ...@@ -798,10 +801,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
iterator __start(std::__addressof(*__q), 0); iterator __start(std::__addressof(*__q), 0);
iterator __i = _M_copy_aligned(begin(), __position, __start); iterator __i = _M_copy_aligned(begin(), __position, __start);
*__i++ = __x; *__i++ = __x;
this->_M_impl._M_finish = std::copy(__position, end(), __i); iterator __finish = std::copy(__position, end(), __i);
this->_M_deallocate(); this->_M_deallocate();
this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_end_of_storage = __q + _S_nword(__len);
this->_M_impl._M_start = __start; this->_M_impl._M_start = __start;
this->_M_impl._M_finish = __finish;
} }
} }
......
// Copyright (C) 2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-require-cstdint "" }
// { dg-skip-if "" { *-*-* } { "-fno-exceptions" } }
#include <vector>
#include <ext/throw_allocator.h>
#include <testsuite_hooks.h>
// PR libstdc++/72847
void
test01()
{
bool test __attribute((unused)) = true;
typedef bool value_type;
typedef __gnu_cxx::throw_allocator_limit<value_type> allocator_type;
typedef std::vector<value_type, allocator_type> test_type;
test_type v1(1, false);
test_type v2(v1.capacity()+1, false);
allocator_type::set_limit(0);
try {
v1 = v2;
} catch (const __gnu_cxx::forced_error&) {
}
// throw_allocator will throw if double-free happens
}
// Container requirement testing, exceptional behavior
int main()
{
test01();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment