IoReleaseRemoveLock race
- From: BubbaGump <BubbaGump@localhost>
- Date: Mon, 23 Apr 2007 18:58:49 -0400
http://msdn2.microsoft.com/en-us/library/aa490593.aspx
In the documentation of IoReleaseRemoveLock, the directions for I/O
operations that set an IoCompletion routine include a race condition.
They could allow a driver to release the last known reference to its
own code, and if this happens then unpredictable behavior will result.
In this situation, if the lower driver happens to call
IoCompleteRequest from its dispatch routine then the completion
routine of the higher driver will be called, and if that then releases
the higher driver's remove lock then the higher driver's
IRP_MN_REMOVE_DEVICE handler could be allowed to proceed and
dereference the lower driver, all before the lower driver's dispatch
routine returns. The lower driver has just indirectly released the
last known reference to its own code.
In a graphical form:
higher driver's dispatch routine is entered
higher driver acquires its remove lock
higher driver calls IoCallDriver
lower driver's dispatch routine is entered
lower driver acquires its remove lock
lower driver calls IoCompleteRequest
higher driver's IoCompletion routine is entered
higher driver releases its remove lock
higher driver's IoCompletion routine returns
lower driver releases its remove lock
<no known reference to lower driver at this point>
lower driver's dispatch routine returns
higher driver's dispatch routine returns
There must be two remove lock acquires by the higher driver in this
situation. Where the current documentation says:
"For I/O operations (including power and PnP IRPs) that set an
IoCompletion routine, a driver should call IoReleaseRemoveLock in the
IoCompletion routine, after calling IoCompleteRequest.
For I/O operations that do not set an IoCompletion routine, a
driver should call IoReleaseRemoveLock after passing the current IRP
to the next-lower driver, but before exiting the dispatch routine."
the second sentence should read:
"... do _or_ do not set an IoCompletion routine ..."
with the implication that setting an IoCompletion routine requires
calling IoReleaseRemoveLock twice (in the IoCompletion routine and
also after passing the current IRP to the next-lower driver) and
correspondingly calling IoAcquireRemoveLock twice, since it cannot be
predicted whether the higher driver's IoCompletion routine will run
before or after the lower driver's dispatch routine has returned, so
that in any case the higher driver's remove lock will not be
completely released until the lower driver's dispatch routine returns.
.
- Follow-Ups:
- Re: IoReleaseRemoveLock race
- From: chris . aseltine
- Re: IoReleaseRemoveLock race
- Prev by Date: Re: selectively bind a NDIS IM
- Next by Date: Re: IoReleaseRemoveLock race
- Previous by thread: Re: Extra reference/remove-lock and completion routines
- Next by thread: Re: IoReleaseRemoveLock race
- Index(es):
Relevant Pages
|
|