From 86483d6e222e42f3faefeac280f988cf8437736d Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Mon, 25 Feb 2019 22:27:00 +0100 Subject: [PATCH] [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 | 107 +++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/drivers/network/afd/afd/info.c b/drivers/network/afd/afd/info.c index 1c05842e4e0..c780eb86a2b 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); + NewBuffer = ExAllocatePoolWithTag(PagedPool, + InfoReq->Information.Ulong, + 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 { - 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); + NewBuffer = ExAllocatePoolWithTag(PagedPool, + InfoReq->Information.Ulong, + 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 { - Status = STATUS_NO_MEMORY; + Status = STATUS_INVALID_PARAMETER; } break; default: