https://git.reactos.org/?p=reactos.git;a=commitdiff;h=86483d6e222e42f3faefeā¦
commit 86483d6e222e42f3faefeac280f988cf8437736d
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Mon Feb 25 22:27:00 2019 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Mon Feb 25 22:34:28 2019 +0100
[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
---
drivers/network/afd/afd/info.c | 111 ++++++++++++++++++++++++++---------------
1 file changed, 71 insertions(+), 40 deletions(-)
diff --git a/drivers/network/afd/afd/info.c b/drivers/network/afd/afd/info.c
index 1c05842e4e..c780eb86a2 100644
--- a/drivers/network/afd/afd/info.c
+++ b/drivers/network/afd/afd/info.c
@@ -124,61 +124,92 @@ AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
FCB->OobInline = InfoReq->Information.Boolean;
break;
case AFD_INFO_RECEIVE_WINDOW_SIZE:
- NewBuffer = ExAllocatePoolWithTag(PagedPool,
- InfoReq->Information.Ulong,
- TAG_AFD_DATA_BUFFER);
-
- if (NewBuffer)
+ if (FCB->State == SOCKET_STATE_CONNECTED ||
+ FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
{
- if (FCB->Recv.Content > InfoReq->Information.Ulong)
- FCB->Recv.Content = InfoReq->Information.Ulong;
-
- if (FCB->Recv.Window)
+ /* FIXME: likely not right, check tcpip.sys for
TDI_QUERY_MAX_DATAGRAM_INFO */
+ if (InfoReq->Information.Ulong > 0 &&
InfoReq->Information.Ulong < 0xFFFF)
{
- RtlCopyMemory(NewBuffer,
- FCB->Recv.Window,
- FCB->Recv.Content);
-
- ExFreePoolWithTag(FCB->Recv.Window, TAG_AFD_DATA_BUFFER);
+ NewBuffer = ExAllocatePoolWithTag(PagedPool,
+ InfoReq->Information.Ulong,
+ 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
{
- Status = STATUS_NO_MEMORY;
+ Status = STATUS_INVALID_PARAMETER;
}
break;
case AFD_INFO_SEND_WINDOW_SIZE:
- NewBuffer = ExAllocatePoolWithTag(PagedPool,
- InfoReq->Information.Ulong,
- TAG_AFD_DATA_BUFFER);
-
- if (NewBuffer)
+ if (FCB->State == SOCKET_STATE_CONNECTED ||
+ FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
{
- if (FCB->Send.BytesUsed > InfoReq->Information.Ulong)
- FCB->Send.BytesUsed = InfoReq->Information.Ulong;
-
- if (FCB->Send.Window)
+ if (InfoReq->Information.Ulong > 0 &&
InfoReq->Information.Ulong < 0xFFFF)
{
- RtlCopyMemory(NewBuffer,
- FCB->Send.Window,
- FCB->Send.BytesUsed);
-
- ExFreePoolWithTag(FCB->Send.Window, TAG_AFD_DATA_BUFFER);
+ NewBuffer = ExAllocatePoolWithTag(PagedPool,
+ InfoReq->Information.Ulong,
+ 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
{
- Status = STATUS_NO_MEMORY;
+ Status = STATUS_INVALID_PARAMETER;
}
break;
default: