id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 12919,multi_index indexed with hashed_non_unique produces buffer overrun.,Alex Huszagh ,Joaquín M López Muñoz,"Using multi_index_container on a struct indexing using hashed_non_unique (hashing a std::string) can cause a buffer overrun in unchecked_rehash(size_type,hashed_non_unique_tag), typically culminating in a segfault. The segment below, taken from lines 1351-1372 of boost/multi_index/hash_index.hpp, can iterate between two different nodes, causing `x==end_` to never occur, causing a auto_space to be overrun, eventually leading to a segmentation fault. {{{ #!div style=""font-size: 80%"" Code highlighting: {{{#!cpp auto_space< std::size_t,allocator_type> hashes(get_allocator(),size()); auto_space< node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); std::size_t i=0; bool within_bucket=false; BOOST_TRY{ for(;;++i){ node_impl_pointer x=end_->prior(); if(x==end_)break; /* only this can possibly throw */ std::size_t h=hash_(key(node_type::from_impl(x)->value())); hashes.data()[i]=h; node_ptrs.data()[i]=x; std::pair p= node_alg::unlink_last_group(end_); node_alg::link_range( p.first,x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); within_bucket=!(p.second); } } }}} }}} The solution is quite simple, and is shown in the other implementation of unchecked_rehash(size_type,hashed_unique_tag), by ensuring the rehash does not exceed the number of elements. The proper implementation (possibly suboptimal) would look something like this: {{{ #!div style=""font-size: 80%"" Code highlighting: {{{#!cpp auto_space< std::size_t,allocator_type> hashes(get_allocator(),size()); auto_space< node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); std::size_t i=0, size_=size(); bool within_bucket=false; BOOST_TRY{ for(;i!=size_;++i){ node_impl_pointer x=end_->prior(); if(x==end_)break; /* only this can possibly throw */ std::size_t h=hash_(key(node_type::from_impl(x)->value())); hashes.data()[i]=h; node_ptrs.data()[i]=x; std::pair p= node_alg::unlink_last_group(end_); node_alg::link_range( p.first,x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); within_bucket=!(p.second); } } }}} }}} As the data leading to this segfault is private, I currently do not have a minimal, verified example to reproduce the bug, however, I believe this is a rational explanation, with a straight-forward fix. I've seen examples where an ~800 element buffer will continue until i > 15,000, culminating in a segfault. I will submit a pull request with the above diff. Thanks, Alex",Bugs,closed,To Be Determined,multi_index,Boost 1.63.0,Problem,invalid,multi_index,joaquin@…