Description: fix integer overflow in xf_Pointer_New
Origin: vendor, https://build.opensuse.org/request/show/237030
Bug-Redhat: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-0250
Bug: https://github.com/FreeRDP/FreeRDP/issues/1871
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=749585
Bug-Suse: https://bugzilla.novell.com/show_bug.cgi?id=CVE-2014-0250

Index: freerdp-1.0.2/libfreerdp-core/fastpath.c
===================================================================
--- freerdp-1.0.2.orig/libfreerdp-core/fastpath.c	2017-08-03 09:47:58.319217330 -0400
+++ freerdp-1.0.2/libfreerdp-core/fastpath.c	2017-08-03 09:47:58.315217330 -0400
@@ -203,8 +203,10 @@ static void fastpath_recv_update(rdpFast
 			break;
 
 		case FASTPATH_UPDATETYPE_COLOR:
-			update_read_pointer_color(s, &pointer->pointer_color);
-			IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
+			if (update_read_pointer_color(s, &pointer->pointer_color))
+				IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
+			else
+				DEBUG_WARN("update color failed");
 			break;
 
 		case FASTPATH_UPDATETYPE_CACHED:
@@ -213,8 +215,10 @@ static void fastpath_recv_update(rdpFast
 			break;
 
 		case FASTPATH_UPDATETYPE_POINTER:
-			update_read_pointer_new(s, &pointer->pointer_new);
-			IFCALL(pointer->PointerNew, context, &pointer->pointer_new);
+			if (update_read_pointer_new(s, &pointer->pointer_new))
+				IFCALL(pointer->PointerNew, context, &pointer->pointer_new);
+			else
+				DEBUG_WARN("update pointer error");
 			break;
 
 		default:
Index: freerdp-1.0.2/libfreerdp-core/rdp.c
===================================================================
--- freerdp-1.0.2.orig/libfreerdp-core/rdp.c	2017-08-03 09:47:58.319217330 -0400
+++ freerdp-1.0.2/libfreerdp-core/rdp.c	2017-08-03 09:47:58.315217330 -0400
@@ -483,7 +483,7 @@ void rdp_recv_set_error_info_data_pdu(rd
 		rdp_print_errinfo(rdp->errorInfo);
 }
 
-void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
+boolean rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
 {
 	uint8 type;
 	uint16 length;
@@ -509,7 +509,8 @@ void rdp_recv_data_pdu(rdpRdp* rdp, STRE
 			break;
 
 		case DATA_PDU_TYPE_POINTER:
-			update_recv_pointer(rdp->update, s);
+			if (!update_recv_pointer(rdp->update, s))
+				return false;
 			break;
 
 		case DATA_PDU_TYPE_INPUT:
@@ -583,6 +584,7 @@ void rdp_recv_data_pdu(rdpRdp* rdp, STRE
 		default:
 			break;
 	}
+	return true;
 }
 
 boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
@@ -595,8 +597,10 @@ boolean rdp_recv_out_of_sequence_pdu(rdp
 
 	if (type == PDU_TYPE_DATA)
 	{
-		rdp_recv_data_pdu(rdp, s);
-		return true;
+		if (rdp_recv_data_pdu(rdp, s))
+			return true;
+		else
+			return false;
 	}
 	else if (type == PDU_TYPE_SERVER_REDIRECTION)
 	{
@@ -734,7 +738,8 @@ static boolean rdp_recv_tpkt_pdu(rdpRdp*
 		switch (pduType)
 		{
 			case PDU_TYPE_DATA:
-				rdp_recv_data_pdu(rdp, s);
+				if (!rdp_recv_data_pdu(rdp, s))
+					return false;
 				break;
 
 			case PDU_TYPE_DEACTIVATE_ALL:
Index: freerdp-1.0.2/libfreerdp-core/rdp.h
===================================================================
--- freerdp-1.0.2.orig/libfreerdp-core/rdp.h	2017-08-03 09:47:58.319217330 -0400
+++ freerdp-1.0.2/libfreerdp-core/rdp.h	2017-08-03 09:47:58.315217330 -0400
@@ -181,7 +181,7 @@ boolean rdp_send_pdu(rdpRdp* rdp, STREAM
 
 STREAM* rdp_data_pdu_init(rdpRdp* rdp);
 boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id);
-void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s);
+boolean rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s);
 
 boolean rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id);
 void rdp_recv(rdpRdp* rdp);
Index: freerdp-1.0.2/libfreerdp-core/update.c
===================================================================
--- freerdp-1.0.2.orig/libfreerdp-core/update.c	2017-08-03 09:47:58.319217330 -0400
+++ freerdp-1.0.2/libfreerdp-core/update.c	2017-08-03 09:47:58.315217330 -0400
@@ -165,13 +165,27 @@ void update_read_pointer_system(STREAM*
 	stream_read_uint32(s, pointer_system->type); /* systemPointerType (4 bytes) */
 }
 
-void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color)
+boolean update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color)
 {
 	stream_read_uint16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */
 	stream_read_uint16(s, pointer_color->xPos); /* xPos (2 bytes) */
 	stream_read_uint16(s, pointer_color->yPos); /* yPos (2 bytes) */
+
+    /**
+         *  As stated in 2.2.9.1.1.4.4 Color Pointer Update:
+         *  The maximum allowed pointer width/height is 96 pixels if the client indicated support
+         *  for large pointers by setting the LARGE_POINTER_FLAG (0x00000001) in the Large
+         *  Pointer Capability Set (section 2.2.7.2.7). If the LARGE_POINTER_FLAG was not
+         *  set, the maximum allowed pointer width/height is 32 pixels.
+         *
+         *  So we check for a maximum of 96 for CVE-2014-0250.
+         */
 	stream_read_uint16(s, pointer_color->width); /* width (2 bytes) */
 	stream_read_uint16(s, pointer_color->height); /* height (2 bytes) */
+        if ((pointer_color->width > 96) || (pointer_color->height > 96))
+                return false;
+
+
 	stream_read_uint16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */
 	stream_read_uint16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */
 
@@ -200,12 +214,13 @@ void update_read_pointer_color(STREAM* s
 
 	if (stream_get_left(s) > 0)
 		stream_seek_uint8(s); /* pad (1 byte) */
+	return true;
 }
 
-void update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new)
+boolean update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new)
 {
 	stream_read_uint16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
-	update_read_pointer_color(s, &pointer_new->colorPtrAttr); /* colorPtrAttr */
+	return update_read_pointer_color(s, &pointer_new->colorPtrAttr); /* colorPtrAttr */
 }
 
 void update_read_pointer_cached(STREAM* s, POINTER_CACHED_UPDATE* pointer_cached)
@@ -213,7 +228,7 @@ void update_read_pointer_cached(STREAM*
 	stream_read_uint16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
 }
 
-void update_recv_pointer(rdpUpdate* update, STREAM* s)
+boolean update_recv_pointer(rdpUpdate* update, STREAM* s)
 {
 	uint16 messageType;
 	rdpContext* context = update->context;
@@ -235,8 +250,10 @@ void update_recv_pointer(rdpUpdate* upda
 			break;
 
 		case PTR_MSG_TYPE_COLOR:
-			update_read_pointer_color(s, &pointer->pointer_color);
-			IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
+			if (update_read_pointer_color(s, &pointer->pointer_color))
+				IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
+			else
+				return false;
 			break;
 
 		case PTR_MSG_TYPE_POINTER:
@@ -252,6 +269,7 @@ void update_recv_pointer(rdpUpdate* upda
 		default:
 			break;
 	}
+	return true;
 }
 
 void update_recv(rdpUpdate* update, STREAM* s)
Index: freerdp-1.0.2/libfreerdp-core/update.h
===================================================================
--- freerdp-1.0.2.orig/libfreerdp-core/update.h	2017-08-03 09:47:58.319217330 -0400
+++ freerdp-1.0.2/libfreerdp-core/update.h	2017-08-03 09:47:58.315217330 -0400
@@ -43,13 +43,13 @@ void update_reset_state(rdpUpdate* updat
 void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_update);
 void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update);
 void update_recv_play_sound(rdpUpdate* update, STREAM* s);
-void update_recv_pointer(rdpUpdate* update, STREAM* s);
+boolean update_recv_pointer(rdpUpdate* update, STREAM* s);
 void update_recv(rdpUpdate* update, STREAM* s);
 
 void update_read_pointer_position(STREAM* s, POINTER_POSITION_UPDATE* pointer_position);
 void update_read_pointer_system(STREAM* s, POINTER_SYSTEM_UPDATE* pointer_system);
-void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color);
-void update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new);
+boolean update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color);
+boolean update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new);
 void update_read_pointer_cached(STREAM* s, POINTER_CACHED_UPDATE* pointer_cached);
 
 void update_register_server_callbacks(rdpUpdate* update);
