diff -Nru gst-plugins-good0.10-0.10.31/debian/changelog gst-plugins-good0.10-0.10.31/debian/changelog --- gst-plugins-good0.10-0.10.31/debian/changelog 2013-02-13 12:52:41.000000000 +0000 +++ gst-plugins-good0.10-0.10.31/debian/changelog 2016-11-22 13:56:53.000000000 +0000 @@ -1,3 +1,14 @@ +gst-plugins-good0.10 (0.10.31-1ubuntu1.3) precise-security; urgency=medium + + * SECURITY UPDATE: code execution via out-of-bounds write in flx decoder + - debian/patches/flxdec-bounds1.patch: add bounds checking to + gst/flx/gstflxdec.c. + - debian/patches/flxdec-bounds2.patch: fix compiler warnings in + gst/flx/gstflxdec.c. + - No CVE number + + -- Marc Deslauriers Tue, 22 Nov 2016 08:56:53 -0500 + gst-plugins-good0.10 (0.10.31-1ubuntu1.2) precise; urgency=low * debian/patches/0001-fix-v4l2_munmap.patch: Cherry-pick a commit from diff -Nru gst-plugins-good0.10-0.10.31/debian/patches/flxdec-bounds1.patch gst-plugins-good0.10-0.10.31/debian/patches/flxdec-bounds1.patch --- gst-plugins-good0.10-0.10.31/debian/patches/flxdec-bounds1.patch 1970-01-01 00:00:00.000000000 +0000 +++ gst-plugins-good0.10-0.10.31/debian/patches/flxdec-bounds1.patch 2016-11-22 15:29:49.000000000 +0000 @@ -0,0 +1,302 @@ +Backport of: + +From ec66c7c584f0b41c98e93758d9b53bd6dd582df2 Mon Sep 17 00:00:00 2001 +From: Matthew Waters +Date: Tue, 22 Nov 2016 19:05:00 +1100 +Subject: flxdec: add some write bounds checking + +Without checking the bounds of the frame we are writing into, we can +write off the end of the destination buffer. + +https://scarybeastsecurity.blogspot.dk/2016/11/0day-exploit-advancing-exploitation.html + +https://bugzilla.gnome.org/show_bug.cgi?id=774834 + +Index: gst-plugins-good0.10-0.10.31/gst/flx/gstflxdec.c +=================================================================== +--- gst-plugins-good0.10-0.10.31.orig/gst/flx/gstflxdec.c 2016-11-22 08:49:30.987370013 -0500 ++++ gst-plugins-good0.10-0.10.31/gst/flx/gstflxdec.c 2016-11-22 08:52:35.889496961 -0500 +@@ -70,9 +70,9 @@ + static gboolean gst_flxdec_sink_event_handler (GstPad * pad, GstEvent * event); + + static void flx_decode_color (GstFlxDec *, guchar *, guchar *, gint); +-static void flx_decode_brun (GstFlxDec *, guchar *, guchar *); +-static void flx_decode_delta_fli (GstFlxDec *, guchar *, guchar *); +-static void flx_decode_delta_flc (GstFlxDec *, guchar *, guchar *); ++static gboolean flx_decode_brun (GstFlxDec *, guchar *, guchar *); ++static gboolean flx_decode_delta_fli (GstFlxDec *, guchar *, guchar *); ++static gboolean flx_decode_delta_flc (GstFlxDec *, guchar *, guchar *); + + #define rndalign(off) ((off) + ((off) & 1)) + +@@ -225,13 +225,14 @@ + return ret; + } + +-static void ++static gboolean + flx_decode_chunks (GstFlxDec * flxdec, gulong count, guchar * data, + guchar * dest) + { + FlxFrameChunk *hdr; ++ gboolean ret = TRUE; + +- g_return_if_fail (data != NULL); ++ g_return_val_if_fail (data != NULL, FALSE); + + while (count--) { + hdr = (FlxFrameChunk *) data; +@@ -250,17 +251,17 @@ + break; + + case FLX_BRUN: +- flx_decode_brun (flxdec, data, dest); ++ ret = flx_decode_brun (flxdec, data, dest); + data += rndalign (hdr->size) - FlxFrameChunkSize; + break; + + case FLX_LC: +- flx_decode_delta_fli (flxdec, data, dest); ++ ret = flx_decode_delta_fli (flxdec, data, dest); + data += rndalign (hdr->size) - FlxFrameChunkSize; + break; + + case FLX_SS2: +- flx_decode_delta_flc (flxdec, data, dest); ++ ret = flx_decode_delta_flc (flxdec, data, dest); + data += rndalign (hdr->size) - FlxFrameChunkSize; + break; + +@@ -278,7 +279,12 @@ + data += rndalign (hdr->size) - FlxFrameChunkSize; + break; + } ++ ++ if (!ret) ++ break; + } ++ ++ return ret; + } + + +@@ -311,13 +317,13 @@ + } + } + +-static void ++static gboolean + flx_decode_brun (GstFlxDec * flxdec, guchar * data, guchar * dest) + { + gulong count, lines, row; + guchar x; + +- g_return_if_fail (flxdec != NULL); ++ g_return_val_if_fail (flxdec != NULL, FALSE); + + lines = flxdec->hdr.height; + while (lines--) { +@@ -335,12 +341,21 @@ + if (count > 0x7f) { + /* literal run */ + count = 0x100 - count; ++ if ((glong) row - count < 0) { ++ GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected."); ++ return FALSE; ++ } + row -= count; + + while (count--) + *dest++ = *data++; + + } else { ++ if ((glong) row - count < 0) { ++ GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected."); ++ return FALSE; ++ } ++ + /* replicate run */ + row -= count; + x = *data++; +@@ -350,16 +365,18 @@ + } + } + } ++ ++ return TRUE; + } + +-static void ++static gboolean + flx_decode_delta_fli (GstFlxDec * flxdec, guchar * data, guchar * dest) + { + gulong count, packets, lines, start_line; + guchar *start_p, x; + +- g_return_if_fail (flxdec != NULL); +- g_return_if_fail (flxdec->delta != NULL); ++ g_return_val_if_fail (flxdec != NULL, FALSE); ++ g_return_val_if_fail (flxdec->delta != NULL, FALSE); + + /* use last frame for delta */ + memcpy (dest, GST_BUFFER_DATA (flxdec->delta), +@@ -367,6 +382,10 @@ + + start_line = (data[0] + (data[1] << 8)); + lines = (data[2] + (data[3] << 8)); ++ if (start_line + lines > flxdec->hdr.height) { ++ GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. too many lines."); ++ return FALSE; ++ } + data += 4; + + /* start position of delta */ +@@ -379,7 +398,8 @@ + + while (packets--) { + /* skip count */ +- dest += *data++; ++ guchar skip = *data++; ++ dest += skip; + + /* RLE count */ + count = *data++; +@@ -387,12 +407,24 @@ + if (count > 0x7f) { + /* literal run */ + count = 0x100 - count; +- x = *data++; + ++ if (skip + count > flxdec->hdr.width) { ++ GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. " ++ "line too long."); ++ return FALSE; ++ } ++ ++ x = *data++; + while (count--) + *dest++ = x; + + } else { ++ if (skip + count > flxdec->hdr.width) { ++ GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. " ++ "line too long."); ++ return FALSE; ++ } ++ + /* replicate run */ + while (count--) + *dest++ = *data++; +@@ -401,22 +433,28 @@ + start_p += flxdec->hdr.width; + dest = start_p; + } ++ ++ return TRUE; + } + +-static void ++static gboolean + flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) + { + gulong count, lines, start_l, opcode; + guchar *start_p; + +- g_return_if_fail (flxdec != NULL); +- g_return_if_fail (flxdec->delta != NULL); ++ g_return_val_if_fail (flxdec != NULL, FALSE); ++ g_return_val_if_fail (flxdec->delta != NULL, FALSE); + + /* use last frame for delta */ + memcpy (dest, GST_BUFFER_DATA (flxdec->delta), + GST_BUFFER_SIZE (flxdec->delta)); + + lines = (data[0] + (data[1] << 8)); ++ if (lines > flxdec->hdr.height) { ++ GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. too many lines."); ++ return FALSE; ++ } + data += 2; + + start_p = dest; +@@ -429,9 +467,15 @@ + while ((opcode = (data[0] + (data[1] << 8))) & 0xc000) { + data += 2; + if ((opcode & 0xc000) == 0xc000) { +- /* skip count */ +- start_l += (0x10000 - opcode); +- dest += flxdec->hdr.width * (0x10000 - opcode); ++ /* line skip count */ ++ gulong skip = (0x10000 - opcode); ++ if (skip > flxdec->hdr.height) { ++ GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. " ++ "skip line count too big."); ++ return FALSE; ++ } ++ start_l += skip; ++ dest += flxdec->hdr.width * skip; + } else { + /* last pixel */ + dest += flxdec->hdr.width; +@@ -443,7 +487,8 @@ + /* last opcode is the packet count */ + while (opcode--) { + /* skip count */ +- dest += *data++; ++ guchar skip = *data++; ++ dest += skip; + + /* RLE count */ + count = *data++; +@@ -451,12 +496,25 @@ + if (count > 0x7f) { + /* replicate word run */ + count = 0x100 - count; ++ ++ if (skip + count > flxdec->hdr.width) { ++ GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. " ++ "line too long."); ++ return FALSE; ++ } ++ + while (count--) { + *dest++ = data[0]; + *dest++ = data[1]; + } + data += 2; + } else { ++ if (skip + count > flxdec->hdr.width) { ++ GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. " ++ "line too long."); ++ return FALSE; ++ } ++ + /* literal word run */ + while (count--) { + *dest++ = *data++; +@@ -466,6 +524,8 @@ + } + lines--; + } ++ ++ return TRUE; + } + + static GstFlowReturn +@@ -593,9 +653,13 @@ + break; + + /* decode chunks */ +- flx_decode_chunks (flxdec, +- ((FlxFrameType *) chunk)->chunks, +- chunk + FlxFrameTypeSize, GST_BUFFER_DATA (flxdec->frame)); ++ if (!flx_decode_chunks (flxdec, ++ ((FlxFrameType *) chunk)->chunks, ++ chunk + FlxFrameTypeSize, GST_BUFFER_DATA (flxdec->frame))) { ++ GST_ELEMENT_ERROR (flxdec, STREAM, DECODE, ++ ("%s", "Could not decode chunk"), NULL); ++ return GST_FLOW_ERROR; ++ } + + /* save copy of the current frame for possible delta. */ + memcpy (GST_BUFFER_DATA (flxdec->delta), diff -Nru gst-plugins-good0.10-0.10.31/debian/patches/flxdec-bounds2.patch gst-plugins-good0.10-0.10.31/debian/patches/flxdec-bounds2.patch --- gst-plugins-good0.10-0.10.31/debian/patches/flxdec-bounds2.patch 1970-01-01 00:00:00.000000000 +0000 +++ gst-plugins-good0.10-0.10.31/debian/patches/flxdec-bounds2.patch 2016-11-22 13:56:48.000000000 +0000 @@ -0,0 +1,43 @@ +From af7f70e60e364b551c2589dee5fb458a83fa0e7e Mon Sep 17 00:00:00 2001 +From: Matthew Waters +Date: Tue, 22 Nov 2016 23:46:00 +1100 +Subject: flxdec: fix some warnings comparing unsigned < 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +bf43f44fcfada5ec4a3ce60cb374340486fe9fac was comparing an unsigned +expression to be < 0 which was always false. + +gstflxdec.c: In function ‘flx_decode_brun’: +gstflxdec.c:322:33: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] + if ((glong) row - count < 0) { + ^ +gstflxdec.c:332:33: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] + if ((glong) row - count < 0) { + ^ + +https://bugzilla.gnome.org/show_bug.cgi?id=774834 + +Index: gst-plugins-good0.10-0.10.31/gst/flx/gstflxdec.c +=================================================================== +--- gst-plugins-good0.10-0.10.31.orig/gst/flx/gstflxdec.c 2016-11-22 08:53:19.577997632 -0500 ++++ gst-plugins-good0.10-0.10.31/gst/flx/gstflxdec.c 2016-11-22 08:53:19.569997540 -0500 +@@ -341,7 +341,7 @@ + if (count > 0x7f) { + /* literal run */ + count = 0x100 - count; +- if ((glong) row - count < 0) { ++ if ((glong) row - (glong) count < 0) { + GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected."); + return FALSE; + } +@@ -351,7 +351,7 @@ + *dest++ = *data++; + + } else { +- if ((glong) row - count < 0) { ++ if ((glong) row - (glong) count < 0) { + GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected."); + return FALSE; + } diff -Nru gst-plugins-good0.10-0.10.31/debian/patches/series gst-plugins-good0.10-0.10.31/debian/patches/series --- gst-plugins-good0.10-0.10.31/debian/patches/series 2013-02-13 12:51:48.000000000 +0000 +++ gst-plugins-good0.10-0.10.31/debian/patches/series 2016-11-22 13:56:48.000000000 +0000 @@ -4,3 +4,5 @@ 99_ltmain_as-needed.patch git_ring_buffer_null_check.patch 0001-fix-v4l2_munmap.patch +flxdec-bounds1.patch +flxdec-bounds2.patch