Gentoo Archives: gentoo-commits

From: "Mike Gilbert (floppym)" <floppym@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in net-misc/freerdp/files: freerdp-1.1-CVE-2014-0250.patch
Date: Sat, 21 Jun 2014 01:55:14
Message-Id: 20140621015510.0B0892004F@flycatcher.gentoo.org
1 floppym 14/06/21 01:55:09
2
3 Added: freerdp-1.1-CVE-2014-0250.patch
4 Log:
5 Add fix for CVE-2014-0250, bug 511688.
6
7 (Portage version: 2.2.10/cvs/Linux x86_64, signed Manifest commit with key 0BBEEA1FEA4843A4)
8
9 Revision Changes Path
10 1.1 net-misc/freerdp/files/freerdp-1.1-CVE-2014-0250.patch
11
12 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-misc/freerdp/files/freerdp-1.1-CVE-2014-0250.patch?rev=1.1&view=markup
13 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-misc/freerdp/files/freerdp-1.1-CVE-2014-0250.patch?rev=1.1&content-type=text/plain
14
15 Index: freerdp-1.1-CVE-2014-0250.patch
16 ===================================================================
17 From 5ad707ddf33d1d785a8ca1fbeec91d2eee985820 Mon Sep 17 00:00:00 2001
18 From: Hardening <rdp.effort@×××××.com>
19 Date: Fri, 6 Jun 2014 23:24:16 +0200
20 Subject: [PATCH] Fix CVE-2014-0250
21
22 This patch fixes CVE-2014-0250 by checking width, height and bpp when
23 receiving a new pointer.
24 ---
25 client/X11/xf_cliprdr.c | 11 +++++--
26 libfreerdp/core/fastpath.c | 2 +-
27 libfreerdp/core/orders.c | 21 ++++++++++++
28 libfreerdp/core/surface.c | 6 ++++
29 libfreerdp/core/update.c | 82 +++++++++++++++++++++++++++++++++++++++-------
30 libfreerdp/core/update.h | 2 +-
31 libfreerdp/core/window.c | 5 +++
32 7 files changed, 114 insertions(+), 15 deletions(-)
33
34 diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c
35 index 19c4332..8fb49f9 100644
36 --- a/client/X11/xf_cliprdr.c
37 +++ b/client/X11/xf_cliprdr.c
38 @@ -914,7 +914,7 @@ static void xf_cliprdr_process_unicodetext(clipboardContext* cb, BYTE* data, int
39 crlf2lf(cb->data, &cb->data_length);
40 }
41
42 -static void xf_cliprdr_process_dib(clipboardContext* cb, BYTE* data, int size)
43 +static BOOL xf_cliprdr_process_dib(clipboardContext* cb, BYTE* data, int size)
44 {
45 wStream* s;
46 UINT16 bpp;
47 @@ -926,12 +926,18 @@ static void xf_cliprdr_process_dib(clipboardContext* cb, BYTE* data, int size)
48 if (size < 40)
49 {
50 DEBUG_X11_CLIPRDR("dib size %d too short", size);
51 - return;
52 + return FALSE;
53 }
54
55 s = Stream_New(data, size);
56 Stream_Seek(s, 14);
57 Stream_Read_UINT16(s, bpp);
58 + if ((bpp < 1) || (bpp > 32))
59 + {
60 + fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, bpp);
61 + return FALSE;
62 + }
63 +
64 Stream_Read_UINT32(s, ncolors);
65 offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0);
66 Stream_Free(s, FALSE);
67 @@ -949,6 +955,7 @@ static void xf_cliprdr_process_dib(clipboardContext* cb, BYTE* data, int size)
68 cb->data = Stream_Buffer(s);
69 cb->data_length = Stream_GetPosition(s);
70 Stream_Free(s, FALSE);
71 + return TRUE;
72 }
73
74 static void xf_cliprdr_process_html(clipboardContext* cb, BYTE* data, int size)
75 diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c
76 index 8448160..dcc7117 100644
77 --- a/libfreerdp/core/fastpath.c
78 +++ b/libfreerdp/core/fastpath.c
79 @@ -254,7 +254,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
80 break;
81
82 case FASTPATH_UPDATETYPE_COLOR:
83 - if (!update_read_pointer_color(s, &pointer->pointer_color))
84 + if (!update_read_pointer_color(s, &pointer->pointer_color, 24))
85 return -1;
86 IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
87 break;
88 diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c
89 index e5cc520..f22407f 100644
90 --- a/libfreerdp/core/orders.c
91 +++ b/libfreerdp/core/orders.c
92 @@ -1830,6 +1830,11 @@ BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap
93 Stream_Read_UINT8(s, cache_bitmap->bitmapWidth); /* bitmapWidth (1 byte) */
94 Stream_Read_UINT8(s, cache_bitmap->bitmapHeight); /* bitmapHeight (1 byte) */
95 Stream_Read_UINT8(s, cache_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */
96 + if ((cache_bitmap->bitmapBpp < 1) || (cache_bitmap->bitmapBpp > 32))
97 + {
98 + fprintf(stderr, "%s: invalid bitmap bpp %d\n", __FUNCTION__, cache_bitmap->bitmapBpp);
99 + return FALSE;
100 + }
101 Stream_Read_UINT16(s, cache_bitmap->bitmapLength); /* bitmapLength (2 bytes) */
102 Stream_Read_UINT16(s, cache_bitmap->cacheIndex); /* cacheIndex (2 bytes) */
103
104 @@ -2068,6 +2073,11 @@ BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_
105 bitmapData = &cache_bitmap_v3->bitmapData;
106
107 Stream_Read_UINT8(s, bitmapData->bpp);
108 + if ((bitmapData->bpp < 1) || (bitmapData->bpp > 32))
109 + {
110 + fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, bitmapData->bpp);
111 + return FALSE;
112 + }
113 Stream_Seek_UINT8(s); /* reserved1 (1 byte) */
114 Stream_Seek_UINT8(s); /* reserved2 (1 byte) */
115 Stream_Read_UINT8(s, bitmapData->codecID); /* codecID (1 byte) */
116 @@ -2672,6 +2682,11 @@ BOOL update_read_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITM
117 return FALSE;
118
119 Stream_Read_UINT8(s, create_nine_grid_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */
120 + if ((create_nine_grid_bitmap->bitmapBpp < 1) || (create_nine_grid_bitmap->bitmapBpp > 32))
121 + {
122 + fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, create_nine_grid_bitmap->bitmapBpp);
123 + return FALSE;
124 + }
125 Stream_Read_UINT16(s, create_nine_grid_bitmap->bitmapId); /* bitmapId (2 bytes) */
126
127 nineGridInfo = &(create_nine_grid_bitmap->nineGridInfo);
128 @@ -2707,6 +2722,12 @@ BOOL update_read_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER
129
130 Stream_Read_UINT8(s, stream_bitmap_first->bitmapFlags); /* bitmapFlags (1 byte) */
131 Stream_Read_UINT8(s, stream_bitmap_first->bitmapBpp); /* bitmapBpp (1 byte) */
132 + if ((stream_bitmap_first->bitmapBpp < 1) || (stream_bitmap_first->bitmapBpp > 32))
133 + {
134 + fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, stream_bitmap_first->bitmapBpp);
135 + return FALSE;
136 + }
137 +
138 Stream_Read_UINT16(s, stream_bitmap_first->bitmapType); /* bitmapType (2 bytes) */
139 Stream_Read_UINT16(s, stream_bitmap_first->bitmapWidth); /* bitmapWidth (2 bytes) */
140 Stream_Read_UINT16(s, stream_bitmap_first->bitmapHeight); /* bitmapHeigth (2 bytes) */
141 diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c
142 index 7d0fb22..992a3dd 100644
143 --- a/libfreerdp/core/surface.c
144 +++ b/libfreerdp/core/surface.c
145 @@ -38,6 +38,12 @@ static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT3
146 Stream_Read_UINT16(s, cmd->destRight);
147 Stream_Read_UINT16(s, cmd->destBottom);
148 Stream_Read_UINT8(s, cmd->bpp);
149 + if ((cmd->bpp < 1) || (cmd->bpp > 32))
150 + {
151 + fprintf(stderr, "%s: invalid bpp value %d", __FUNCTION__, cmd->bpp);
152 + return FALSE;
153 + }
154 +
155 Stream_Seek(s, 2); /* reserved1, reserved2 */
156 Stream_Read_UINT8(s, cmd->codecID);
157 Stream_Read_UINT16(s, cmd->width);
158 diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c
159 index c4eaede..27c36e3 100644
160 --- a/libfreerdp/core/update.c
161 +++ b/libfreerdp/core/update.c
162 @@ -219,16 +219,32 @@ BOOL update_read_pointer_system(wStream* s, POINTER_SYSTEM_UPDATE* pointer_syste
163 return TRUE;
164 }
165
166 -BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color)
167 +BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, int xorBpp)
168 {
169 + BYTE *newMask;
170 + int scanlineSize;
171 +
172 if (Stream_GetRemainingLength(s) < 14)
173 return FALSE;
174
175 Stream_Read_UINT16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */
176 Stream_Read_UINT16(s, pointer_color->xPos); /* xPos (2 bytes) */
177 Stream_Read_UINT16(s, pointer_color->yPos); /* yPos (2 bytes) */
178 +
179 + /**
180 + * As stated in 2.2.9.1.1.4.4 Color Pointer Update:
181 + * The maximum allowed pointer width/height is 96 pixels if the client indicated support
182 + * for large pointers by setting the LARGE_POINTER_FLAG (0x00000001) in the Large
183 + * Pointer Capability Set (section 2.2.7.2.7). If the LARGE_POINTER_FLAG was not
184 + * set, the maximum allowed pointer width/height is 32 pixels.
185 + *
186 + * So we check for a maximum of 96 for CVE-2014-0250.
187 + */
188 Stream_Read_UINT16(s, pointer_color->width); /* width (2 bytes) */
189 Stream_Read_UINT16(s, pointer_color->height); /* height (2 bytes) */
190 + if ((pointer_color->width > 96) || (pointer_color->height > 96))
191 + return FALSE;
192 +
193 Stream_Read_UINT16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */
194 Stream_Read_UINT16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */
195
196 @@ -245,26 +261,65 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color)
197
198 if (pointer_color->lengthXorMask > 0)
199 {
200 + /**
201 + * Spec states that:
202 + *
203 + * xorMaskData (variable): A variable-length array of bytes. Contains the 24-bpp, bottom-up
204 + * XOR mask scan-line data. The XOR mask is padded to a 2-byte boundary for each encoded
205 + * scan-line. For example, if a 3x3 pixel cursor is being sent, then each scan-line will consume 10
206 + * bytes (3 pixels per scan-line multiplied by 3 bytes per pixel, rounded up to the next even
207 + * number of bytes).
208 + *
209 + * In fact instead of 24-bpp, the bpp parameter is given by the containing packet.
210 + */
211 if (Stream_GetRemainingLength(s) < pointer_color->lengthXorMask)
212 return FALSE;
213
214 - if (!pointer_color->xorMaskData)
215 - pointer_color->xorMaskData = malloc(pointer_color->lengthXorMask);
216 - else
217 - pointer_color->xorMaskData = realloc(pointer_color->xorMaskData, pointer_color->lengthXorMask);
218 + scanlineSize = (7 + xorBpp * pointer_color->width) / 8;
219 + scanlineSize = ((scanlineSize + 1) / 2) * 2;
220 + if (scanlineSize * pointer_color->height != pointer_color->lengthXorMask)
221 + {
222 + fprintf(stderr, "%s: invalid lengthXorMask: width=%d height=%d, %d instead of %d\n", __FUNCTION__,
223 + pointer_color->width, pointer_color->height,
224 + pointer_color->lengthXorMask, scanlineSize * pointer_color->height);
225 + return FALSE;
226 + }
227 +
228 + newMask = realloc(pointer_color->xorMaskData, pointer_color->lengthXorMask);
229 + if (!newMask)
230 + return FALSE;
231 +
232 + pointer_color->xorMaskData = newMask;
233
234 Stream_Read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask);
235 }
236
237 if (pointer_color->lengthAndMask > 0)
238 {
239 + /**
240 + * andMaskData (variable): A variable-length array of bytes. Contains the 1-bpp, bottom-up
241 + * AND mask scan-line data. The AND mask is padded to a 2-byte boundary for each encoded
242 + * scan-line. For example, if a 7x7 pixel cursor is being sent, then each scan-line will consume 2
243 + * bytes (7 pixels per scan-line multiplied by 1 bpp, rounded up to the next even number of
244 + * bytes).
245 + */
246 if (Stream_GetRemainingLength(s) < pointer_color->lengthAndMask)
247 return FALSE;
248
249 - if (!pointer_color->andMaskData)
250 - pointer_color->andMaskData = malloc(pointer_color->lengthAndMask);
251 - else
252 - pointer_color->andMaskData = realloc(pointer_color->andMaskData, pointer_color->lengthAndMask);
253 + scanlineSize = ((7 + pointer_color->width) / 8);
254 + scanlineSize = ((1 + scanlineSize) / 2) * 2;
255 + if (scanlineSize * pointer_color->height != pointer_color->lengthAndMask)
256 + {
257 + fprintf(stderr, "%s: invalid lengthAndMask: %d instead of %d\n", __FUNCTION__,
258 + pointer_color->lengthAndMask, scanlineSize * pointer_color->height);
259 + return FALSE;
260 + }
261 +
262 + newMask = realloc(pointer_color->andMaskData, pointer_color->lengthAndMask);
263 + if (!newMask)
264 + return FALSE;
265 +
266 + pointer_color->andMaskData = newMask;
267
268 Stream_Read(s, pointer_color->andMaskData, pointer_color->lengthAndMask);
269 }
270 @@ -281,7 +336,12 @@ BOOL update_read_pointer_new(wStream* s, POINTER_NEW_UPDATE* pointer_new)
271 return FALSE;
272
273 Stream_Read_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
274 - return update_read_pointer_color(s, &pointer_new->colorPtrAttr); /* colorPtrAttr */
275 + if ((pointer_new->xorBpp < 1) || (pointer_new->xorBpp > 32))
276 + {
277 + fprintf(stderr, "%s: invalid xorBpp %d\n", __FUNCTION__, pointer_new->xorBpp);
278 + return FALSE;
279 + }
280 + return update_read_pointer_color(s, &pointer_new->colorPtrAttr, pointer_new->xorBpp); /* colorPtrAttr */
281 }
282
283 BOOL update_read_pointer_cached(wStream* s, POINTER_CACHED_UPDATE* pointer_cached)
284 @@ -320,7 +380,7 @@ BOOL update_recv_pointer(rdpUpdate* update, wStream* s)
285 break;
286
287 case PTR_MSG_TYPE_COLOR:
288 - if (!update_read_pointer_color(s, &pointer->pointer_color))
289 + if (!update_read_pointer_color(s, &pointer->pointer_color, 24))
290 return FALSE;
291 IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
292 break;
293 diff --git a/libfreerdp/core/update.h b/libfreerdp/core/update.h
294 index c3088f2..d6c2d59 100644
295 --- a/libfreerdp/core/update.h
296 +++ b/libfreerdp/core/update.h
297 @@ -53,7 +53,7 @@ BOOL update_recv(rdpUpdate* update, wStream* s);
298
299 BOOL update_read_pointer_position(wStream* s, POINTER_POSITION_UPDATE* pointer_position);
300 BOOL update_read_pointer_system(wStream* s, POINTER_SYSTEM_UPDATE* pointer_system);
301 -BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color);
302 +BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, int xorBpp);
303 BOOL update_read_pointer_new(wStream* s, POINTER_NEW_UPDATE* pointer_new);
304 BOOL update_read_pointer_cached(wStream* s, POINTER_CACHED_UPDATE* pointer_cached);
305
306 diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c
307 index 7422f5b..c10fa33 100644
308 --- a/libfreerdp/core/window.c
309 +++ b/libfreerdp/core/window.c
310 @@ -35,6 +35,11 @@ BOOL update_read_icon_info(wStream* s, ICON_INFO* icon_info)
311 Stream_Read_UINT16(s, icon_info->cacheEntry); /* cacheEntry (2 bytes) */
312 Stream_Read_UINT8(s, icon_info->cacheId); /* cacheId (1 byte) */
313 Stream_Read_UINT8(s, icon_info->bpp); /* bpp (1 byte) */
314 + if ((icon_info->bpp < 1) || (icon_info->bpp > 32))
315 + {
316 + fprintf(stderr, "%s: invalid bpp %d\n", __FUNCTION__, icon_info->bpp);
317 + return FALSE;
318 + }
319 Stream_Read_UINT16(s, icon_info->width); /* width (2 bytes) */
320 Stream_Read_UINT16(s, icon_info->height); /* height (2 bytes) */
321
322 --
323 1.9.3