mirror of
https://github.com/reactos/reactos.git
synced 2025-07-23 04:33:38 +00:00
- Fix a race condition that occurs when an IRP gets cancelled after it is inserted into the completion queue but before it is completed
svn path=/trunk/; revision=44267
This commit is contained in:
parent
83bc88465f
commit
e016a230af
6 changed files with 33 additions and 20 deletions
|
@ -21,7 +21,7 @@ NTSTATUS DGReceiveDatagram(
|
|||
PVOID Context,
|
||||
PIRP Irp);
|
||||
|
||||
VOID DGRemoveIRP(
|
||||
BOOLEAN DGRemoveIRP(
|
||||
PADDRESS_FILE AddrFile,
|
||||
PIRP Irp);
|
||||
|
||||
|
|
|
@ -96,8 +96,8 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
|
|||
PCONNECTION_ENDPOINT Connection,
|
||||
PTDI_REQUEST_KERNEL Request );
|
||||
NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog );
|
||||
VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
|
||||
PCONNECTION_ENDPOINT Connection );
|
||||
BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
|
||||
PCONNECTION_ENDPOINT Connection );
|
||||
NTSTATUS TCPAccept
|
||||
( PTDI_REQUEST Request,
|
||||
PCONNECTION_ENDPOINT Listener,
|
||||
|
@ -179,6 +179,6 @@ NTSTATUS TCPStartup(
|
|||
NTSTATUS TCPShutdown(
|
||||
VOID);
|
||||
|
||||
VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp );
|
||||
BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp );
|
||||
|
||||
#endif /* __TCP_H */
|
||||
|
|
|
@ -133,6 +133,7 @@ VOID NTAPI DispCancelRequest(
|
|||
PTRANSPORT_CONTEXT TranContext;
|
||||
PFILE_OBJECT FileObject;
|
||||
UCHAR MinorFunction;
|
||||
BOOLEAN DequeuedIrp = TRUE;
|
||||
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
|
||||
|
@ -157,7 +158,7 @@ VOID NTAPI DispCancelRequest(
|
|||
switch(MinorFunction) {
|
||||
case TDI_SEND:
|
||||
case TDI_RECEIVE:
|
||||
TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
|
||||
DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
|
||||
break;
|
||||
|
||||
case TDI_SEND_DATAGRAM:
|
||||
|
@ -166,7 +167,7 @@ VOID NTAPI DispCancelRequest(
|
|||
break;
|
||||
}
|
||||
|
||||
DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
|
||||
DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
|
||||
break;
|
||||
|
||||
case TDI_RECEIVE_DATAGRAM:
|
||||
|
@ -175,19 +176,21 @@ VOID NTAPI DispCancelRequest(
|
|||
break;
|
||||
}
|
||||
|
||||
DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
|
||||
DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
|
||||
break;
|
||||
|
||||
case TDI_CONNECT:
|
||||
TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
|
||||
DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
|
||||
break;
|
||||
|
||||
default:
|
||||
TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
IRPFinish(Irp, STATUS_CANCELLED);
|
||||
if (DequeuedIrp)
|
||||
IRPFinish(Irp, STATUS_CANCELLED);
|
||||
|
||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||
}
|
||||
|
@ -207,7 +210,6 @@ VOID NTAPI DispCancelListenRequest(
|
|||
PTRANSPORT_CONTEXT TranContext;
|
||||
PFILE_OBJECT FileObject;
|
||||
PCONNECTION_ENDPOINT Connection;
|
||||
/*NTSTATUS Status = STATUS_SUCCESS;*/
|
||||
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
|
||||
|
@ -228,13 +230,12 @@ VOID NTAPI DispCancelListenRequest(
|
|||
/* Try canceling the request */
|
||||
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
|
||||
|
||||
TCPRemoveIRP(Connection, Irp);
|
||||
|
||||
TCPAbortListenForSocket(Connection->AddressFile->Listener,
|
||||
Connection);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
IRPFinish(Irp, STATUS_CANCELLED);
|
||||
if (TCPAbortListenForSocket(Connection->AddressFile->Listener,
|
||||
Connection))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
IRPFinish(Irp, STATUS_CANCELLED);
|
||||
}
|
||||
|
||||
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
|
||||
}
|
||||
|
|
|
@ -10,13 +10,14 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
VOID DGRemoveIRP(
|
||||
BOOLEAN DGRemoveIRP(
|
||||
PADDRESS_FILE AddrFile,
|
||||
PIRP Irp)
|
||||
{
|
||||
PLIST_ENTRY ListEntry;
|
||||
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
|
||||
KIRQL OldIrql;
|
||||
BOOLEAN Found = FALSE;
|
||||
|
||||
TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n",
|
||||
Irp, AddrFile));
|
||||
|
@ -36,6 +37,7 @@ VOID DGRemoveIRP(
|
|||
{
|
||||
RemoveEntryList(&ReceiveRequest->ListEntry);
|
||||
ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG);
|
||||
Found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +45,8 @@ VOID DGRemoveIRP(
|
|||
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
|
||||
|
||||
TI_DbgPrint(MAX_TRACE, ("Done.\n"));
|
||||
|
||||
return Found;
|
||||
}
|
||||
|
||||
VOID DGDeliverData(
|
||||
|
|
|
@ -104,11 +104,12 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
|||
return Status;
|
||||
}
|
||||
|
||||
VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
|
||||
BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
|
||||
PCONNECTION_ENDPOINT Connection ) {
|
||||
PLIST_ENTRY ListEntry;
|
||||
PTDI_BUCKET Bucket;
|
||||
KIRQL OldIrql;
|
||||
BOOLEAN Found = FALSE;
|
||||
|
||||
KeAcquireSpinLock(&Listener->Lock, &OldIrql);
|
||||
|
||||
|
@ -119,6 +120,7 @@ VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
|
|||
if( Bucket->AssociatedEndpoint == Connection ) {
|
||||
RemoveEntryList( &Bucket->Entry );
|
||||
ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG );
|
||||
Found = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -126,6 +128,8 @@ VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
|
|||
}
|
||||
|
||||
KeReleaseSpinLock(&Listener->Lock, OldIrql);
|
||||
|
||||
return Found;
|
||||
}
|
||||
|
||||
NTSTATUS TCPAccept ( PTDI_REQUEST Request,
|
||||
|
|
|
@ -904,12 +904,13 @@ NTSTATUS TCPGetSockAddress
|
|||
return Status;
|
||||
}
|
||||
|
||||
VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) {
|
||||
BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) {
|
||||
PLIST_ENTRY Entry;
|
||||
PLIST_ENTRY ListHead[4];
|
||||
KIRQL OldIrql;
|
||||
PTDI_BUCKET Bucket;
|
||||
UINT i = 0;
|
||||
BOOLEAN Found = FALSE;
|
||||
|
||||
ListHead[0] = &Endpoint->SendRequest;
|
||||
ListHead[1] = &Endpoint->ReceiveRequest;
|
||||
|
@ -929,12 +930,15 @@ VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) {
|
|||
{
|
||||
RemoveEntryList( &Bucket->Entry );
|
||||
ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG );
|
||||
Found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TcpipReleaseSpinLock( &Endpoint->Lock, OldIrql );
|
||||
|
||||
return Found;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue