Read: Generalized EOF condition slightly.
Remember to check for failure when locking address buffer.
Lock: SEH to protect from bad address length ptr.
Modified: trunk/reactos/drivers/net/afd/afd/lock.c
Modified: trunk/reactos/drivers/net/afd/afd/read.c
_____
Modified: trunk/reactos/drivers/net/afd/afd/lock.c
--- trunk/reactos/drivers/net/afd/afd/lock.c 2005-04-08 05:35:20 UTC
(rev 14542)
+++ trunk/reactos/drivers/net/afd/afd/lock.c 2005-04-08 11:04:13 UTC
(rev 14543)
@@ -11,6 +11,7 @@
#include "tdi_proto.h"
#include "tdiconn.h"
#include "debug.h"
+#include "pseh.h"
/* Lock a method_neither request so it'll be available from
DISPATCH_LEVEL */
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
@@ -49,21 +50,31 @@
UINT Size = sizeof(AFD_WSABUF) * (Count + Lock);
PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 );
PMDL NewMdl;
+ INT NewBufferLen;
AFD_DbgPrint(MID_TRACE,("Called\n"));
if( NewBuf ) {
PAFD_MAPBUF MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock);
- RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count );
+ _SEH_TRY {
+ 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 ) {
- NewBuf[Count].buf = AddressBuf;
- NewBuf[Count].len = *AddressLen;
- Count++;
- NewBuf[Count].buf = (PVOID)AddressLen;
- NewBuf[Count].len = sizeof(*AddressLen);
- Count++;
+ if( LockAddress ) {
+ NewBuf[Count].buf = AddressBuf;
+ NewBuf[Count].len = NewBufferLen;
+ Count++;
+ NewBuf[Count].buf = (PVOID)AddressLen;
+ NewBuf[Count].len = sizeof(*AddressLen);
+ Count++;
}
for( i = 0; i < Count; i++ ) {
_____
Modified: trunk/reactos/drivers/net/afd/afd/read.c
--- trunk/reactos/drivers/net/afd/afd/read.c 2005-04-08 05:35:20 UTC
(rev 14542)
+++ trunk/reactos/drivers/net/afd/afd/read.c 2005-04-08 11:04:13 UTC
(rev 14543)
@@ -33,6 +33,14 @@
(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,
PAFD_RECV_INFO RecvReq,
PUINT TotalBytesCopied ) {
@@ -101,15 +109,9 @@
ReceiveComplete,
FCB );
- 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;
- }
-
+ if( Status == STATUS_SUCCESS )
+ FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
+ HandleEOFOnIrp( FCB, Status, FCB->Recv.Content );
SocketCalloutLeave( FCB );
}
}
@@ -149,6 +151,8 @@
if( NextIrp == Irp ) RetStatus = Status;
IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
FCB->Overread = TRUE;
+ //FCB->PollState |= AFD_EVENT_DISCONNECT;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
}
} else {
/* Kick the user that receive would be possible now */
@@ -233,14 +237,8 @@
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 );
PollReeval( FCB->DeviceExt, FCB->FileObject );
@@ -249,7 +247,7 @@
AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status));
- return Status;
+ return STATUS_SUCCESS;
}
NTSTATUS STDCALL
@@ -260,7 +258,7 @@
PAFD_FCB FCB = FileObject->FsContext;
PAFD_RECV_INFO RecvReq;
UINT TotalBytesCopied = 0;
-
+
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE
);
@@ -294,6 +292,11 @@
NULL, NULL,
TRUE, FALSE );
+ if( !RecvReq->BufferArray ) {
+ return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
+ Irp, 0, NULL, FALSE );
+ }
+
Irp->IoStatus.Status = STATUS_PENDING;
Irp->IoStatus.Information = 0;