[AFD] Don't allow caller to set broken values to window sizes

This will avoid 0-sized allocations, or -1-sized allocations.
So far, it's maxed by hard value stored in TCPIP.sys. I believe
this is not right and would deserve a true fix
This commit is contained in:
Pierre Schweitzer 2019-02-25 22:27:00 +01:00
parent bb9eec7537
commit 86483d6e22
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B

View file

@ -124,61 +124,92 @@ AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
FCB->OobInline = InfoReq->Information.Boolean; FCB->OobInline = InfoReq->Information.Boolean;
break; break;
case AFD_INFO_RECEIVE_WINDOW_SIZE: case AFD_INFO_RECEIVE_WINDOW_SIZE:
NewBuffer = ExAllocatePoolWithTag(PagedPool, if (FCB->State == SOCKET_STATE_CONNECTED ||
InfoReq->Information.Ulong, FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
TAG_AFD_DATA_BUFFER);
if (NewBuffer)
{ {
if (FCB->Recv.Content > InfoReq->Information.Ulong) /* FIXME: likely not right, check tcpip.sys for TDI_QUERY_MAX_DATAGRAM_INFO */
FCB->Recv.Content = InfoReq->Information.Ulong; if (InfoReq->Information.Ulong > 0 && InfoReq->Information.Ulong < 0xFFFF)
if (FCB->Recv.Window)
{ {
RtlCopyMemory(NewBuffer, NewBuffer = ExAllocatePoolWithTag(PagedPool,
FCB->Recv.Window, InfoReq->Information.Ulong,
FCB->Recv.Content); TAG_AFD_DATA_BUFFER);
ExFreePoolWithTag(FCB->Recv.Window, TAG_AFD_DATA_BUFFER); if (NewBuffer)
{
if (FCB->Recv.Content > InfoReq->Information.Ulong)
FCB->Recv.Content = InfoReq->Information.Ulong;
if (FCB->Recv.Window)
{
RtlCopyMemory(NewBuffer,
FCB->Recv.Window,
FCB->Recv.Content);
ExFreePoolWithTag(FCB->Recv.Window, TAG_AFD_DATA_BUFFER);
}
FCB->Recv.Size = InfoReq->Information.Ulong;
FCB->Recv.Window = NewBuffer;
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_NO_MEMORY;
}
}
else
{
Status = STATUS_SUCCESS;
} }
FCB->Recv.Size = InfoReq->Information.Ulong;
FCB->Recv.Window = NewBuffer;
Status = STATUS_SUCCESS;
} }
else else
{ {
Status = STATUS_NO_MEMORY; Status = STATUS_INVALID_PARAMETER;
} }
break; break;
case AFD_INFO_SEND_WINDOW_SIZE: case AFD_INFO_SEND_WINDOW_SIZE:
NewBuffer = ExAllocatePoolWithTag(PagedPool, if (FCB->State == SOCKET_STATE_CONNECTED ||
InfoReq->Information.Ulong, FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
TAG_AFD_DATA_BUFFER);
if (NewBuffer)
{ {
if (FCB->Send.BytesUsed > InfoReq->Information.Ulong) if (InfoReq->Information.Ulong > 0 && InfoReq->Information.Ulong < 0xFFFF)
FCB->Send.BytesUsed = InfoReq->Information.Ulong;
if (FCB->Send.Window)
{ {
RtlCopyMemory(NewBuffer, NewBuffer = ExAllocatePoolWithTag(PagedPool,
FCB->Send.Window, InfoReq->Information.Ulong,
FCB->Send.BytesUsed); TAG_AFD_DATA_BUFFER);
ExFreePoolWithTag(FCB->Send.Window, TAG_AFD_DATA_BUFFER); if (NewBuffer)
{
if (FCB->Send.BytesUsed > InfoReq->Information.Ulong)
FCB->Send.BytesUsed = InfoReq->Information.Ulong;
if (FCB->Send.Window)
{
RtlCopyMemory(NewBuffer,
FCB->Send.Window,
FCB->Send.BytesUsed);
ExFreePoolWithTag(FCB->Send.Window, TAG_AFD_DATA_BUFFER);
}
FCB->Send.Size = InfoReq->Information.Ulong;
FCB->Send.Window = NewBuffer;
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_NO_MEMORY;
}
}
else
{
Status = STATUS_SUCCESS;
} }
FCB->Send.Size = InfoReq->Information.Ulong;
FCB->Send.Window = NewBuffer;
Status = STATUS_SUCCESS;
} }
else else
{ {
Status = STATUS_NO_MEMORY; Status = STATUS_INVALID_PARAMETER;
} }
break; break;
default: default: