Opened 4 years ago

#10624 new Bugs

win_object_handle_service race condition on destroy

Reported by: Rowan Wyborn <rwyborn@…> Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.54.0 Severity: Problem
Keywords: Cc:

Description

I caught a random crash in our code base that appears to be due to a race condition in win_object_handle_service. Reproduction steps are essentially just:

boost::asio::windows::object_handle* handle = new boost::asio::windows::object_handle(service, hEvent);
handle->async_wait(...);
SetEvent?(hEvent);
delete handle;

The race condition occurs in win_object_handle_service::wait_callback. The last few lines of code in this method are:

lock.unlock();
impl->owner_->io_service_.post_deferred_completions(completed_ops);

The problem is that while the delete of the handle waits on the same lock as the wait_callback, the call into impl->owner_->io_service_ happens outside the scope of that lock. Hence there is a race condition that can trigger under multi-threaded/heavy load scenarios where the delete may execute before the call to >io_service_.post_deferred_completions happens

lock.unlock();
<----- delete executes here
impl->owner_->io_service_.post_deferred_completions(completed_ops);

This leaves impl->owner_ pointing at deleted/unintialized memory, and hence the post_deferred_completions call randomly crashes. I can repro this 100% of the time by just adding a Sleep to emulate load:

lock.unlock();
Sleep(1000);
impl->owner_->io_service_.post_deferred_completions(completed_ops);

Change History (0)

Note: See TracTickets for help on using tickets.