[AFD] Don't allow caller to set broken values to window sizes
authorPierre Schweitzer <pierre@reactos.org>
Mon, 25 Feb 2019 21:27:00 +0000 (22:27 +0100)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 25 Feb 2019 21:34:28 +0000 (22:34 +0100)
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

index 1c05842..c780eb8 100644 (file)
@@ -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: