perl/Module-Build-Tiny: update to 0.051 for Perl 5.36 and 5.38
[oi-userland.git] / components / multimedia / gst-plugins-good / patches / 07-flxdec-bounds1.patch
blob3b9d87234d403f450e751239ed7b54dd106e41a6
1 Backport of:
3 From ec66c7c584f0b41c98e93758d9b53bd6dd582df2 Mon Sep 17 00:00:00 2001
4 From: Matthew Waters <matthew@centricular.com>
5 Date: Tue, 22 Nov 2016 19:05:00 +1100
6 Subject: flxdec: add some write bounds checking
8 Without checking the bounds of the frame we are writing into, we can
9 write off the end of the destination buffer.
11 https://scarybeastsecurity.blogspot.dk/2016/11/0day-exploit-advancing-exploitation.html
13 https://bugzilla.gnome.org/show_bug.cgi?id=774834
15 Index: gst-plugins-good0.10-0.10.31/gst/flx/gstflxdec.c
16 ===================================================================
17 --- gst-plugins-good0.10-0.10.31.orig/gst/flx/gstflxdec.c 2016-11-22 08:49:30.987370013 -0500
18 +++ gst-plugins-good0.10-0.10.31/gst/flx/gstflxdec.c 2016-11-22 08:52:35.889496961 -0500
19 @@ -70,9 +70,9 @@
20 static gboolean gst_flxdec_sink_event_handler (GstPad * pad, GstEvent * event);
22 static void flx_decode_color (GstFlxDec *, guchar *, guchar *, gint);
23 -static void flx_decode_brun (GstFlxDec *, guchar *, guchar *);
24 -static void flx_decode_delta_fli (GstFlxDec *, guchar *, guchar *);
25 -static void flx_decode_delta_flc (GstFlxDec *, guchar *, guchar *);
26 +static gboolean flx_decode_brun (GstFlxDec *, guchar *, guchar *);
27 +static gboolean flx_decode_delta_fli (GstFlxDec *, guchar *, guchar *);
28 +static gboolean flx_decode_delta_flc (GstFlxDec *, guchar *, guchar *);
30 #define rndalign(off) ((off) + ((off) & 1))
32 @@ -225,13 +225,14 @@
33 return ret;
36 -static void
37 +static gboolean
38 flx_decode_chunks (GstFlxDec * flxdec, gulong count, guchar * data,
39 guchar * dest)
41 FlxFrameChunk *hdr;
42 + gboolean ret = TRUE;
44 - g_return_if_fail (data != NULL);
45 + g_return_val_if_fail (data != NULL, FALSE);
47 while (count--) {
48 hdr = (FlxFrameChunk *) data;
49 @@ -250,17 +251,17 @@
50 break;
52 case FLX_BRUN:
53 - flx_decode_brun (flxdec, data, dest);
54 + ret = flx_decode_brun (flxdec, data, dest);
55 data += rndalign (hdr->size) - FlxFrameChunkSize;
56 break;
58 case FLX_LC:
59 - flx_decode_delta_fli (flxdec, data, dest);
60 + ret = flx_decode_delta_fli (flxdec, data, dest);
61 data += rndalign (hdr->size) - FlxFrameChunkSize;
62 break;
64 case FLX_SS2:
65 - flx_decode_delta_flc (flxdec, data, dest);
66 + ret = flx_decode_delta_flc (flxdec, data, dest);
67 data += rndalign (hdr->size) - FlxFrameChunkSize;
68 break;
70 @@ -278,7 +279,12 @@
71 data += rndalign (hdr->size) - FlxFrameChunkSize;
72 break;
75 + if (!ret)
76 + break;
79 + return ret;
83 @@ -311,13 +317,13 @@
87 -static void
88 +static gboolean
89 flx_decode_brun (GstFlxDec * flxdec, guchar * data, guchar * dest)
91 gulong count, lines, row;
92 guchar x;
94 - g_return_if_fail (flxdec != NULL);
95 + g_return_val_if_fail (flxdec != NULL, FALSE);
97 lines = flxdec->hdr.height;
98 while (lines--) {
99 @@ -335,12 +341,21 @@
100 if (count > 0x7f) {
101 /* literal run */
102 count = 0x100 - count;
103 + if ((glong) row - count < 0) {
104 + GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected.");
105 + return FALSE;
107 row -= count;
109 while (count--)
110 *dest++ = *data++;
112 } else {
113 + if ((glong) row - count < 0) {
114 + GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected.");
115 + return FALSE;
118 /* replicate run */
119 row -= count;
120 x = *data++;
121 @@ -350,16 +365,18 @@
126 + return TRUE;
129 -static void
130 +static gboolean
131 flx_decode_delta_fli (GstFlxDec * flxdec, guchar * data, guchar * dest)
133 gulong count, packets, lines, start_line;
134 guchar *start_p, x;
136 - g_return_if_fail (flxdec != NULL);
137 - g_return_if_fail (flxdec->delta != NULL);
138 + g_return_val_if_fail (flxdec != NULL, FALSE);
139 + g_return_val_if_fail (flxdec->delta != NULL, FALSE);
141 /* use last frame for delta */
142 memcpy (dest, GST_BUFFER_DATA (flxdec->delta),
143 @@ -367,6 +382,10 @@
145 start_line = (data[0] + (data[1] << 8));
146 lines = (data[2] + (data[3] << 8));
147 + if (start_line + lines > flxdec->hdr.height) {
148 + GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. too many lines.");
149 + return FALSE;
151 data += 4;
153 /* start position of delta */
154 @@ -379,7 +398,8 @@
156 while (packets--) {
157 /* skip count */
158 - dest += *data++;
159 + guchar skip = *data++;
160 + dest += skip;
162 /* RLE count */
163 count = *data++;
164 @@ -387,12 +407,24 @@
165 if (count > 0x7f) {
166 /* literal run */
167 count = 0x100 - count;
168 - x = *data++;
170 + if (skip + count > flxdec->hdr.width) {
171 + GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. "
172 + "line too long.");
173 + return FALSE;
176 + x = *data++;
177 while (count--)
178 *dest++ = x;
180 } else {
181 + if (skip + count > flxdec->hdr.width) {
182 + GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. "
183 + "line too long.");
184 + return FALSE;
187 /* replicate run */
188 while (count--)
189 *dest++ = *data++;
190 @@ -401,22 +433,28 @@
191 start_p += flxdec->hdr.width;
192 dest = start_p;
195 + return TRUE;
198 -static void
199 +static gboolean
200 flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest)
202 gulong count, lines, start_l, opcode;
203 guchar *start_p;
205 - g_return_if_fail (flxdec != NULL);
206 - g_return_if_fail (flxdec->delta != NULL);
207 + g_return_val_if_fail (flxdec != NULL, FALSE);
208 + g_return_val_if_fail (flxdec->delta != NULL, FALSE);
210 /* use last frame for delta */
211 memcpy (dest, GST_BUFFER_DATA (flxdec->delta),
212 GST_BUFFER_SIZE (flxdec->delta));
214 lines = (data[0] + (data[1] << 8));
215 + if (lines > flxdec->hdr.height) {
216 + GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. too many lines.");
217 + return FALSE;
219 data += 2;
221 start_p = dest;
222 @@ -429,9 +467,15 @@
223 while ((opcode = (data[0] + (data[1] << 8))) & 0xc000) {
224 data += 2;
225 if ((opcode & 0xc000) == 0xc000) {
226 - /* skip count */
227 - start_l += (0x10000 - opcode);
228 - dest += flxdec->hdr.width * (0x10000 - opcode);
229 + /* line skip count */
230 + gulong skip = (0x10000 - opcode);
231 + if (skip > flxdec->hdr.height) {
232 + GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. "
233 + "skip line count too big.");
234 + return FALSE;
236 + start_l += skip;
237 + dest += flxdec->hdr.width * skip;
238 } else {
239 /* last pixel */
240 dest += flxdec->hdr.width;
241 @@ -443,7 +487,8 @@
242 /* last opcode is the packet count */
243 while (opcode--) {
244 /* skip count */
245 - dest += *data++;
246 + guchar skip = *data++;
247 + dest += skip;
249 /* RLE count */
250 count = *data++;
251 @@ -451,12 +496,25 @@
252 if (count > 0x7f) {
253 /* replicate word run */
254 count = 0x100 - count;
256 + if (skip + count > flxdec->hdr.width) {
257 + GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. "
258 + "line too long.");
259 + return FALSE;
262 while (count--) {
263 *dest++ = data[0];
264 *dest++ = data[1];
266 data += 2;
267 } else {
268 + if (skip + count > flxdec->hdr.width) {
269 + GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. "
270 + "line too long.");
271 + return FALSE;
274 /* literal word run */
275 while (count--) {
276 *dest++ = *data++;
277 @@ -466,6 +524,8 @@
279 lines--;
282 + return TRUE;
285 static GstFlowReturn
286 @@ -593,9 +653,13 @@
287 break;
289 /* decode chunks */
290 - flx_decode_chunks (flxdec,
291 - ((FlxFrameType *) chunk)->chunks,
292 - chunk + FlxFrameTypeSize, GST_BUFFER_DATA (flxdec->frame));
293 + if (!flx_decode_chunks (flxdec,
294 + ((FlxFrameType *) chunk)->chunks,
295 + chunk + FlxFrameTypeSize, GST_BUFFER_DATA (flxdec->frame))) {
296 + GST_ELEMENT_ERROR (flxdec, STREAM, DECODE,
297 + ("%s", "Could not decode chunk"), NULL);
298 + return GST_FLOW_ERROR;
301 /* save copy of the current frame for possible delta. */
302 memcpy (GST_BUFFER_DATA (flxdec->delta),