boostorg / interprocess

Boost.org interprocess module
http://boost.org/libs/interprocess
132 stars 117 forks source link

Bug in boost::interprocess::ipcdetail::sync_handles::obtain_mutex #210

Closed skorniakov closed 1 month ago

skorniakov commented 7 months ago

Version 1.84. Insertion at boost\interprocess\sync\windows\sync_utils.hpp line 188 umap_type::iterator it = umap_.insert(v).first; invalidates iterators in map if rehashing of umap occurred. Later, due to this, program crashed in destroy_syncs_in_range (syncutils.hpp line 252) at ` umap.erase(uit); `

Fedr commented 1 month ago

In Boost 1.85, umap_ is flat_map, so it is never rehashed.

And there is typically no issue with umap_type::iterator it = umap_.insert(v).first;, because every new v has larger value than existing ones, because of sync_id constructor:

   sync_id()
   {  winapi::query_performance_counter(&rand_);  }

The actual issue is in destroy_syncs_in_range:

      for (; it != ithig; ++it){
         id_map_type::iterator uit = it->second; 
         void * const hnd = uit->second;
         umap_.erase(uit);
         int ret = winapi::close_handle(hnd);
         --num_handles_;
         BOOST_ASSERT(ret != 0); (void)ret;  //Sanity check that handle was ok
      }

Here umap_.erase(uit); invalidates all iterators with larger keys, so the second call umap_.erase(uit); can crash.

igaztanaga commented 1 month ago

Thanks for the report, fixed with the proposed pull request.