This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/84256] New: Use object size checking built-ins in libstdc++
- From: "redi at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 06 Feb 2018 21:41:16 +0000
- Subject: [Bug libstdc++/84256] New: Use object size checking built-ins in libstdc++
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84256
Bug ID: 84256
Summary: Use object size checking built-ins in libstdc++
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: enhancement
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: redi at gcc dot gnu.org
Target Milestone: ---
#include <vector>
int main()
{
int a[2] = { };
std::vector<int> v(a, a+3);
}
This gets caught by AddressSanitizer, but it would be possible to warn at
compile-time by using __builtin_object_size, with something like
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -71,6 +71,15 @@ __sanitizer_annotate_contiguous_container(const void*, const
void*,
const void*, const void*);
#endif
+namespace __gnu_debug
+{
+ void
+ __bad_iterator_range()
+ __attribute__((__warning__("invalid end iterator")));
+
+ inline void __bad_iterator_range() { }
+}
+
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -543,7 +552,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
- { _M_initialize_dispatch(__first, __last, __false_type()); }
+ {
+ if _GLIBCXX17_CONSTEXPR (is_pointer<_InputIterator>::value)
+ {
+ const size_t __len = __builtin_object_size(__first, 1);
+ using _Vp = typename iterator_traits<_InputIterator>::value_type;
+ if (__len < (size_t)std::distance(__last - __first) *
sizeof(_Vp))
+ __gnu_debug::__bad_iterator_range();
+ }
+ _M_initialize_dispatch(__first, __last, __false_type());
+ }
#else
template<typename _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
We could do this in every function that takes a pair of iterators to read from
or write to, although maybe only when _GLIBCXX_ASSERTIONS is defined.
We could also use the checking versions of __builtin_memmove etc. in
<bits/stl_algobase.h> (although only when __memcpy_chk is available, and again
probably onyl when ASSERTIONS are enabled).
https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
(This is the general case of PR 54924 which is specific to std::basic_string)