Fixed input stream length checks in rdpgfx_recv_caps_advertise_pdu
authorArmin Novak <armin.novak@thincast.com>
Fri, 15 Mar 2019 07:39:46 +0000 (08:39 +0100)
committerArmin Novak <armin.novak@thincast.com>
Fri, 26 Apr 2019 11:11:46 +0000 (13:11 +0200)
channels/rdpgfx/server/rdpgfx_main.c

index 0990d94..d8e4754 100644 (file)
@@ -1202,13 +1202,6 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context,
        }
 
        Stream_Read_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */
-
-       if (Stream_GetRemainingLength(s) < (pdu.capsSetCount * (RDPGFX_CAPSET_BASE_SIZE + 4)))
-       {
-               WLog_ERR(TAG, "not enough data!");
-               return ERROR_INVALID_DATA;
-       }
-
        capsSets = calloc(pdu.capsSetCount, (RDPGFX_CAPSET_BASE_SIZE + 4));
 
        if (!capsSets)
@@ -1219,13 +1212,26 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context,
        for (index = 0; index < pdu.capsSetCount; index++)
        {
                RDPGFX_CAPSET* capsSet = &(pdu.capsSets[index]);
+
+               if (Stream_GetRemainingLength(s) < 8)
+               {
+                       WLog_ERR(TAG, "not enough data!");
+                       return ERROR_INVALID_DATA;
+               }
+
                Stream_Read_UINT32(s, capsSet->version); /* version (4 bytes) */
                Stream_Read_UINT32(s, capsSet->length); /* capsDataLength (4 bytes) */
 
                if (capsSet->length >= 4)
+               {
+                       if (Stream_GetRemainingLength(s) < 4)
+                               return ERROR_INVALID_DATA;
+
                        Stream_Peek_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
+               }
 
-               Stream_Seek(s, capsSet->length);
+               if (!Stream_SafeSeek(s, capsSet->length))
+                       return ERROR_INVALID_DATA;
        }
 
        if (context)