From e44b511298590ecc87c2c85d1cbc043a638dd1e0 Mon Sep 17 00:00:00 2001 From: Danny Milosavljevic Date: Thu, 24 Nov 2016 21:58:40 +0100 Subject: gnu: ldc: Update to 0.17.2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gnu/packages/ldc.scm (ldc): Update to 0.17.2. * gnu/packages/patches/ldc-disable-tests.patch: Fix timezone file name. Signed-off-by: Ludovic Courtès --- gnu/packages/patches/ldc-disable-tests.patch | 50 ++++++++++------------------ 1 file changed, 17 insertions(+), 33 deletions(-) (limited to 'gnu/packages/patches') diff --git a/gnu/packages/patches/ldc-disable-tests.patch b/gnu/packages/patches/ldc-disable-tests.patch index 3f5e6c29a1..bdd6e5b76c 100644 --- a/gnu/packages/patches/ldc-disable-tests.patch +++ b/gnu/packages/patches/ldc-disable-tests.patch @@ -4,19 +4,9 @@ two others use networking. Not bad out of almost 700 tests! by Pjotr Prins -diff --git a/std/datetime.d b/std/datetime.d -index 8e4ed3b..6c15bc5 100644 ---- a/std/datetime.d -+++ b/std/datetime.d -@@ -28018,6 +28018,7 @@ public: - The default directory where the TZ Database files are. It's empty - for Windows, since Windows doesn't have them. - +/ -+ - enum defaultTZDatabaseDir = "/usr/share/zoneinfo/"; - } - else version(Windows) -@@ -28069,14 +28070,13 @@ assert(tz.dstName == "PDT"); +--- a/std/datetime.d.orig 2016-11-24 01:13:52.584495545 +0100 ++++ b/std/datetime.d 2016-11-24 01:17:09.655306728 +0100 +@@ -28081,22 +28081,24 @@ import std.range : retro; import std.format : format; @@ -25,9 +15,20 @@ index 8e4ed3b..6c15bc5 100644 enforce(tzDatabaseDir.exists(), new DateTimeException(format("Directory %s does not exist.", tzDatabaseDir))); enforce(tzDatabaseDir.isDir, new DateTimeException(format("%s is not a directory.", tzDatabaseDir))); -- immutable file = buildNormalizedPath(tzDatabaseDir, name); -+ auto filename = "./" ~ strip(name); // make sure the prefix is not stripped -+ immutable file = buildNormalizedPath(tzDatabaseDir, filename); + version(Android) + { ++ name = strip(name); + auto tzfileOffset = name in tzdataIndex(tzDatabaseDir); + enforce(tzfileOffset, new DateTimeException(format("The time zone %s is not listed.", name))); + string tzFilename = separate_index ? "zoneinfo.dat" : "tzdata"; + immutable file = buildNormalizedPath(tzDatabaseDir, tzFilename); + } + else +- immutable file = buildNormalizedPath(tzDatabaseDir, name); ++ { ++ auto filename = "./" ~ strip(name); // make sure the prefix is not stripped ++ immutable file = buildNormalizedPath(tzDatabaseDir, filename); ++ } - enforce(file.exists(), new DateTimeException(format("File %s does not exist.", file))); + enforce(file.exists(), new DateTimeException(format("File %s does not exist in %s.", file, tzDatabaseDir))); @@ -54,23 +55,6 @@ diff --git a/std/socket.d b/std/socket.d index b85d1c9..7fbf346 100644 --- a/std/socket.d +++ b/std/socket.d -@@ -517,6 +517,8 @@ class Protocol - - unittest - { -+ pragma(msg, "test disabled on GNU Guix"); -+/* - // getprotobyname,number are unimplemented on Android - softUnittest({ - Protocol proto = new Protocol; -@@ -530,6 +532,7 @@ unittest - assert(proto.name == "tcp"); - assert(proto.aliases.length == 1 && proto.aliases[0] == "TCP"); - }); -+*/ - } - - @@ -859,6 +862,8 @@ class InternetHost unittest -- cgit v1.2.3 From 9e46245b89e0f30397f69391a2219a29caa336a2 Mon Sep 17 00:00:00 2001 From: Leo Famulari Date: Fri, 25 Nov 2016 01:47:14 -0500 Subject: gnu: gst-plugins-good: Fix CVE-2016-{9634,9635,9636} and other security issues. * gnu/packages/patches/gst-plugins-good-fix-crashes.patch, gnu/packages/patches/gst-plugins-good-fix-invalid-read.patch, gnu/packages/patches/gst-plugins-good-fix-signedness.patch, gnu/packages/patches/gst-plugins-good-flic-bounds-check.patch: New files. * gnu/local.mk (dist_patch_DATA): Add them. * gnu/packages/gstreamer.scm (gst-plugins-good): Use them. --- gnu/local.mk | 4 + gnu/packages/gstreamer.scm | 5 + .../patches/gst-plugins-good-fix-crashes.patch | 1047 ++++++++++++++++++++ .../gst-plugins-good-fix-invalid-read.patch | 37 + .../patches/gst-plugins-good-fix-signedness.patch | 58 ++ .../gst-plugins-good-flic-bounds-check.patch | 319 ++++++ 6 files changed, 1470 insertions(+) create mode 100644 gnu/packages/patches/gst-plugins-good-fix-crashes.patch create mode 100644 gnu/packages/patches/gst-plugins-good-fix-invalid-read.patch create mode 100644 gnu/packages/patches/gst-plugins-good-fix-signedness.patch create mode 100644 gnu/packages/patches/gst-plugins-good-flic-bounds-check.patch (limited to 'gnu/packages/patches') diff --git a/gnu/local.mk b/gnu/local.mk index f3f8772337..8ca4d932d3 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -585,6 +585,10 @@ dist_patch_DATA = \ %D%/packages/patches/grub-gets-undeclared.patch \ %D%/packages/patches/grub-freetype.patch \ %D%/packages/patches/gsl-test-i686.patch \ + %D%/packages/patches/gst-plugins-good-fix-crashes.patch \ + %D%/packages/patches/gst-plugins-good-fix-invalid-read.patch \ + %D%/packages/patches/gst-plugins-good-fix-signedness.patch \ + %D%/packages/patches/gst-plugins-good-flic-bounds-check.patch \ %D%/packages/patches/guile-1.8-cpp-4.5.patch \ %D%/packages/patches/guile-arm-fixes.patch \ %D%/packages/patches/guile-default-utf8.patch \ diff --git a/gnu/packages/gstreamer.scm b/gnu/packages/gstreamer.scm index 5fe84ec2fc..86ea690e8b 100644 --- a/gnu/packages/gstreamer.scm +++ b/gnu/packages/gstreamer.scm @@ -4,6 +4,7 @@ ;;; Copyright © 2015, 2016 Sou Bunnbu ;;; Copyright © 2015 Mark H Weaver ;;; Copyright © 2016 Efraim Flashner +;;; Copyright © 2016 Leo Famulari ;;; ;;; This file is part of GNU Guix. ;;; @@ -207,6 +208,10 @@ (define-public gst-plugins-good (uri (string-append "https://gstreamer.freedesktop.org/src/" name "/" name "-" version ".tar.xz")) + (patches (search-patches "gst-plugins-good-flic-bounds-check.patch" + "gst-plugins-good-fix-signedness.patch" + "gst-plugins-good-fix-invalid-read.patch" + "gst-plugins-good-fix-crashes.patch")) (sha256 (base32 "1hkcap9l2603266gyi6jgvx7frbvfmb7xhfhjizbczy1wykjwr57")))) diff --git a/gnu/packages/patches/gst-plugins-good-fix-crashes.patch b/gnu/packages/patches/gst-plugins-good-fix-crashes.patch new file mode 100644 index 0000000000..c36a595608 --- /dev/null +++ b/gnu/packages/patches/gst-plugins-good-fix-crashes.patch @@ -0,0 +1,1047 @@ +Fixes upstream bug #774859 (flic decoder: Invalid memory read in +flx_decode_chunks): + +https://bugzilla.gnome.org/show_bug.cgi?id=774859 + +Patch copied from upstream source repository: + +https://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=be670f0daf67304fb92c76aa09c30cae0bfd1fe4 + +From be670f0daf67304fb92c76aa09c30cae0bfd1fe4 Mon Sep 17 00:00:00 2001 +From: Matthew Waters +Date: Wed, 23 Nov 2016 07:09:06 +1100 +Subject: [PATCH] flxdec: rewrite logic based on GstByteReader/Writer + +Solves overreading/writing the given arrays and will error out if the +streams asks to do that. + +Also does more error checking that the stream is valid and won't +overrun any allocated arrays. Also mitigate integer overflow errors +calculating allocation sizes. + +https://bugzilla.gnome.org/show_bug.cgi?id=774859 +--- + gst/flx/flx_color.c | 1 - + gst/flx/flx_fmt.h | 72 ------- + gst/flx/gstflxdec.c | 610 ++++++++++++++++++++++++++++++++++++---------------- + gst/flx/gstflxdec.h | 4 +- + 4 files changed, 427 insertions(+), 260 deletions(-) + +diff --git a/gst/flx/flx_color.c b/gst/flx/flx_color.c +index 047bfdf..3a58135 100644 +--- a/gst/flx/flx_color.c ++++ b/gst/flx/flx_color.c +@@ -101,7 +101,6 @@ flx_set_palette_vector (FlxColorSpaceConverter * flxpal, guint start, guint num, + } else { + memcpy (&flxpal->palvec[start * 3], newpal, grab * 3); + } +- + } + + void +diff --git a/gst/flx/flx_fmt.h b/gst/flx/flx_fmt.h +index 9ab31ba..abff200 100644 +--- a/gst/flx/flx_fmt.h ++++ b/gst/flx/flx_fmt.h +@@ -123,78 +123,6 @@ typedef struct _FlxFrameType + } FlxFrameType; + #define FlxFrameTypeSize 10 + +-#if G_BYTE_ORDER == G_BIG_ENDIAN +-#define LE_TO_BE_16(i16) ((guint16) (((i16) << 8) | ((i16) >> 8))) +-#define LE_TO_BE_32(i32) \ +- (((guint32) (LE_TO_BE_16((guint16) (i32))) << 16) | (LE_TO_BE_16((i32) >> 16))) +- +-#define FLX_FRAME_TYPE_FIX_ENDIANNESS(frm_type_p) \ +- do { \ +- (frm_type_p)->chunks = LE_TO_BE_16((frm_type_p)->chunks); \ +- (frm_type_p)->delay = LE_TO_BE_16((frm_type_p)->delay); \ +- } while(0) +- +-#define FLX_HUFFMAN_TABLE_FIX_ENDIANNESS(hffmn_table_p) \ +- do { \ +- (hffmn_table_p)->codelength = \ +- LE_TO_BE_16((hffmn_table_p)->codelength); \ +- (hffmn_table_p)->numcodes = LE_TO_BE_16((hffmn_table_p)->numcodes); \ +- } while(0) +- +-#define FLX_SEGMENT_TABLE_FIX_ENDIANNESS(sgmnt_table_p) \ +- ((sgmnt_table_p)->segments = LE_TO_BE_16((sgmnt_table_p)->segments)) +- +-#define FLX_PREFIX_CHUNK_FIX_ENDIANNESS(prfx_chnk_p) \ +- do { \ +- (prfx_chnk_p)->chunks = LE_TO_BE_16((prfx_chnk_p)->chunks); \ +- } while(0) +- +-#define FLX_FRAME_CHUNK_FIX_ENDIANNESS(frm_chnk_p) \ +- do { \ +- (frm_chnk_p)->size = LE_TO_BE_32((frm_chnk_p)->size); \ +- (frm_chnk_p)->id = LE_TO_BE_16((frm_chnk_p)->id); \ +- } while(0) +- +-#define FLX_HDR_FIX_ENDIANNESS(hdr_p) \ +- do { \ +- (hdr_p)->size = LE_TO_BE_32((hdr_p)->size); \ +- (hdr_p)->type = LE_TO_BE_16((hdr_p)->type); \ +- (hdr_p)->frames = LE_TO_BE_16((hdr_p)->frames); \ +- (hdr_p)->width = LE_TO_BE_16((hdr_p)->width); \ +- (hdr_p)->height = LE_TO_BE_16((hdr_p)->height); \ +- (hdr_p)->depth = LE_TO_BE_16((hdr_p)->depth); \ +- (hdr_p)->flags = LE_TO_BE_16((hdr_p)->flags); \ +- (hdr_p)->speed = LE_TO_BE_32((hdr_p)->speed); \ +- (hdr_p)->reserved1 = LE_TO_BE_16((hdr_p)->reserved1); \ +- (hdr_p)->created = LE_TO_BE_32((hdr_p)->created); \ +- (hdr_p)->creator = LE_TO_BE_32((hdr_p)->creator); \ +- (hdr_p)->updated = LE_TO_BE_32((hdr_p)->updated); \ +- (hdr_p)->updater = LE_TO_BE_32((hdr_p)->updater); \ +- (hdr_p)->aspect_dx = LE_TO_BE_16((hdr_p)->aspect_dx); \ +- (hdr_p)->aspect_dy = LE_TO_BE_16((hdr_p)->aspect_dy); \ +- (hdr_p)->ext_flags = LE_TO_BE_16((hdr_p)->ext_flags); \ +- (hdr_p)->keyframes = LE_TO_BE_16((hdr_p)->keyframes); \ +- (hdr_p)->totalframes = LE_TO_BE_16((hdr_p)->totalframes); \ +- (hdr_p)->req_memory = LE_TO_BE_32((hdr_p)->req_memory); \ +- (hdr_p)->max_regions = LE_TO_BE_16((hdr_p)->max_regions); \ +- (hdr_p)->transp_num = LE_TO_BE_16((hdr_p)->transp_num); \ +- (hdr_p)->oframe1 = LE_TO_BE_32((hdr_p)->oframe1); \ +- (hdr_p)->oframe2 = LE_TO_BE_32((hdr_p)->oframe2); \ +- } while(0) +-#else +- +-#define LE_TO_BE_16(i16) ((i16)) +-#define LE_TO_BE_32(i32) ((i32)) +- +-#define FLX_FRAME_TYPE_FIX_ENDIANNESS(frm_type_p) +-#define FLX_HUFFMAN_TABLE_FIX_ENDIANNESS(hffmn_table_p) +-#define FLX_SEGMENT_TABLE_FIX_ENDIANNESS(sgmnt_table_p) +-#define FLX_PREFIX_CHUNK_FIX_ENDIANNESS(prfx_chnk_p) +-#define FLX_FRAME_CHUNK_FIX_ENDIANNESS(frm_chnk_p) +-#define FLX_HDR_FIX_ENDIANNESS(hdr_p) +- +-#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */ +- + G_END_DECLS + + #endif /* __GST_FLX_FMT_H__ */ +diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c +index a237976..aa1bed5 100644 +--- a/gst/flx/gstflxdec.c ++++ b/gst/flx/gstflxdec.c +@@ -1,5 +1,6 @@ + /* GStreamer + * Copyright (C) <1999> Erik Walthinsen ++ * Copyright (C) <2016> Matthew Waters + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public +@@ -24,6 +25,7 @@ + /* + * http://www.coolutils.com/Formats/FLI + * http://woodshole.er.usgs.gov/operations/modeling/flc.html ++ * http://www.compuphase.com/flic.htm + */ + + #ifdef HAVE_CONFIG_H +@@ -73,10 +75,14 @@ static GstStateChangeReturn gst_flxdec_change_state (GstElement * element, + static gboolean gst_flxdec_src_query_handler (GstPad * pad, GstObject * parent, + GstQuery * query); + +-static void flx_decode_color (GstFlxDec *, guchar *, guchar *, gint); +-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 *); ++static gboolean flx_decode_color (GstFlxDec * flxdec, GstByteReader * reader, ++ GstByteWriter * writer, gint scale); ++static gboolean flx_decode_brun (GstFlxDec * flxdec, ++ GstByteReader * reader, GstByteWriter * writer); ++static gboolean flx_decode_delta_fli (GstFlxDec * flxdec, ++ GstByteReader * reader, GstByteWriter * writer); ++static gboolean flx_decode_delta_flc (GstFlxDec * flxdec, ++ GstByteReader * reader, GstByteWriter * writer); + + #define rndalign(off) ((off) + ((off) & 1)) + +@@ -204,57 +210,59 @@ gst_flxdec_sink_event_handler (GstPad * pad, GstObject * parent, + } + + static gboolean +-flx_decode_chunks (GstFlxDec * flxdec, gulong count, guchar * data, +- guchar * dest) ++flx_decode_chunks (GstFlxDec * flxdec, gulong n_chunks, GstByteReader * reader, ++ GstByteWriter * writer) + { +- FlxFrameChunk *hdr; + gboolean ret = TRUE; + +- g_return_val_if_fail (data != NULL, FALSE); +- +- while (count--) { +- hdr = (FlxFrameChunk *) data; +- FLX_FRAME_CHUNK_FIX_ENDIANNESS (hdr); +- data += FlxFrameChunkSize; ++ while (n_chunks--) { ++ GstByteReader chunk; ++ guint32 size; ++ guint16 type; ++ ++ if (!gst_byte_reader_get_uint32_le (reader, &size)) ++ goto parse_error; ++ if (!gst_byte_reader_get_uint16_le (reader, &type)) ++ goto parse_error; ++ GST_LOG_OBJECT (flxdec, "chunk has type 0x%02x size %d", type, size); ++ ++ if (!gst_byte_reader_get_sub_reader (reader, &chunk, ++ size - FlxFrameChunkSize)) { ++ GST_ERROR_OBJECT (flxdec, "Incorrect size in the chunk header"); ++ goto error; ++ } + +- switch (hdr->id) { ++ switch (type) { + case FLX_COLOR64: +- flx_decode_color (flxdec, data, dest, 2); +- data += rndalign (hdr->size) - FlxFrameChunkSize; ++ ret = flx_decode_color (flxdec, &chunk, writer, 2); + break; + + case FLX_COLOR256: +- flx_decode_color (flxdec, data, dest, 0); +- data += rndalign (hdr->size) - FlxFrameChunkSize; ++ ret = flx_decode_color (flxdec, &chunk, writer, 0); + break; + + case FLX_BRUN: +- ret = flx_decode_brun (flxdec, data, dest); +- data += rndalign (hdr->size) - FlxFrameChunkSize; ++ ret = flx_decode_brun (flxdec, &chunk, writer); + break; + + case FLX_LC: +- ret = flx_decode_delta_fli (flxdec, data, dest); +- data += rndalign (hdr->size) - FlxFrameChunkSize; ++ ret = flx_decode_delta_fli (flxdec, &chunk, writer); + break; + + case FLX_SS2: +- ret = flx_decode_delta_flc (flxdec, data, dest); +- data += rndalign (hdr->size) - FlxFrameChunkSize; ++ ret = flx_decode_delta_flc (flxdec, &chunk, writer); + break; + + case FLX_BLACK: +- memset (dest, 0, flxdec->size); ++ ret = gst_byte_writer_fill (writer, 0, flxdec->size); + break; + + case FLX_MINI: +- data += rndalign (hdr->size) - FlxFrameChunkSize; + break; + + default: +- GST_WARNING ("Unimplented chunk type: 0x%02x size: %d - skipping", +- hdr->id, hdr->size); +- data += rndalign (hdr->size) - FlxFrameChunkSize; ++ GST_WARNING ("Unimplemented chunk type: 0x%02x size: %d - skipping", ++ type, size); + break; + } + +@@ -263,43 +271,60 @@ flx_decode_chunks (GstFlxDec * flxdec, gulong count, guchar * data, + } + + return ret; ++ ++parse_error: ++ GST_ERROR_OBJECT (flxdec, "Failed to decode chunk"); ++error: ++ return FALSE; + } + + +-static void +-flx_decode_color (GstFlxDec * flxdec, guchar * data, guchar * dest, gint scale) ++static gboolean ++flx_decode_color (GstFlxDec * flxdec, GstByteReader * reader, ++ GstByteWriter * writer, gint scale) + { +- guint packs, count, indx; ++ guint8 count, indx; ++ guint16 packs; + +- g_return_if_fail (flxdec != NULL); +- +- packs = (data[0] + (data[1] << 8)); +- +- data += 2; ++ if (!gst_byte_reader_get_uint16_le (reader, &packs)) ++ goto error; + indx = 0; + +- GST_LOG ("GstFlxDec: cmap packs: %d", packs); ++ GST_LOG ("GstFlxDec: cmap packs: %d", (guint) packs); + while (packs--) { ++ const guint8 *data; ++ guint16 actual_count; ++ + /* color map index + skip count */ +- indx += *data++; ++ if (!gst_byte_reader_get_uint8 (reader, &indx)) ++ goto error; + + /* number of rgb triplets */ +- count = *data++ & 0xff; +- if (count == 0) +- count = 256; ++ if (!gst_byte_reader_get_uint8 (reader, &count)) ++ goto error; + +- GST_LOG ("GstFlxDec: cmap count: %d (indx: %d)", count, indx); +- flx_set_palette_vector (flxdec->converter, indx, count, data, scale); ++ actual_count = count == 0 ? 256 : count; + +- data += (count * 3); ++ if (!gst_byte_reader_get_data (reader, count * 3, &data)) ++ goto error; ++ ++ GST_LOG_OBJECT (flxdec, "cmap count: %d (indx: %d)", actual_count, indx); ++ flx_set_palette_vector (flxdec->converter, indx, actual_count, ++ (guchar *) data, scale); + } ++ ++ return TRUE; ++ ++error: ++ GST_ERROR_OBJECT (flxdec, "Error decoding color palette"); ++ return FALSE; + } + + static gboolean +-flx_decode_brun (GstFlxDec * flxdec, guchar * data, guchar * dest) ++flx_decode_brun (GstFlxDec * flxdec, GstByteReader * reader, ++ GstByteWriter * writer) + { +- gulong count, lines, row; +- guchar x; ++ gulong lines, row; + + g_return_val_if_fail (flxdec != NULL, FALSE); + +@@ -310,82 +335,125 @@ flx_decode_brun (GstFlxDec * flxdec, guchar * data, guchar * dest) + * contain more then 255 RLE packets. we use the frame + * width instead. + */ +- data++; ++ if (!gst_byte_reader_skip (reader, 1)) ++ goto error; + + row = flxdec->hdr.width; + while (row) { +- count = *data++; ++ gint8 count; ++ ++ if (!gst_byte_reader_get_int8 (reader, &count)) ++ goto error; ++ ++ if (count <= 0) { ++ const guint8 *data; + +- if (count > 0x7f) { + /* literal run */ +- count = 0x100 - count; +- if ((glong) row - (glong) count < 0) { +- GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected."); ++ count = ABS (count); ++ ++ GST_LOG_OBJECT (flxdec, "have literal run of size %d", count); ++ ++ if (count > row) { ++ GST_ERROR_OBJECT (flxdec, "Invalid BRUN line detected. " ++ "bytes to write exceeds the end of the row"); + return FALSE; + } + row -= count; + +- while (count--) +- *dest++ = *data++; +- ++ if (!gst_byte_reader_get_data (reader, count, &data)) ++ goto error; ++ if (!gst_byte_writer_put_data (writer, data, count)) ++ goto error; + } else { +- if ((glong) row - (glong) count < 0) { +- GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected."); ++ guint8 x; ++ ++ GST_LOG_OBJECT (flxdec, "have replicate run of size %d", count); ++ ++ if (count > row) { ++ GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected." ++ "bytes to write exceeds the end of the row"); + return FALSE; + } + + /* replicate run */ + row -= count; +- x = *data++; + +- while (count--) +- *dest++ = x; ++ if (!gst_byte_reader_get_uint8 (reader, &x)) ++ goto error; ++ if (!gst_byte_writer_fill (writer, x, count)) ++ goto error; + } + } + } + + return TRUE; ++ ++error: ++ GST_ERROR_OBJECT (flxdec, "Failed to decode BRUN packet"); ++ return FALSE; + } + + static gboolean +-flx_decode_delta_fli (GstFlxDec * flxdec, guchar * data, guchar * dest) ++flx_decode_delta_fli (GstFlxDec * flxdec, GstByteReader * reader, ++ GstByteWriter * writer) + { +- gulong count, packets, lines, start_line; +- guchar *start_p, x; ++ guint16 start_line, lines; ++ guint line_start_i; + + g_return_val_if_fail (flxdec != NULL, FALSE); + g_return_val_if_fail (flxdec->delta_data != NULL, FALSE); + + /* use last frame for delta */ +- memcpy (dest, flxdec->delta_data, flxdec->size); ++ if (!gst_byte_writer_put_data (writer, flxdec->delta_data, flxdec->size)) ++ goto error; ++ ++ if (!gst_byte_reader_get_uint16_le (reader, &start_line)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &lines)) ++ goto error; ++ GST_LOG_OBJECT (flxdec, "height %d start line %d line count %d", ++ flxdec->hdr.height, start_line, lines); + +- 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 */ +- dest += (flxdec->hdr.width * start_line); +- start_p = dest; ++ line_start_i = flxdec->hdr.width * start_line; ++ if (!gst_byte_writer_set_pos (writer, line_start_i)) ++ goto error; + + while (lines--) { ++ guint8 packets; ++ + /* packet count */ +- packets = *data++; ++ if (!gst_byte_reader_get_uint8 (reader, &packets)) ++ goto error; ++ GST_LOG_OBJECT (flxdec, "have %d packets", packets); + + while (packets--) { + /* skip count */ +- guchar skip = *data++; +- dest += skip; ++ guint8 skip; ++ gint8 count; ++ if (!gst_byte_reader_get_uint8 (reader, &skip)) ++ goto error; ++ ++ /* skip bytes */ ++ if (!gst_byte_writer_set_pos (writer, ++ gst_byte_writer_get_pos (writer) + skip)) ++ goto error; + + /* RLE count */ +- count = *data++; ++ if (!gst_byte_reader_get_int8 (reader, &count)) ++ goto error; ++ ++ if (count < 0) { ++ guint8 x; + +- if (count > 0x7f) { + /* literal run */ +- count = 0x100 - count; ++ count = ABS (count); ++ GST_LOG_OBJECT (flxdec, "have literal run of size %d at offset %d", ++ count, skip); + + if (skip + count > flxdec->hdr.width) { + GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. " +@@ -393,11 +461,16 @@ flx_decode_delta_fli (GstFlxDec * flxdec, guchar * data, guchar * dest) + return FALSE; + } + +- x = *data++; +- while (count--) +- *dest++ = x; +- ++ if (!gst_byte_reader_get_uint8 (reader, &x)) ++ goto error; ++ if (!gst_byte_writer_fill (writer, x, count)) ++ goto error; + } else { ++ const guint8 *data; ++ ++ GST_LOG_OBJECT (flxdec, "have replicate run of size %d at offset %d", ++ count, skip); ++ + if (skip + count > flxdec->hdr.width) { + GST_ERROR_OBJECT (flxdec, "Invalid FLI packet detected. " + "line too long."); +@@ -405,45 +478,60 @@ flx_decode_delta_fli (GstFlxDec * flxdec, guchar * data, guchar * dest) + } + + /* replicate run */ +- while (count--) +- *dest++ = *data++; ++ if (!gst_byte_reader_get_data (reader, count, &data)) ++ goto error; ++ if (!gst_byte_writer_put_data (writer, data, count)) ++ goto error; + } + } +- start_p += flxdec->hdr.width; +- dest = start_p; ++ line_start_i += flxdec->hdr.width; ++ if (!gst_byte_writer_set_pos (writer, line_start_i)) ++ goto error; + } + + return TRUE; ++ ++error: ++ GST_ERROR_OBJECT (flxdec, "Failed to decode FLI packet"); ++ return FALSE; + } + + static gboolean +-flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) ++flx_decode_delta_flc (GstFlxDec * flxdec, GstByteReader * reader, ++ GstByteWriter * writer) + { +- gulong count, lines, start_l, opcode; +- guchar *start_p; ++ guint16 lines, start_l; + + g_return_val_if_fail (flxdec != NULL, FALSE); + g_return_val_if_fail (flxdec->delta_data != NULL, FALSE); + + /* use last frame for delta */ +- memcpy (dest, flxdec->delta_data, flxdec->size); ++ if (!gst_byte_writer_put_data (writer, flxdec->delta_data, flxdec->size)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &lines)) ++ goto error; + +- 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; + start_l = lines; + + while (lines) { +- dest = start_p + (flxdec->hdr.width * (start_l - lines)); ++ guint16 opcode; ++ ++ if (!gst_byte_writer_set_pos (writer, ++ flxdec->hdr.width * (start_l - lines))) ++ goto error; + + /* process opcode(s) */ +- while ((opcode = (data[0] + (data[1] << 8))) & 0xc000) { +- data += 2; ++ while (TRUE) { ++ if (!gst_byte_reader_get_uint16_le (reader, &opcode)) ++ goto error; ++ if ((opcode & 0xc000) == 0) ++ break; ++ + if ((opcode & 0xc000) == 0xc000) { + /* line skip count */ + gulong skip = (0x10000 - opcode); +@@ -453,27 +541,44 @@ flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) + return FALSE; + } + start_l += skip; +- dest += flxdec->hdr.width * skip; ++ if (!gst_byte_writer_set_pos (writer, ++ gst_byte_writer_get_pos (writer) + flxdec->hdr.width * skip)) ++ goto error; + } else { + /* last pixel */ +- dest += flxdec->hdr.width; +- *dest++ = (opcode & 0xff); ++ if (!gst_byte_writer_set_pos (writer, ++ gst_byte_writer_get_pos (writer) + flxdec->hdr.width)) ++ goto error; ++ if (!gst_byte_writer_put_uint8 (writer, opcode & 0xff)) ++ goto error; + } + } +- data += 2; + + /* last opcode is the packet count */ ++ GST_LOG_OBJECT (flxdec, "have %d packets", opcode); + while (opcode--) { + /* skip count */ +- guchar skip = *data++; +- dest += skip; ++ guint8 skip; ++ gint8 count; ++ ++ if (!gst_byte_reader_get_uint8 (reader, &skip)) ++ goto error; ++ if (!gst_byte_writer_set_pos (writer, ++ gst_byte_writer_get_pos (writer) + skip)) ++ goto error; + + /* RLE count */ +- count = *data++; ++ if (!gst_byte_reader_get_int8 (reader, &count)) ++ goto error; ++ ++ if (count < 0) { ++ guint16 x; + +- if (count > 0x7f) { + /* replicate word run */ +- count = 0x100 - count; ++ count = ABS (count); ++ ++ GST_LOG_OBJECT (flxdec, "have replicate run of size %d at offset %d", ++ count, skip); + + if (skip + count > flxdec->hdr.width) { + GST_ERROR_OBJECT (flxdec, "Invalid FLC packet detected. " +@@ -481,22 +586,31 @@ flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) + return FALSE; + } + ++ if (!gst_byte_reader_get_uint16_le (reader, &x)) ++ goto error; ++ + while (count--) { +- *dest++ = data[0]; +- *dest++ = data[1]; ++ if (!gst_byte_writer_put_uint16_le (writer, x)) { ++ goto error; ++ } + } +- data += 2; + } else { ++ GST_LOG_OBJECT (flxdec, "have literal run of size %d at offset %d", ++ count, skip); ++ + 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++; +- *dest++ = *data++; ++ guint16 x; ++ ++ if (!gst_byte_reader_get_uint16_le (reader, &x)) ++ goto error; ++ if (!gst_byte_writer_put_uint16_le (writer, x)) ++ goto error; + } + } + } +@@ -504,13 +618,91 @@ flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) + } + + return TRUE; ++ ++error: ++ GST_ERROR_OBJECT (flxdec, "Failed to decode FLI packet"); ++ return FALSE; ++} ++ ++static gboolean ++_read_flx_header (GstFlxDec * flxdec, GstByteReader * reader, FlxHeader * flxh) ++{ ++ memset (flxh, 0, sizeof (*flxh)); ++ ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->size)) ++ goto error; ++ if (flxh->size < FlxHeaderSize) { ++ GST_ERROR_OBJECT (flxdec, "Invalid file size in the header"); ++ return FALSE; ++ } ++ ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->type)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->frames)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->width)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->height)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->depth)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->flags)) ++ goto error; ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->speed)) ++ goto error; ++ if (!gst_byte_reader_skip (reader, 2)) /* reserved */ ++ goto error; ++ /* FLC */ ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->created)) ++ goto error; ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->creator)) ++ goto error; ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->updated)) ++ goto error; ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->updater)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->aspect_dx)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->aspect_dy)) ++ goto error; ++ /* EGI */ ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->ext_flags)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->keyframes)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->totalframes)) ++ goto error; ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->req_memory)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->max_regions)) ++ goto error; ++ if (!gst_byte_reader_get_uint16_le (reader, &flxh->transp_num)) ++ goto error; ++ if (!gst_byte_reader_skip (reader, 24)) /* reserved */ ++ goto error; ++ /* FLC */ ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->oframe1)) ++ goto error; ++ if (!gst_byte_reader_get_uint32_le (reader, &flxh->oframe2)) ++ goto error; ++ if (!gst_byte_reader_skip (reader, 40)) /* reserved */ ++ goto error; ++ ++ return TRUE; ++ ++error: ++ GST_ERROR_OBJECT (flxdec, "Error reading file header"); ++ return FALSE; + } + + static GstFlowReturn + gst_flxdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + { ++ GstByteReader reader; ++ GstBuffer *input; ++ GstMapInfo map_info; + GstCaps *caps; +- guint avail; ++ guint available; + GstFlowReturn res = GST_FLOW_OK; + + GstFlxDec *flxdec; +@@ -521,31 +713,50 @@ gst_flxdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + g_return_val_if_fail (flxdec != NULL, GST_FLOW_ERROR); + + gst_adapter_push (flxdec->adapter, buf); +- avail = gst_adapter_available (flxdec->adapter); ++ available = gst_adapter_available (flxdec->adapter); ++ input = gst_adapter_get_buffer (flxdec->adapter, available); ++ if (!gst_buffer_map (input, &map_info, GST_MAP_READ)) { ++ GST_ELEMENT_ERROR (flxdec, STREAM, DECODE, ++ ("%s", "Failed to map buffer"), (NULL)); ++ goto error; ++ } ++ gst_byte_reader_init (&reader, map_info.data, map_info.size); + + if (flxdec->state == GST_FLXDEC_READ_HEADER) { +- if (avail >= FlxHeaderSize) { +- const guint8 *data = gst_adapter_map (flxdec->adapter, FlxHeaderSize); ++ if (available >= FlxHeaderSize) { ++ GstByteReader header; + GstCaps *templ; + +- memcpy ((gchar *) & flxdec->hdr, data, FlxHeaderSize); +- FLX_HDR_FIX_ENDIANNESS (&(flxdec->hdr)); +- gst_adapter_unmap (flxdec->adapter); ++ if (!gst_byte_reader_get_sub_reader (&reader, &header, FlxHeaderSize)) { ++ GST_ELEMENT_ERROR (flxdec, STREAM, DECODE, ++ ("%s", "Could not read header"), (NULL)); ++ goto unmap_input_error; ++ } + gst_adapter_flush (flxdec->adapter, FlxHeaderSize); ++ available -= FlxHeaderSize; ++ ++ if (!_read_flx_header (flxdec, &header, &flxdec->hdr)) { ++ GST_ELEMENT_ERROR (flxdec, STREAM, DECODE, ++ ("%s", "Failed to parse header"), (NULL)); ++ goto unmap_input_error; ++ } + + flxh = &flxdec->hdr; + + /* check header */ + if (flxh->type != FLX_MAGICHDR_FLI && +- flxh->type != FLX_MAGICHDR_FLC && flxh->type != FLX_MAGICHDR_FLX) +- goto wrong_type; ++ flxh->type != FLX_MAGICHDR_FLC && flxh->type != FLX_MAGICHDR_FLX) { ++ GST_ELEMENT_ERROR (flxdec, STREAM, WRONG_TYPE, (NULL), ++ ("not a flx file (type %x)", flxh->type)); ++ goto unmap_input_error; ++ } + +- GST_LOG ("size : %d", flxh->size); +- GST_LOG ("frames : %d", flxh->frames); +- GST_LOG ("width : %d", flxh->width); +- GST_LOG ("height : %d", flxh->height); +- GST_LOG ("depth : %d", flxh->depth); +- GST_LOG ("speed : %d", flxh->speed); ++ GST_INFO_OBJECT (flxdec, "size : %d", flxh->size); ++ GST_INFO_OBJECT (flxdec, "frames : %d", flxh->frames); ++ GST_INFO_OBJECT (flxdec, "width : %d", flxh->width); ++ GST_INFO_OBJECT (flxdec, "height : %d", flxh->height); ++ GST_INFO_OBJECT (flxdec, "depth : %d", flxh->depth); ++ GST_INFO_OBJECT (flxdec, "speed : %d", flxh->speed); + + flxdec->next_time = 0; + +@@ -573,18 +784,32 @@ gst_flxdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + gst_pad_set_caps (flxdec->srcpad, caps); + gst_caps_unref (caps); + +- if (flxh->depth <= 8) +- flxdec->converter = +- flx_colorspace_converter_new (flxh->width, flxh->height); ++ /* zero means 8 */ ++ if (flxh->depth == 0) ++ flxh->depth = 8; ++ ++ if (flxh->depth != 8) { ++ GST_ELEMENT_ERROR (flxdec, STREAM, WRONG_TYPE, ++ ("%s", "Don't know how to decode non 8 bit depth streams"), (NULL)); ++ goto unmap_input_error; ++ } ++ ++ flxdec->converter = ++ flx_colorspace_converter_new (flxh->width, flxh->height); + + if (flxh->type == FLX_MAGICHDR_FLC || flxh->type == FLX_MAGICHDR_FLX) { +- GST_LOG ("(FLC) aspect_dx : %d", flxh->aspect_dx); +- GST_LOG ("(FLC) aspect_dy : %d", flxh->aspect_dy); +- GST_LOG ("(FLC) oframe1 : 0x%08x", flxh->oframe1); +- GST_LOG ("(FLC) oframe2 : 0x%08x", flxh->oframe2); ++ GST_INFO_OBJECT (flxdec, "(FLC) aspect_dx : %d", flxh->aspect_dx); ++ GST_INFO_OBJECT (flxdec, "(FLC) aspect_dy : %d", flxh->aspect_dy); ++ GST_INFO_OBJECT (flxdec, "(FLC) oframe1 : 0x%08x", flxh->oframe1); ++ GST_INFO_OBJECT (flxdec, "(FLC) oframe2 : 0x%08x", flxh->oframe2); + } + + flxdec->size = ((guint) flxh->width * (guint) flxh->height); ++ if (flxdec->size >= G_MAXSIZE / 4) { ++ GST_ELEMENT_ERROR (flxdec, STREAM, DECODE, ++ ("%s", "Cannot allocate required memory"), (NULL)); ++ goto unmap_input_error; ++ } + + /* create delta and output frame */ + flxdec->frame_data = g_malloc (flxdec->size); +@@ -596,55 +821,66 @@ gst_flxdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + GstBuffer *out; + + /* while we have enough data in the adapter */ +- while (avail >= FlxFrameChunkSize && res == GST_FLOW_OK) { +- FlxFrameChunk flxfh; +- guchar *chunk; +- const guint8 *data; +- GstMapInfo map; +- +- chunk = NULL; +- data = gst_adapter_map (flxdec->adapter, FlxFrameChunkSize); +- memcpy (&flxfh, data, FlxFrameChunkSize); +- FLX_FRAME_CHUNK_FIX_ENDIANNESS (&flxfh); +- gst_adapter_unmap (flxdec->adapter); +- +- switch (flxfh.id) { +- case FLX_FRAME_TYPE: +- /* check if we have the complete frame */ +- if (avail < flxfh.size) +- goto need_more_data; +- +- /* flush header */ +- gst_adapter_flush (flxdec->adapter, FlxFrameChunkSize); +- +- chunk = gst_adapter_take (flxdec->adapter, +- flxfh.size - FlxFrameChunkSize); +- FLX_FRAME_TYPE_FIX_ENDIANNESS ((FlxFrameType *) chunk); +- if (((FlxFrameType *) chunk)->chunks == 0) +- break; ++ while (available >= FlxFrameChunkSize && res == GST_FLOW_OK) { ++ guint32 size; ++ guint16 type; + +- /* create 32 bits output frame */ +-// res = gst_pad_alloc_buffer_and_set_caps (flxdec->srcpad, +-// GST_BUFFER_OFFSET_NONE, +-// flxdec->size * 4, GST_PAD_CAPS (flxdec->srcpad), &out); +-// if (res != GST_FLOW_OK) +-// break; ++ if (!gst_byte_reader_get_uint32_le (&reader, &size)) ++ goto parse_error; ++ if (available < size) ++ goto need_more_data; + +- out = gst_buffer_new_and_alloc (flxdec->size * 4); ++ available -= size; ++ gst_adapter_flush (flxdec->adapter, size); ++ ++ if (!gst_byte_reader_get_uint16_le (&reader, &type)) ++ goto parse_error; ++ ++ switch (type) { ++ case FLX_FRAME_TYPE:{ ++ GstByteReader chunks; ++ GstByteWriter writer; ++ guint16 n_chunks; ++ GstMapInfo map; ++ ++ GST_LOG_OBJECT (flxdec, "Have frame type 0x%02x of size %d", type, ++ size); ++ ++ if (!gst_byte_reader_get_sub_reader (&reader, &chunks, ++ size - FlxFrameChunkSize)) ++ goto parse_error; ++ ++ if (!gst_byte_reader_get_uint16_le (&chunks, &n_chunks)) ++ goto parse_error; ++ GST_LOG_OBJECT (flxdec, "Have %d chunks", n_chunks); ++ ++ if (n_chunks == 0) ++ break; ++ if (!gst_byte_reader_skip (&chunks, 8)) /* reserved */ ++ goto parse_error; ++ ++ gst_byte_writer_init_with_data (&writer, flxdec->frame_data, ++ flxdec->size, TRUE); + + /* decode chunks */ +- if (!flx_decode_chunks (flxdec, +- ((FlxFrameType *) chunk)->chunks, +- chunk + FlxFrameTypeSize, flxdec->frame_data)) { ++ if (!flx_decode_chunks (flxdec, n_chunks, &chunks, &writer)) { + GST_ELEMENT_ERROR (flxdec, STREAM, DECODE, + ("%s", "Could not decode chunk"), NULL); +- return GST_FLOW_ERROR; ++ goto unmap_input_error; + } ++ gst_byte_writer_reset (&writer); + + /* save copy of the current frame for possible delta. */ + memcpy (flxdec->delta_data, flxdec->frame_data, flxdec->size); + +- gst_buffer_map (out, &map, GST_MAP_WRITE); ++ out = gst_buffer_new_and_alloc (flxdec->size * 4); ++ if (!gst_buffer_map (out, &map, GST_MAP_WRITE)) { ++ GST_ELEMENT_ERROR (flxdec, STREAM, DECODE, ++ ("%s", "Could not map output buffer"), NULL); ++ gst_buffer_unref (out); ++ goto unmap_input_error; ++ } ++ + /* convert current frame. */ + flx_colorspace_convert (flxdec->converter, flxdec->frame_data, + map.data); +@@ -655,30 +891,32 @@ gst_flxdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + + res = gst_pad_push (flxdec->srcpad, out); + break; ++ } + default: +- /* check if we have the complete frame */ +- if (avail < flxfh.size) +- goto need_more_data; +- +- gst_adapter_flush (flxdec->adapter, flxfh.size); ++ GST_DEBUG_OBJECT (flxdec, "Unknown frame type 0x%02x, skipping %d", ++ type, size); ++ if (!gst_byte_reader_skip (&reader, size - FlxFrameChunkSize)) ++ goto parse_error; + break; + } +- +- g_free (chunk); +- +- avail = gst_adapter_available (flxdec->adapter); + } + } ++ ++ gst_buffer_unmap (input, &map_info); ++ gst_buffer_unref (input); ++ + need_more_data: + return res; + + /* ERRORS */ +-wrong_type: +- { +- GST_ELEMENT_ERROR (flxdec, STREAM, WRONG_TYPE, (NULL), +- ("not a flx file (type %x)", flxh->type)); +- return GST_FLOW_ERROR; +- } ++parse_error: ++ GST_ELEMENT_ERROR (flxdec, STREAM, DECODE, ++ ("%s", "Failed to parse stream"), (NULL)); ++unmap_input_error: ++ gst_buffer_unmap (input, &map_info); ++ gst_buffer_unref (input); ++error: ++ return GST_FLOW_ERROR; + } + + static GstStateChangeReturn +diff --git a/gst/flx/gstflxdec.h b/gst/flx/gstflxdec.h +index 3f9a0aa..4fd8dfd 100644 +--- a/gst/flx/gstflxdec.h ++++ b/gst/flx/gstflxdec.h +@@ -23,6 +23,8 @@ + #include + + #include ++#include ++#include + #include "flx_color.h" + + G_BEGIN_DECLS +@@ -45,7 +47,7 @@ struct _GstFlxDec { + + guint8 *delta_data, *frame_data; + GstAdapter *adapter; +- gulong size; ++ gsize size; + GstFlxDecState state; + gint64 frame_time; + gint64 next_time; +-- +2.10.2 + diff --git a/gnu/packages/patches/gst-plugins-good-fix-invalid-read.patch b/gnu/packages/patches/gst-plugins-good-fix-invalid-read.patch new file mode 100644 index 0000000000..1daaa2ae15 --- /dev/null +++ b/gnu/packages/patches/gst-plugins-good-fix-invalid-read.patch @@ -0,0 +1,37 @@ +Fixes upstream bug #774897 (flxdec: Unreferences itself one time too many on +invalid files): + +https://bugzilla.gnome.org/show_bug.cgi?id=774897 + +Patch copied from upstream source repository: + +https://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=b31c504645a814c59d91d49e4fe218acaf93f4ca + +From b31c504645a814c59d91d49e4fe218acaf93f4ca Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= +Date: Wed, 23 Nov 2016 11:20:49 +0200 +Subject: [PATCH] flxdec: Don't unref() parent in the chain function + +We don't own the reference here, it is owned by the caller and given to +us for the scope of this function. Leftover mistake from 0.10 porting. + +https://bugzilla.gnome.org/show_bug.cgi?id=774897 +--- + gst/flx/gstflxdec.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c +index e675c99..a237976 100644 +--- a/gst/flx/gstflxdec.c ++++ b/gst/flx/gstflxdec.c +@@ -677,7 +677,6 @@ wrong_type: + { + GST_ELEMENT_ERROR (flxdec, STREAM, WRONG_TYPE, (NULL), + ("not a flx file (type %x)", flxh->type)); +- gst_object_unref (flxdec); + return GST_FLOW_ERROR; + } + } +-- +2.10.2 + diff --git a/gnu/packages/patches/gst-plugins-good-fix-signedness.patch b/gnu/packages/patches/gst-plugins-good-fix-signedness.patch new file mode 100644 index 0000000000..a3e20e19dd --- /dev/null +++ b/gnu/packages/patches/gst-plugins-good-fix-signedness.patch @@ -0,0 +1,58 @@ +This is a followup fix for upstream bug #774834 (flic decoder: Buffer overflow +in flx_decode_delta_fli): + +https://bugzilla.gnome.org/show_bug.cgi?id=774834#c2 + +Patch copied from upstream source repository: + +https://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=1ab2b26193861b124426e2f8eb62b75b59ec5488 + +From 1ab2b26193861b124426e2f8eb62b75b59ec5488 Mon Sep 17 00:00:00 2001 +From: Matthew Waters +Date: Tue, 22 Nov 2016 23:46:00 +1100 +Subject: [PATCH] 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 +--- + gst/flx/gstflxdec.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c +index d51a8e6..e675c99 100644 +--- a/gst/flx/gstflxdec.c ++++ b/gst/flx/gstflxdec.c +@@ -319,7 +319,7 @@ flx_decode_brun (GstFlxDec * flxdec, guchar * data, guchar * dest) + 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; + } +@@ -329,7 +329,7 @@ flx_decode_brun (GstFlxDec * flxdec, guchar * data, guchar * dest) + *dest++ = *data++; + + } else { +- if ((glong) row - count < 0) { ++ if ((glong) row - (glong) count < 0) { + GST_ERROR_OBJECT (flxdec, "Invalid BRUN packet detected."); + return FALSE; + } +-- +2.10.2 + diff --git a/gnu/packages/patches/gst-plugins-good-flic-bounds-check.patch b/gnu/packages/patches/gst-plugins-good-flic-bounds-check.patch new file mode 100644 index 0000000000..f77dca2cd6 --- /dev/null +++ b/gnu/packages/patches/gst-plugins-good-flic-bounds-check.patch @@ -0,0 +1,319 @@ +Fix CVE-2016-{9634,9635,9636}. + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9634 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9635 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9636 + +This fixes upstream bug #774834 (flic decoder: Buffer overflow in +flx_decode_delta_fli): + +https://bugzilla.gnome.org/show_bug.cgi?id=774834 + +Patch copied from upstream source repository: + +https://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=2e203a79b7d9af4029307c1a845b3c148d5f5e62 + +From 2e203a79b7d9af4029307c1a845b3c148d5f5e62 Mon Sep 17 00:00:00 2001 +From: Matthew Waters +Date: Tue, 22 Nov 2016 19:05:00 +1100 +Subject: [PATCH] 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 +--- + gst/flx/gstflxdec.c | 116 +++++++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 91 insertions(+), 25 deletions(-) + +diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c +index 604be2f..d51a8e6 100644 +--- a/gst/flx/gstflxdec.c ++++ b/gst/flx/gstflxdec.c +@@ -74,9 +74,9 @@ static gboolean gst_flxdec_src_query_handler (GstPad * pad, GstObject * parent, + GstQuery * query); + + 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)) + +@@ -203,13 +203,14 @@ gst_flxdec_sink_event_handler (GstPad * pad, GstObject * parent, + 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; +@@ -228,17 +229,17 @@ flx_decode_chunks (GstFlxDec * flxdec, gulong count, guchar * data, + 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; + +@@ -256,7 +257,12 @@ flx_decode_chunks (GstFlxDec * flxdec, gulong count, guchar * data, + data += rndalign (hdr->size) - FlxFrameChunkSize; + break; + } ++ ++ if (!ret) ++ break; + } ++ ++ return ret; + } + + +@@ -289,13 +295,13 @@ flx_decode_color (GstFlxDec * flxdec, guchar * data, guchar * dest, gint scale) + } + } + +-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--) { +@@ -313,12 +319,21 @@ flx_decode_brun (GstFlxDec * flxdec, guchar * data, guchar * dest) + 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++; +@@ -328,22 +343,28 @@ flx_decode_brun (GstFlxDec * flxdec, guchar * data, guchar * dest) + } + } + } ++ ++ 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_data != NULL); ++ g_return_val_if_fail (flxdec != NULL, FALSE); ++ g_return_val_if_fail (flxdec->delta_data != NULL, FALSE); + + /* use last frame for delta */ + memcpy (dest, flxdec->delta_data, flxdec->size); + + 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 */ +@@ -356,7 +377,8 @@ flx_decode_delta_fli (GstFlxDec * flxdec, guchar * data, guchar * dest) + + while (packets--) { + /* skip count */ +- dest += *data++; ++ guchar skip = *data++; ++ dest += skip; + + /* RLE count */ + count = *data++; +@@ -364,12 +386,24 @@ flx_decode_delta_fli (GstFlxDec * flxdec, guchar * data, guchar * dest) + 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++; +@@ -378,21 +412,27 @@ flx_decode_delta_fli (GstFlxDec * flxdec, guchar * data, guchar * dest) + 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_data != NULL); ++ g_return_val_if_fail (flxdec != NULL, FALSE); ++ g_return_val_if_fail (flxdec->delta_data != NULL, FALSE); + + /* use last frame for delta */ + memcpy (dest, flxdec->delta_data, flxdec->size); + + 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; +@@ -405,9 +445,15 @@ flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) + 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; +@@ -419,7 +465,8 @@ flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) + /* last opcode is the packet count */ + while (opcode--) { + /* skip count */ +- dest += *data++; ++ guchar skip = *data++; ++ dest += skip; + + /* RLE count */ + count = *data++; +@@ -427,12 +474,25 @@ flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) + 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++; +@@ -442,6 +502,8 @@ flx_decode_delta_flc (GstFlxDec * flxdec, guchar * data, guchar * dest) + } + lines--; + } ++ ++ return TRUE; + } + + static GstFlowReturn +@@ -571,9 +633,13 @@ gst_flxdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) + out = gst_buffer_new_and_alloc (flxdec->size * 4); + + /* decode chunks */ +- flx_decode_chunks (flxdec, +- ((FlxFrameType *) chunk)->chunks, +- chunk + FlxFrameTypeSize, flxdec->frame_data); ++ if (!flx_decode_chunks (flxdec, ++ ((FlxFrameType *) chunk)->chunks, ++ chunk + FlxFrameTypeSize, flxdec->frame_data)) { ++ 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 (flxdec->delta_data, flxdec->frame_data, flxdec->size); +-- +2.10.2 + -- cgit v1.2.3 From cd65d600ac6e8701ef9c54f5d09a45cd6c149949 Mon Sep 17 00:00:00 2001 From: Leo Famulari Date: Sat, 26 Nov 2016 15:03:06 -0500 Subject: gnu: cyrus-sasl: Fix CVE-2013-4122. * gnu/packages/patches/cyrus-sasl-CVE-2013-4122.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/cyrus-sasl.scm (cyrus-sasl)[replacement]: New field. (cyrus-sasl/fixed): New variable. [source]: Use patch. --- gnu/local.mk | 1 + gnu/packages/cyrus-sasl.scm | 9 ++ .../patches/cyrus-sasl-CVE-2013-4122.patch | 130 +++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 gnu/packages/patches/cyrus-sasl-CVE-2013-4122.patch (limited to 'gnu/packages/patches') diff --git a/gnu/local.mk b/gnu/local.mk index 8ca4d932d3..dfa9c0077d 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -506,6 +506,7 @@ dist_patch_DATA = \ %D%/packages/patches/cssc-missing-include.patch \ %D%/packages/patches/clucene-contribs-lib.patch \ %D%/packages/patches/cursynth-wave-rand.patch \ + %D%/packages/patches/cyrus-sasl-CVE-2013-4122.patch \ %D%/packages/patches/dbus-helper-search-path.patch \ %D%/packages/patches/devil-CVE-2009-3994.patch \ %D%/packages/patches/devil-fix-libpng.patch \ diff --git a/gnu/packages/cyrus-sasl.scm b/gnu/packages/cyrus-sasl.scm index 99ff1e228e..89a4a49797 100644 --- a/gnu/packages/cyrus-sasl.scm +++ b/gnu/packages/cyrus-sasl.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès ;;; Copyright © 2013 Andreas Enge +;;; Copyright © 2016 Leo Famulari ;;; ;;; This file is part of GNU Guix. ;;; @@ -30,6 +31,7 @@ (define-module (gnu packages cyrus-sasl) (define-public cyrus-sasl (package (name "cyrus-sasl") + (replacement cyrus-sasl/fixed) (version "2.1.26") (source (origin (method url-fetch) @@ -64,3 +66,10 @@ (define-public cyrus-sasl (license (license:non-copyleft "file://COPYING" "See COPYING in the distribution.")) (home-page "http://cyrusimap.web.cmu.edu"))) + +(define cyrus-sasl/fixed + (package + (inherit cyrus-sasl) + (source (origin + (inherit (package-source cyrus-sasl)) + (patches (search-patches "cyrus-sasl-CVE-2013-4122.patch")))))) diff --git a/gnu/packages/patches/cyrus-sasl-CVE-2013-4122.patch b/gnu/packages/patches/cyrus-sasl-CVE-2013-4122.patch new file mode 100644 index 0000000000..fc72e42e03 --- /dev/null +++ b/gnu/packages/patches/cyrus-sasl-CVE-2013-4122.patch @@ -0,0 +1,130 @@ +Fix CVE-2013-4122. + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4122 + +Patch copied from upstream source repository: +https://github.com/cyrusimap/cyrus-sasl/commit/dedad73e5e7a75d01a5f3d5a6702ab8ccd2ff40d + +From dedad73e5e7a75d01a5f3d5a6702ab8ccd2ff40d Mon Sep 17 00:00:00 2001 +From: mancha +Date: Thu, 11 Jul 2013 10:08:07 +0100 +Subject: Handle NULL returns from glibc 2.17+ crypt() + +Starting with glibc 2.17 (eglibc 2.17), crypt() fails with EINVAL +(w/ NULL return) if the salt violates specifications. Additionally, +on FIPS-140 enabled Linux systems, DES/MD5-encrypted passwords +passed to crypt() fail with EPERM (w/ NULL return). + +When using glibc's crypt(), check return value to avoid a possible +NULL pointer dereference. + +Patch by mancha1@hush.com. +--- + pwcheck/pwcheck_getpwnam.c | 3 ++- + pwcheck/pwcheck_getspnam.c | 4 +++- + saslauthd/auth_getpwent.c | 4 +++- + saslauthd/auth_shadow.c | 8 +++----- + 4 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/pwcheck/pwcheck_getpwnam.c b/pwcheck/pwcheck_getpwnam.c +index 4b34222..400289c 100644 +--- a/pwcheck/pwcheck_getpwnam.c ++++ b/pwcheck/pwcheck_getpwnam.c +@@ -32,6 +32,7 @@ char *userid; + char *password; + { + char* r; ++ char* crpt_passwd; + struct passwd *pwd; + + pwd = getpwnam(userid); +@@ -41,7 +42,7 @@ char *password; + else if (pwd->pw_passwd[0] == '*') { + r = "Account disabled"; + } +- else if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) { ++ else if (!(crpt_passwd = crypt(password, pwd->pw_passwd)) || strcmp(pwd->pw_passwd, (const char *)crpt_passwd) != 0) { + r = "Incorrect password"; + } + else { +diff --git a/pwcheck/pwcheck_getspnam.c b/pwcheck/pwcheck_getspnam.c +index 2b11286..6d607bb 100644 +--- a/pwcheck/pwcheck_getspnam.c ++++ b/pwcheck/pwcheck_getspnam.c +@@ -32,13 +32,15 @@ char *userid; + char *password; + { + struct spwd *pwd; ++ char *crpt_passwd; + + pwd = getspnam(userid); + if (!pwd) { + return "Userid not found"; + } + +- if (strcmp(pwd->sp_pwdp, crypt(password, pwd->sp_pwdp)) != 0) { ++ crpt_passwd = crypt(password, pwd->sp_pwdp); ++ if (!crpt_passwd || strcmp(pwd->sp_pwdp, (const char *)crpt_passwd) != 0) { + return "Incorrect password"; + } + else { +diff --git a/saslauthd/auth_getpwent.c b/saslauthd/auth_getpwent.c +index fc8029d..d4ebe54 100644 +--- a/saslauthd/auth_getpwent.c ++++ b/saslauthd/auth_getpwent.c +@@ -77,6 +77,7 @@ auth_getpwent ( + { + /* VARIABLES */ + struct passwd *pw; /* pointer to passwd file entry */ ++ char *crpt_passwd; /* encrypted password */ + int errnum; + /* END VARIABLES */ + +@@ -105,7 +106,8 @@ auth_getpwent ( + } + } + +- if (strcmp(pw->pw_passwd, (const char *)crypt(password, pw->pw_passwd))) { ++ crpt_passwd = crypt(password, pw->pw_passwd); ++ if (!crpt_passwd || strcmp(pw->pw_passwd, (const char *)crpt_passwd)) { + if (flags & VERBOSE) { + syslog(LOG_DEBUG, "DEBUG: auth_getpwent: %s: invalid password", login); + } +diff --git a/saslauthd/auth_shadow.c b/saslauthd/auth_shadow.c +index 677131b..1988afd 100644 +--- a/saslauthd/auth_shadow.c ++++ b/saslauthd/auth_shadow.c +@@ -210,8 +210,8 @@ auth_shadow ( + RETURN("NO Insufficient permission to access NIS authentication database (saslauthd)"); + } + +- cpw = strdup((const char *)crypt(password, sp->sp_pwdp)); +- if (strcmp(sp->sp_pwdp, cpw)) { ++ cpw = crypt(password, sp->sp_pwdp); ++ if (!cpw || strcmp(sp->sp_pwdp, (const char *)cpw)) { + if (flags & VERBOSE) { + /* + * This _should_ reveal the SHADOW_PW_LOCKED prefix to an +@@ -221,10 +221,8 @@ auth_shadow ( + syslog(LOG_DEBUG, "DEBUG: auth_shadow: pw mismatch: '%s' != '%s'", + sp->sp_pwdp, cpw); + } +- free(cpw); + RETURN("NO Incorrect password"); + } +- free(cpw); + + /* + * The following fields will be set to -1 if: +@@ -286,7 +284,7 @@ auth_shadow ( + RETURN("NO Invalid username"); + } + +- if (strcmp(upw->upw_passwd, crypt(password, upw->upw_passwd)) != 0) { ++ if (!(cpw = crypt(password, upw->upw_passwd)) || (strcmp(upw->upw_passwd, (const char *)cpw) != 0)) { + if (flags & VERBOSE) { + syslog(LOG_DEBUG, "auth_shadow: pw mismatch: %s != %s", + password, upw->upw_passwd); +-- +cgit v0.12 + -- cgit v1.2.3 From dbf8f84f15fb80fa41caeed073460853083e48d3 Mon Sep 17 00:00:00 2001 From: Ricardo Wurmus Date: Fri, 25 Nov 2016 22:29:41 +0100 Subject: gnu: gcj: Fix build on armhf. * gnu/packages/patches/gcj-arm-mode.patch: New file. * gnu/local.mk (dist_patch_DATA): Add patch. * gnu/packages/gcc.scm (gcj): Add patch. [arguments]: Delete failing tests. --- gnu/local.mk | 1 + gnu/packages/gcc.scm | 14 +++++++++++++ gnu/packages/patches/gcj-arm-mode.patch | 36 +++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 gnu/packages/patches/gcj-arm-mode.patch (limited to 'gnu/packages/patches') diff --git a/gnu/local.mk b/gnu/local.mk index 5a9001b6d4..5ab9c3b036 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -554,6 +554,7 @@ dist_patch_DATA = \ %D%/packages/patches/gcc-5.0-libvtv-runpath.patch \ %D%/packages/patches/gcc-6-arm-none-eabi-multilib.patch \ %D%/packages/patches/gcc-6-cross-environment-variables.patch \ + %D%/packages/patches/gcj-arm-mode.patch \ %D%/packages/patches/gd-CVE-2016-7568.patch \ %D%/packages/patches/gd-CVE-2016-8670.patch \ %D%/packages/patches/gd-fix-chunk-size-on-boundaries.patch \ diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm index c26cc4f497..ead270a3b5 100644 --- a/gnu/packages/gcc.scm +++ b/gnu/packages/gcc.scm @@ -521,6 +521,16 @@ (define javac.in (define-public gcj (package (inherit gcc) (name "gcj") + (version (package-version gcc)) + (source (origin + (method url-fetch) + (uri (string-append "mirror://gnu/gcc/gcc-" + version "/gcc-" version ".tar.bz2")) + (sha256 + (base32 + "0zmnm00d2a1hsd41g34bhvxzvxisa2l584q3p447bd91lfjv4ci3")) + (patches (cons (search-patch "gcj-arm-mode.diff") + (origin-patches (package-source gcc)))))) (inputs `(("fastjar" ,fastjar) ("perl" ,perl) @@ -568,6 +578,10 @@ (define-public gcj 'unpack 'patch-testsuite ;; dejagnu-1.6 removes the 'absolute' command (lambda _ + ;; This test fails on armhf. It seems harmless enough to disable it. + (for-each delete-file '("libjava/testsuite/libjava.lang/Throw_2.java" + "libjava/testsuite/libjava.lang/Throw_2.out" + "libjava/testsuite/libjava.lang/Throw_2.jar")) (substitute* "libjava/testsuite/lib/libjava.exp" (("absolute") "file normalize")) #t)) diff --git a/gnu/packages/patches/gcj-arm-mode.patch b/gnu/packages/patches/gcj-arm-mode.patch new file mode 100644 index 0000000000..16fdb5ecac --- /dev/null +++ b/gnu/packages/patches/gcj-arm-mode.patch @@ -0,0 +1,36 @@ +Taken from +https://sources.debian.net/data/main/g/gcc-4.9/4.9.2-10/debian/patches/gcj-arm-mode.diff + +# DP: For armhf, force arm mode instead of thumb mode + +--- a/src/libjava/configure.host ++++ b/src/libjava/configure.host +@@ -66,6 +66,9 @@ + ;; + esac + ++# on armhf force arm mode ++libgcj_flags="${libgcj_flags} -marm" ++ + AM_RUNTESTFLAGS= + + # Set any host dependent compiler flags. +--- a/src/gcc/java/lang-specs.h ++++ b/src/gcc/java/lang-specs.h +@@ -47,7 +47,7 @@ + %{.class|.zip|.jar|!fsyntax-only:jc1 \ + %{.java|fsaw-java-file:%U.jar -fsource-filename=%i % Date: Sun, 27 Nov 2016 18:59:54 +0100 Subject: gnu: gcj: Correct paths in ARM patch. * gnu/packages/patches/gcj-arm-mode.patch: Strip directories. --- gnu/packages/patches/gcj-arm-mode.patch | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'gnu/packages/patches') diff --git a/gnu/packages/patches/gcj-arm-mode.patch b/gnu/packages/patches/gcj-arm-mode.patch index 16fdb5ecac..a3f999f7e9 100644 --- a/gnu/packages/patches/gcj-arm-mode.patch +++ b/gnu/packages/patches/gcj-arm-mode.patch @@ -3,8 +3,8 @@ https://sources.debian.net/data/main/g/gcc-4.9/4.9.2-10/debian/patches/gcj-arm-m # DP: For armhf, force arm mode instead of thumb mode ---- a/src/libjava/configure.host -+++ b/src/libjava/configure.host +--- a/libjava/configure.host ++++ b/libjava/configure.host @@ -66,6 +66,9 @@ ;; esac @@ -15,8 +15,8 @@ https://sources.debian.net/data/main/g/gcc-4.9/4.9.2-10/debian/patches/gcj-arm-m AM_RUNTESTFLAGS= # Set any host dependent compiler flags. ---- a/src/gcc/java/lang-specs.h -+++ b/src/gcc/java/lang-specs.h +--- a/gcc/java/lang-specs.h ++++ b/gcc/java/lang-specs.h @@ -47,7 +47,7 @@ %{.class|.zip|.jar|!fsyntax-only:jc1 \ %{.java|fsaw-java-file:%U.jar -fsource-filename=%i % Date: Sun, 27 Nov 2016 00:19:21 -0500 Subject: gnu: python-rarfile: Update to 2.8. * gnu/packages/python.scm (python-rarfile, python2-rarfile): Update to 2.8. [source]: Remove obsolete patch. * gnu/packages/patches/python-rarfile-fix-tests.patch: Delete file. * gnu/local.mk (dist_patch_DATA): Remove it. --- gnu/local.mk | 1 - gnu/packages/patches/python-rarfile-fix-tests.patch | 14 -------------- gnu/packages/python.scm | 6 ++---- 3 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 gnu/packages/patches/python-rarfile-fix-tests.patch (limited to 'gnu/packages/patches') diff --git a/gnu/local.mk b/gnu/local.mk index 5ab9c3b036..c50ef254e0 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -827,7 +827,6 @@ dist_patch_DATA = \ %D%/packages/patches/python-file-double-encoding-bug.patch \ %D%/packages/patches/python-fix-tests.patch \ %D%/packages/patches/python-parse-too-many-fields.patch \ - %D%/packages/patches/python-rarfile-fix-tests.patch \ %D%/packages/patches/python2-rdflib-drop-sparqlwrapper.patch \ %D%/packages/patches/python-statsmodels-fix-tests.patch \ %D%/packages/patches/python-configobj-setuptools.patch \ diff --git a/gnu/packages/patches/python-rarfile-fix-tests.patch b/gnu/packages/patches/python-rarfile-fix-tests.patch deleted file mode 100644 index 8ae8894009..0000000000 --- a/gnu/packages/patches/python-rarfile-fix-tests.patch +++ /dev/null @@ -1,14 +0,0 @@ -There is no test.sh, but there are test1.sh and test2.sh. - -diff --git a/test/Makefile b/test/Makefile -index 027bc5f..5383db3 100644 ---- a/test/Makefile -+++ b/test/Makefile -@@ -1,5 +1,6 @@ - test: -- ./test.sh -+ ./test1.sh -+ ./test2.sh - - clean: - rm -rf __pycache__ diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm index 5c27b90402..e3cde11ab4 100644 --- a/gnu/packages/python.scm +++ b/gnu/packages/python.scm @@ -9816,15 +9816,13 @@ (define-public python2-unicodecsv (define-public python-rarfile (package (name "python-rarfile") - (version "2.7") + (version "2.8") (source (origin (method url-fetch) (uri (pypi-uri "rarfile" version)) (sha256 (base32 - "0d8n1dlpiz7av8dmbp0vclrwl9cnxizr4f2c9xvj1h5nvn480527")) - ;; https://github.com/markokr/rarfile/pull/17/ - (patches (search-patches "python-rarfile-fix-tests.patch")))) + "0qfad483kcbga0bn4qmcz953xjk16r52fahiy46zzn56v80y89ra")))) (build-system python-build-system) (arguments '(#:phases -- cgit v1.2.3 From c51d926c740f98883ce3332852e826f57fdf4566 Mon Sep 17 00:00:00 2001 From: Efraim Flashner Date: Mon, 28 Nov 2016 19:25:21 +0200 Subject: gnu: cairo: Fix CVE-2016-9082. * gnu/packages/gtk.scm (cairo)[replacement]: New field. (cairo/fixed): New variable. (cairo-xcb)[source]: Use patch. [replacement]: New field, set false. * gnu/packages/pdf.scm (poppler)[inputs]: Custom cairo should be replaced by a new custom patched cairo. * gnu/packages/patches/cairo-CVE-2016-9082.patch: New file. * gnu/local.mk (dist_patch_DATA): Register it. --- gnu/local.mk | 1 + gnu/packages/gtk.scm | 12 +++ gnu/packages/patches/cairo-CVE-2016-9082.patch | 122 +++++++++++++++++++++++++ gnu/packages/pdf.scm | 11 +++ 4 files changed, 146 insertions(+) create mode 100644 gnu/packages/patches/cairo-CVE-2016-9082.patch (limited to 'gnu/packages/patches') diff --git a/gnu/local.mk b/gnu/local.mk index 49609cd68f..9d0e4c5094 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -489,6 +489,7 @@ dist_patch_DATA = \ %D%/packages/patches/binutils-loongson-workaround.patch \ %D%/packages/patches/binutils-mips-bash-bug.patch \ %D%/packages/patches/byobu-writable-status.patch \ + %D%/packages/patches/cairo-CVE-2016-9082.patch \ %D%/packages/patches/calibre-drop-unrar.patch \ %D%/packages/patches/calibre-no-updates-dialog.patch \ %D%/packages/patches/cdparanoia-fpic.patch \ diff --git a/gnu/packages/gtk.scm b/gnu/packages/gtk.scm index 17bd9c9b00..8a258b54cc 100644 --- a/gnu/packages/gtk.scm +++ b/gnu/packages/gtk.scm @@ -100,6 +100,7 @@ (define-public atk (define-public cairo (package (name "cairo") + (replacement cairo/fixed) (version "1.14.6") (source (origin (method url-fetch) @@ -153,6 +154,10 @@ (define-public cairo-xcb (package (inherit cairo) (name "cairo-xcb") + (source (origin + (inherit (package-source cairo)) + (patches (search-patches "cairo-CVE-2016-9082.patch")))) + (replacement #f) (inputs `(("mesa" ,mesa) ,@(package-inputs cairo))) @@ -162,6 +167,13 @@ (define-public cairo-xcb '("--enable-xlib-xcb" "--enable-gl" "--enable-egl"))) (synopsis "2D graphics library (with X11 support)"))) +(define cairo/fixed + (package + (inherit cairo) + (source (origin + (inherit (package-source cairo)) + (patches (search-patches "cairo-CVE-2016-9082.patch")))))) + (define-public harfbuzz (package (name "harfbuzz") diff --git a/gnu/packages/patches/cairo-CVE-2016-9082.patch b/gnu/packages/patches/cairo-CVE-2016-9082.patch new file mode 100644 index 0000000000..ad83404194 --- /dev/null +++ b/gnu/packages/patches/cairo-CVE-2016-9082.patch @@ -0,0 +1,122 @@ +From: Adrian Johnson +Date: Thu, 20 Oct 2016 21:12:30 +1030 +Subject: [PATCH] image: prevent invalid ptr access for > 4GB images + +Image data is often accessed using: + + image->data + y * image->stride + +On 64-bit achitectures if the image data is > 4GB, this computation +will overflow since both y and stride are 32-bit types. + +bug report: https://bugs.freedesktop.org/show_bug.cgi?id=98165 +patch: https://bugs.freedesktop.org/attachment.cgi?id=127421 +--- + boilerplate/cairo-boilerplate.c | 4 +++- + src/cairo-image-compositor.c | 4 ++-- + src/cairo-image-surface-private.h | 2 +- + src/cairo-mesh-pattern-rasterizer.c | 2 +- + src/cairo-png.c | 2 +- + src/cairo-script-surface.c | 3 ++- + 6 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c +index 7fdbf79..4804dea 100644 +--- a/boilerplate/cairo-boilerplate.c ++++ b/boilerplate/cairo-boilerplate.c +@@ -42,6 +42,7 @@ + #undef CAIRO_VERSION_H + #include "../cairo-version.h" + ++#include + #include + #include + #include +@@ -976,7 +977,8 @@ cairo_surface_t * + cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file) + { + char format; +- int width, height, stride; ++ int width, height; ++ ptrdiff_t stride; + int x, y; + unsigned char *data; + cairo_surface_t *image = NULL; +diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c +index 48072f8..3ca0006 100644 +--- a/src/cairo-image-compositor.c ++++ b/src/cairo-image-compositor.c +@@ -1575,7 +1575,7 @@ typedef struct _cairo_image_span_renderer { + pixman_image_t *src, *mask; + union { + struct fill { +- int stride; ++ ptrdiff_t stride; + uint8_t *data; + uint32_t pixel; + } fill; +@@ -1594,7 +1594,7 @@ typedef struct _cairo_image_span_renderer { + struct finish { + cairo_rectangle_int_t extents; + int src_x, src_y; +- int stride; ++ ptrdiff_t stride; + uint8_t *data; + } mask; + } u; +diff --git a/src/cairo-image-surface-private.h b/src/cairo-image-surface-private.h +index 8ca694c..7e78d61 100644 +--- a/src/cairo-image-surface-private.h ++++ b/src/cairo-image-surface-private.h +@@ -71,7 +71,7 @@ struct _cairo_image_surface { + + int width; + int height; +- int stride; ++ ptrdiff_t stride; + int depth; + + unsigned owns_data : 1; +diff --git a/src/cairo-mesh-pattern-rasterizer.c b/src/cairo-mesh-pattern-rasterizer.c +index 1b63ca8..e7f0db6 100644 +--- a/src/cairo-mesh-pattern-rasterizer.c ++++ b/src/cairo-mesh-pattern-rasterizer.c +@@ -470,7 +470,7 @@ draw_pixel (unsigned char *data, int width, int height, int stride, + tg += tg >> 16; + tb += tb >> 16; + +- *((uint32_t*) (data + y*stride + 4*x)) = ((ta << 16) & 0xff000000) | ++ *((uint32_t*) (data + y*(ptrdiff_t)stride + 4*x)) = ((ta << 16) & 0xff000000) | + ((tr >> 8) & 0xff0000) | ((tg >> 16) & 0xff00) | (tb >> 24); + } + } +diff --git a/src/cairo-png.c b/src/cairo-png.c +index 562b743..aa8c227 100644 +--- a/src/cairo-png.c ++++ b/src/cairo-png.c +@@ -673,7 +673,7 @@ read_png (struct png_read_closure_t *png_closure) + } + + for (i = 0; i < png_height; i++) +- row_pointers[i] = &data[i * stride]; ++ row_pointers[i] = &data[i * (ptrdiff_t)stride]; + + png_read_image (png, row_pointers); + png_read_end (png, info); +diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c +index ea0117d..91e4baa 100644 +--- a/src/cairo-script-surface.c ++++ b/src/cairo-script-surface.c +@@ -1202,7 +1202,8 @@ static cairo_status_t + _write_image_surface (cairo_output_stream_t *output, + const cairo_image_surface_t *image) + { +- int stride, row, width; ++ int row, width; ++ ptrdiff_t stride; + uint8_t row_stack[CAIRO_STACK_BUFFER_SIZE]; + uint8_t *rowdata; + uint8_t *data; +-- +2.1.4 + diff --git a/gnu/packages/pdf.scm b/gnu/packages/pdf.scm index 39f4d021de..6442f08af9 100644 --- a/gnu/packages/pdf.scm +++ b/gnu/packages/pdf.scm @@ -95,6 +95,17 @@ (define-public poppler ;; To build poppler-glib (as needed by Evince), we need Cairo and ;; GLib. But of course, that Cairo must not depend on Poppler. ("cairo" ,(package (inherit cairo) + (replacement + (package + (inherit cairo) + (replacement #f) + (source + (origin + (inherit (package-source cairo)) + (patches (search-patches + "cairo-CVE-2016-9082.patch")))) + (inputs (alist-delete "poppler" + (package-inputs cairo))))) (inputs (alist-delete "poppler" (package-inputs cairo))))) ("glib" ,glib))) -- cgit v1.2.3