Read: Generalized EOF condition slightly.

Remember to check for failure when locking address buffer.
Lock: SEH to protect from bad address length ptr.

svn path=/trunk/; revision=14543
This commit is contained in:
Art Yerkes 2005-04-08 11:04:13 +00:00
parent e2303991a6
commit c0282425ac
2 changed files with 40 additions and 26 deletions

View file

@ -11,6 +11,7 @@
#include "tdi_proto.h" #include "tdi_proto.h"
#include "tdiconn.h" #include "tdiconn.h"
#include "debug.h" #include "debug.h"
#include "pseh.h"
/* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */ /* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) { PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
@ -49,17 +50,27 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count,
UINT Size = sizeof(AFD_WSABUF) * (Count + Lock); UINT Size = sizeof(AFD_WSABUF) * (Count + Lock);
PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 ); PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 );
PMDL NewMdl; PMDL NewMdl;
INT NewBufferLen;
AFD_DbgPrint(MID_TRACE,("Called\n")); AFD_DbgPrint(MID_TRACE,("Called\n"));
if( NewBuf ) { if( NewBuf ) {
PAFD_MAPBUF MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock); PAFD_MAPBUF MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock);
_SEH_TRY {
RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count ); RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count );
NewBufferLen = *AddressLen;
} _SEH_HANDLE {
AFD_DbgPrint(MIN_TRACE,("Access violation copying buffer info "
"from userland (%x %x)\n",
Buf, AddressLen));
ExFreePool( NewBuf );
return NULL;
} _SEH_END;
if( LockAddress ) { if( LockAddress ) {
NewBuf[Count].buf = AddressBuf; NewBuf[Count].buf = AddressBuf;
NewBuf[Count].len = *AddressLen; NewBuf[Count].len = NewBufferLen;
Count++; Count++;
NewBuf[Count].buf = (PVOID)AddressLen; NewBuf[Count].buf = (PVOID)AddressLen;
NewBuf[Count].len = sizeof(*AddressLen); NewBuf[Count].len = sizeof(*AddressLen);

View file

@ -33,6 +33,14 @@ BOOLEAN CantReadMore( PAFD_FCB FCB ) {
(FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT)); (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT));
} }
VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, UINT Information ) {
if( Status == STATUS_SUCCESS && Information == 0 ) {
AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
FCB->PollState |= AFD_EVENT_CLOSE /*| AFD_EVENT_DISCONNECT */;
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
}
NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
PAFD_RECV_INFO RecvReq, PAFD_RECV_INFO RecvReq,
PUINT TotalBytesCopied ) { PUINT TotalBytesCopied ) {
@ -101,15 +109,9 @@ NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
ReceiveComplete, ReceiveComplete,
FCB ); FCB );
if( Status == STATUS_SUCCESS ) { if( Status == STATUS_SUCCESS )
if( !FCB->ReceiveIrp.Iosb.Information ) {
AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
FCB->PollState |= AFD_EVENT_DISCONNECT;
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information; FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
} HandleEOFOnIrp( FCB, Status, FCB->Recv.Content );
SocketCalloutLeave( FCB ); SocketCalloutLeave( FCB );
} }
} }
@ -149,6 +151,8 @@ NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
if( NextIrp == Irp ) RetStatus = Status; if( NextIrp == Irp ) RetStatus = Status;
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
FCB->Overread = TRUE; FCB->Overread = TRUE;
//FCB->PollState |= AFD_EVENT_DISCONNECT;
PollReeval( FCB->DeviceExt, FCB->FileObject );
} }
} else { } else {
/* Kick the user that receive would be possible now */ /* Kick the user that receive would be possible now */
@ -233,13 +237,7 @@ NTSTATUS DDKAPI ReceiveComplete
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
Status = FCB->ReceiveIrp.Iosb.Status; HandleEOFOnIrp( FCB, Irp->IoStatus.Status, Irp->IoStatus.Information );
if( Irp->IoStatus.Status == STATUS_SUCCESS &&
Irp->IoStatus.Information == 0 ) {
AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
FCB->PollState |= AFD_EVENT_DISCONNECT;
}
ReceiveActivity( FCB, NULL ); ReceiveActivity( FCB, NULL );
@ -249,7 +247,7 @@ NTSTATUS DDKAPI ReceiveComplete
AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status)); AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status));
return Status; return STATUS_SUCCESS;
} }
NTSTATUS STDCALL NTSTATUS STDCALL
@ -294,6 +292,11 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
NULL, NULL, NULL, NULL,
TRUE, FALSE ); TRUE, FALSE );
if( !RecvReq->BufferArray ) {
return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
Irp, 0, NULL, FALSE );
}
Irp->IoStatus.Status = STATUS_PENDING; Irp->IoStatus.Status = STATUS_PENDING;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;