Modify

Ticket #2735 (closed Bugs: worksforme)

Opened 5 years ago

Last modified 5 years ago

Memory corruption

Reported by: Lono <KHaiFeng@…> Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.37.0 Severity: Problem
Keywords: Cc:

Description

A memory corruption caused by access to invalid pointer "overlapped" at function shutdown_service in win_iocp_io_service.hpp line 144

The bug is caused by the return value of ::GetQueuedCompletionStatus? is not checked. when the function return false, the value of "overlapped" will be invalid( not zero) and access to the pointer will cause memory corruption.

I am sorry that I cannot give you a example to reproduce this bug (due to the company policy) You can reproduce this issue by calling ::ConnectNamedPipe? and close the pipe immediately before any clients connect to the pipe. ::GetQueuedCompletionStatus? will return "pending I/O operation is still in progress" and failed.

This bug is very hard to find due to the corruption may corrupt other part of the code. If you don't want to fully support windows pipe(::ConnectNamedPipe? is supported by Windows IOCP, but not by asio), that's fine. I know the problem is caused by my misuse of asio, but please do check the return value of windows API and avoid the memory corruption problem.

Thank you.

btw, please ingore "?" above.

void shutdown_service()
  {
    ::InterlockedExchange(&shutdown_, 1);

    while (::InterlockedExchangeAdd(&outstanding_operations_, 0) > 0)
    {
      DWORD bytes_transferred = 0;
#if (WINVER < 0x0500)
      DWORD completion_key = 0;
#else
      DWORD_PTR completion_key = 0;
#endif
      LPOVERLAPPED overlapped = 0;
      ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
          &completion_key, &overlapped, INFINITE);
      if (overlapped)
        static_cast<operation*>(overlapped)->destroy();
    }

    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
      timer_queues_[i]->destroy_timers();
    timer_queues_.clear();
  }

Attachments

Change History

comment:1 Changed 5 years ago by chris_kohlhoff

  • Status changed from new to closed
  • Resolution set to worksforme

Unfortunately your patch is not correct, as you appear to have missed an important detail in the MSDN page:

If *lpOverlapped is not NULL and the function dequeues a completion packet for a failed I/O operation from the completion port, the return value is zero.

That is, the fact that overlapped is non-null means that there is an OVERLAPPED-derived object that needs to be deleted, it's just that it happens to be for a failed operation. That it is deleting an "invalid" object makes me suspect that your program (or asio) is deleting the OVERLAPPED-derived object too early.

There isn't enough information here for me to determine if there is a bug in asio. Using ConnectNamedPipe? with asio appears to work correctly when I try it following your instructions. Please reopen this bug if you can provide more detailed instructions.

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.