Click to See Complete Forum and Search --> : buffer overflow in a worker thread


skval
May 22nd, 2009, 03:52 PM
Hi, i'm writing a server using the port completion architecture.
below the worker thread code.
the program crashes write after i queue the completion request, but the weird thing is that it crashes only if i send info that fills all the buffer in the WSAREcv function.
if for example the buffer size is 10 only 10 length string i'll send will make it crash.
any ideas?

thanks in advance for any help.


void CServer::HandleConnections()
{
OVERLAPPED *lpOverlapped=NULL;
DWORD dwTransfered;
PER_HANDLE_DATA *PerHandleData;
PER_IO_DATA *PerIoData;
while(1)
{
GetQueuedCompletionStatus(this->hCompletion,
&dwTransfered,
(LPDWORD)&PerHandleData,
&lpOverlapped,INFINITE);

PerIoData = CONTAINING_RECORD(lpOverlapped, PER_IO_DATA, Overlapped);
ResetEvent(PerIoData->Overlapped.hEvent);


//if WSARecv/WSASend returns 0 then connection was closed
if(dwTransfered==0 && (PerIoData->OperationType == RECV_POSTED ||
PerIoData->OperationType == SEND_POSTED))
{
WSACloseEvent(PerIoData->Overlapped.hEvent);
lpfnDisconnectEx(PerHandleData->Socket,NULL,TF_REUSE_SOCKET,0);
this->bFreeSockets[PerHandleData->iIndex]=TRUE;

delete PerHandleData;
delete PerIoData;

continue;
}

else if(PerIoData->OperationType == RECV_POSTED)
{

if(dwTransfered<0)
{
//error occured
}
else if(dwTransfered<3 && PerHandleData->bWriteDataToFile==FALSE)
{ //error occured
char szData[10];
sprintf(szData,"%c",iInvalidRequest);
//invalid request
//empty the buffer and send an INVALID_REQUEST error
//

WSASendWrapper(PerIoData,PerHandleData->Socket,szData);

}


//check if we need to write the data
else if(PerHandleData->bWriteDataToFile==TRUE)
{

//write the data to the file
}
else
{

PerIoData->dataBuf.buf[dwTransfered]=NULL;


if(PerIoData->dataBuf.buf[dwTransfered-2]!='\r'
&& PerIoData->dataBuf.buf[dwTransfered-1]!='\n')
{

char szData[10];
sprintf(szData,"%c",iInvalidRequest);

//invalid request
//empty the buffer and send an INVALID_REQUEST error
//
WSASendWrapper(PerIoData,PerHandleData->Socket,szData);

}
else
{
printf("%s",PerIoData->dataBuf.buf);
WSARecvWrapper(PerIoData,PerHandleData->Socket);

}
//make sure the command is valid
//and if it's not send an invalid request message
}

}

else if(PerIoData->OperationType==SEND_POSTED)
{
this->WSARecvWrapper(PerIoData,PerHandleData->Socket);
}
else if(PerIoData->OperationType==SHUTDOWN_SERVER)
{
SetEvent(hCompletionDone);
delete PerHandleData;
delete PerIoData;
break;
}

}

}

Richard.J
May 25th, 2009, 09:44 AM
I don't know how your dataBuf is defined, but this line looks suspicious:
PerIoData->dataBuf.buf[dwTransfered]=NULL;

if your dataBuf is of size 10, and dwTransfered is also 10, then you are addressing dataBuf[10] which is non-existent, i. e. you are writing behind your memory. This might cause a problem.