Vulnerability: In FreeRDP greater than 1.1 and before 2.0.0, there is an out-of-bounds read in update_read_icon_info. It allows reading a attacker-defined amount of client memory (32bit unsigned -> 4GB) to an intermediate buffer. This can be used to crash the client or store information for later retrieval. This has been patched in 2.0.0.
Vulnerability ID: CVE-2020-11042
CWE: CWE-125
Severity score: 4.9
Project: https://github.com/FreeRDP/FreeRDP
Published: 2020-05-07
File: libfreerdp/core/window.c
Commit message: Fix #6010: Check length in read_icon_info
Commit author: akallabeth

Vulnerable version (before fix):
 static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) 	Stream_Read_UINT16(s, iconInfo->cbBitsMask);  /* cbBitsMask (2 bytes) */ 	Stream_Read_UINT16(s, iconInfo->cbBitsColor); /* cbBitsColor (2 bytes) */  	if (Stream_GetRemainingLength(s) < iconInfo->cbBitsMask + iconInfo->cbBitsColor) 		return FALSE;  	/* bitsMask */ 	newBitMask = (BYTE*)realloc(iconInfo->bitsMask, iconInfo->cbBitsMask);  static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) 	}  	iconInfo->bitsMask = newBitMask; 	Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask);  	/* colorTable */ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) 	}  	if (iconInfo->colorTable) 		Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable);  	/* bitsColor */ 	newBitMask = (BYTE*)realloc(iconInfo->bitsColor, iconInfo->cbBitsColor); static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) 	}  	iconInfo->bitsColor = newBitMask; 	Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor); 	return TRUE; }

Fixed version (after fix):
 static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) 	Stream_Read_UINT16(s, iconInfo->cbBitsMask);  /* cbBitsMask (2 bytes) */ 	Stream_Read_UINT16(s, iconInfo->cbBitsColor); /* cbBitsColor (2 bytes) */  	/* bitsMask */ 	newBitMask = (BYTE*)realloc(iconInfo->bitsMask, iconInfo->cbBitsMask);  static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) 	}  	iconInfo->bitsMask = newBitMask; 	if (Stream_GetRemainingLength(s) < iconInfo->cbBitsMask) 		return FALSE; 	Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask);  	/* colorTable */ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) 	}  	if (iconInfo->colorTable) 	{ 		if (Stream_GetRemainingLength(s) < iconInfo->cbColorTable) 			return FALSE; 		Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable); 	}  	/* bitsColor */ 	newBitMask = (BYTE*)realloc(iconInfo->bitsColor, iconInfo->cbBitsColor); static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo) 	}  	iconInfo->bitsColor = newBitMask; 	if (Stream_GetRemainingLength(s) < iconInfo->cbBitsColor) 		return FALSE; 	Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor); 	return TRUE; }

Patch:
patch: @@ -136,9 +136,6 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo)
 	Stream_Read_UINT16(s, iconInfo->cbBitsMask);  /* cbBitsMask (2 bytes) */
 	Stream_Read_UINT16(s, iconInfo->cbBitsColor); /* cbBitsColor (2 bytes) */
 
-	if (Stream_GetRemainingLength(s) < iconInfo->cbBitsMask + iconInfo->cbBitsColor)
-		return FALSE;
-
 	/* bitsMask */
 	newBitMask = (BYTE*)realloc(iconInfo->bitsMask, iconInfo->cbBitsMask);
 
@@ -150,6 +147,8 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo)
 	}
 
 	iconInfo->bitsMask = newBitMask;
+	if (Stream_GetRemainingLength(s) < iconInfo->cbBitsMask)
+		return FALSE;
 	Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask);
 
 	/* colorTable */
@@ -184,7 +183,11 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo)
 	}
 
 	if (iconInfo->colorTable)
+	{
+		if (Stream_GetRemainingLength(s) < iconInfo->cbColorTable)
+			return FALSE;
 		Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable);
+	}
 
 	/* bitsColor */
 	newBitMask = (BYTE*)realloc(iconInfo->bitsColor, iconInfo->cbBitsColor);
@@ -197,6 +200,8 @@ static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo)
 	}
 
 	iconInfo->bitsColor = newBitMask;
+	if (Stream_GetRemainingLength(s) < iconInfo->cbBitsColor)
+		return FALSE;
 	Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor);
 	return TRUE;
 }
path: libfreerdp/core/window.c