Subject: bug#47999: closed (RE: [PATCH] gnu: gst-plugins-good: Fix CVE-2021-3497 and CVE-2021-3498.)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 24 Apr 2021 18:27:01 +0000

Your bug report

#47999: [PATCH] gnu: gst-plugins-good: Fix CVE-2021-3497 and CVE-2021-3498.

which was filed against the guix-patches package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
47999: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=47999
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: RE: [PATCH] gnu: gst-plugins-good: Fix CVE-2021-3497 and CVE-2021-3498.
From: Leo Famulari <[email-masked]>
To: [email-masked]
Date: Sat, 24 Apr 2021 14:25:53 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

I'm closing this bug in advance of a full set of GStreamer security
updates, coming shortly.

Subject: [PATCH] gnu: gst-plugins-good: Fix CVE-2021-3497 and CVE-2021-3498.
From: Leo Famulari <[email-masked]>
To: [email-masked]
Date: Sat, 24 Apr 2021 14:14:50 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

* gnu/packages/patches/gst-plugins-good-CVE-2021-3497.patch,
gnu/packages/patches/gst-plugins-good-CVE-2021-3498.patch: New files.
* gnu/local.mk (dist_patch_DATA): Add them.
* gnu/packages/gstreamer.scm (gst-plugins-good)[source]: Use them.
---
 gnu/local.mk                                  |   2 +
 gnu/packages/gstreamer.scm                    |   4 +-
 .../gst-plugins-good-CVE-2021-3497.patch      | 174 ++++++++++++++++++
 .../gst-plugins-good-CVE-2021-3498.patch      |  22 +++
 4 files changed, 201 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/gst-plugins-good-CVE-2021-3497.patch
 create mode 100644 gnu/packages/patches/gst-plugins-good-CVE-2021-3498.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 50b11a8ca2..e19daf76ca 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1170,6 +1170,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/grub-verifiers-Blocklist-fallout-cleanup.patch \
   %D%/packages/patches/gspell-dash-test.patch			\
   %D%/packages/patches/gst-plugins-good-fix-test.patch		\
+  %D%/packages/patches/gst-plugins-good-CVE-2021-3497.patch	\
+  %D%/packages/patches/gst-plugins-good-CVE-2021-3498.patch	\
   %D%/packages/patches/guile-1.8-cpp-4.5.patch			\
   %D%/packages/patches/guile-2.2-skip-oom-test.patch            \
   %D%/packages/patches/guile-2.2-skip-so-test.patch             \
diff --git a/gnu/packages/gstreamer.scm b/gnu/packages/gstreamer.scm
index 6a4e14167d..6a050ca297 100644
--- a/gnu/packages/gstreamer.scm
+++ b/gnu/packages/gstreamer.scm
@@ -591,7 +591,9 @@ for the GStreamer multimedia library.")
         (string-append
          "https://gstreamer.freedesktop.org/src/" name "/"
          name "-" version ".tar.xz"))
-       (patches (search-patches "gst-plugins-good-fix-test.patch"))
+       (patches (search-patches "gst-plugins-good-fix-test.patch"
+                                "gst-plugins-good-CVE-2021-3497.patch"
+                                "gst-plugins-good-CVE-2021-3498.patch"))
        (sha256
         (base32 "1929nhjsvbl4bw37nfagnfsnxz737cm2x3ayz9ayrn9lwkfm45zp"))))
     (build-system meson-build-system)
diff --git a/gnu/packages/patches/gst-plugins-good-CVE-2021-3497.patch b/gnu/packages/patches/gst-plugins-good-CVE-2021-3497.patch
new file mode 100644
index 0000000000..c8c3ee6cf1
--- /dev/null
+++ b/gnu/packages/patches/gst-plugins-good-CVE-2021-3497.patch
@@ -0,0 +1,174 @@
+Fix CVE-2021-3497:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3497
+https://gstreamer.freedesktop.org/security/sa-2021-0002.html
+
+Patch copied from upstream source repository:
+
+https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/commit/9181191511f9c0be6a89c98b311f49d66bd46dc3?merge_request_iid=903
+
+diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
+index 467815986c8c3d86fd8906a0d539b34f67d6693e..0e47ee7b5e25ac3331f30439710ae755235f2a22 100644
+--- a/gst/matroska/matroska-demux.c
++++ b/gst/matroska/matroska-demux.c
+@@ -3851,6 +3851,12 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
+     guint32 block_samples, tmp;
+     gsize size = gst_buffer_get_size (*buf);
+ 
++    if (size < 4) {
++      GST_ERROR_OBJECT (element, "Too small wavpack buffer");
++      gst_buffer_unmap (*buf, &map);
++      return GST_FLOW_ERROR;
++    }
++
+     gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
+     block_samples = GUINT32_FROM_LE (tmp);
+     /* we need to reconstruct the header of the wavpack block */
+@@ -3858,10 +3864,10 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
+     /* -20 because ck_size is the size of the wavpack block -8
+      * and lace_size is the size of the wavpack block + 12
+      * (the three guint32 of the header that already are in the buffer) */
+-    wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
++    wvh.ck_size = size + WAVPACK4_HEADER_SIZE - 20;
+ 
+     /* block_samples, flags and crc are already in the buffer */
+-    newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
++    newbuf = gst_buffer_new_allocate (NULL, WAVPACK4_HEADER_SIZE - 12, NULL);
+ 
+     gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
+     data = outmap.data;
+@@ -3886,9 +3892,11 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
+     audiocontext->wvpk_block_index += block_samples;
+   } else {
+     guint8 *outdata = NULL;
+-    guint outpos = 0;
+-    gsize buf_size, size, out_size = 0;
++    gsize buf_size, size;
+     guint32 block_samples, flags, crc, blocksize;
++    GstAdapter *adapter;
++
++    adapter = gst_adapter_new ();
+ 
+     gst_buffer_map (*buf, &map, GST_MAP_READ);
+     buf_data = map.data;
+@@ -3897,6 +3905,7 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
+     if (buf_size < 4) {
+       GST_ERROR_OBJECT (element, "Too small wavpack buffer");
+       gst_buffer_unmap (*buf, &map);
++      g_object_unref (adapter);
+       return GST_FLOW_ERROR;
+     }
+ 
+@@ -3918,59 +3927,57 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
+       data += 4;
+       size -= 4;
+ 
+-      if (blocksize == 0 || size < blocksize)
+-        break;
+-
+-      g_assert ((newbuf == NULL) == (outdata == NULL));
++      if (blocksize == 0 || size < blocksize) {
++        GST_ERROR_OBJECT (element, "Too small wavpack buffer");
++        gst_buffer_unmap (*buf, &map);
++        g_object_unref (adapter);
++        return GST_FLOW_ERROR;
++      }
+ 
+-      if (newbuf == NULL) {
+-        out_size = sizeof (Wavpack4Header) + blocksize;
+-        newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
++      g_assert (newbuf == NULL);
+ 
+-        gst_buffer_copy_into (newbuf, *buf,
+-            GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
++      newbuf =
++          gst_buffer_new_allocate (NULL, WAVPACK4_HEADER_SIZE + blocksize,
++          NULL);
++      gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
++      outdata = outmap.data;
++
++      outdata[0] = 'w';
++      outdata[1] = 'v';
++      outdata[2] = 'p';
++      outdata[3] = 'k';
++      outdata += 4;
++
++      GST_WRITE_UINT32_LE (outdata, blocksize + WAVPACK4_HEADER_SIZE - 8);
++      GST_WRITE_UINT16_LE (outdata + 4, wvh.version);
++      GST_WRITE_UINT8 (outdata + 6, wvh.track_no);
++      GST_WRITE_UINT8 (outdata + 7, wvh.index_no);
++      GST_WRITE_UINT32_LE (outdata + 8, wvh.total_samples);
++      GST_WRITE_UINT32_LE (outdata + 12, wvh.block_index);
++      GST_WRITE_UINT32_LE (outdata + 16, block_samples);
++      GST_WRITE_UINT32_LE (outdata + 20, flags);
++      GST_WRITE_UINT32_LE (outdata + 24, crc);
++      outdata += 28;
++
++      memcpy (outdata, data, blocksize);
+ 
+-        outpos = 0;
+-        gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
+-        outdata = outmap.data;
+-      } else {
+-        gst_buffer_unmap (newbuf, &outmap);
+-        out_size += sizeof (Wavpack4Header) + blocksize;
+-        gst_buffer_set_size (newbuf, out_size);
+-        gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
+-        outdata = outmap.data;
+-      }
++      gst_buffer_unmap (newbuf, &outmap);
++      gst_adapter_push (adapter, newbuf);
++      newbuf = NULL;
+ 
+-      outdata[outpos] = 'w';
+-      outdata[outpos + 1] = 'v';
+-      outdata[outpos + 2] = 'p';
+-      outdata[outpos + 3] = 'k';
+-      outpos += 4;
+-
+-      GST_WRITE_UINT32_LE (outdata + outpos,
+-          blocksize + sizeof (Wavpack4Header) - 8);
+-      GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
+-      GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
+-      GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
+-      GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
+-      GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
+-      GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
+-      GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
+-      GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
+-      outpos += 28;
+-
+-      memmove (outdata + outpos, data, blocksize);
+-      outpos += blocksize;
+       data += blocksize;
+       size -= blocksize;
+     }
+     gst_buffer_unmap (*buf, &map);
+-    gst_buffer_unref (*buf);
+ 
+-    if (newbuf)
+-      gst_buffer_unmap (newbuf, &outmap);
++    newbuf = gst_adapter_take_buffer (adapter, gst_adapter_available (adapter));
++    g_object_unref (adapter);
+ 
++    gst_buffer_copy_into (newbuf, *buf,
++        GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
++    gst_buffer_unref (*buf);
+     *buf = newbuf;
++
+     audiocontext->wvpk_block_index += block_samples;
+   }
+ 
+diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h
+index 429213f778063ba0063944ab64ad60373bbce5ee..8d4a685a910ec13100a3c3d156b2412d28ec0522 100644
+--- a/gst/matroska/matroska-ids.h
++++ b/gst/matroska/matroska-ids.h
+@@ -688,6 +688,8 @@ typedef struct _Wavpack4Header {
+   guint32 crc;           /* crc for actual decoded data                    */
+ } Wavpack4Header;
+ 
++#define WAVPACK4_HEADER_SIZE (32)
++
+ typedef enum {
+   GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME = (1<<0),
+   GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA = (1<<1),
diff --git a/gnu/packages/patches/gst-plugins-good-CVE-2021-3498.patch b/gnu/packages/patches/gst-plugins-good-CVE-2021-3498.patch
new file mode 100644
index 0000000000..50eb42f126
--- /dev/null
+++ b/gnu/packages/patches/gst-plugins-good-CVE-2021-3498.patch
@@ -0,0 +1,22 @@
+Fix CVE-2021-3498:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3498
+https://gstreamer.freedesktop.org/security/sa-2021-0003.html
+
+Patch copied from upstream source repository:
+
+https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/commit/02174790726dd20a5c73ce2002189bf240ad4fe0?merge_request_iid=903
+
+diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
+index 4d0234743b8cf243b4521e56ef9027ba23b1b5d0..467815986c8c3d86fd8906a0d539b34f67d6693e 100644
+--- a/gst/matroska/matroska-demux.c
++++ b/gst/matroska/matroska-demux.c
+@@ -692,6 +692,8 @@ gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
+ 
+   DEBUG_ELEMENT_START (demux, ebml, "TrackEntry");
+ 
++  *dest_context = NULL;
++
+   /* start with the master */
+   if ((ret = gst_ebml_read_master (ebml, &id)) != GST_FLOW_OK) {
+     DEBUG_ELEMENT_STOP (demux, ebml, "TrackEntry", ret);
-- 
2.31.1