From 15d4d3c209b4d107cb1d0314f487b0b599980def Mon Sep 17 00:00:00 2001 From: yangl777 Date: Tue, 17 Aug 2021 11:11:11 +0800 Subject: [PATCH] fix CVE-2021-3497 CVE-2021-3498 --- backport-CVE-2021-3497.patch | 200 +++++++++++++++++++++++++++++++++++ backport-CVE-2021-3498.patch | 37 +++++++ gstreamer1-plugins-good.spec | 11 +- 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2021-3497.patch create mode 100644 backport-CVE-2021-3498.patch diff --git a/backport-CVE-2021-3497.patch b/backport-CVE-2021-3497.patch new file mode 100644 index 0000000..645c774 --- /dev/null +++ b/backport-CVE-2021-3497.patch @@ -0,0 +1,200 @@ +From 242f3cae6da748ac128e86b5cadcd406fa61aff6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= +Date: Thu, 4 Mar 2021 13:05:19 +0200 +Subject: [PATCH] matroskademux: Fix extraction of multichannel WavPack + +The old code had a couple of issues that all lead to potential memory +safety bugs. + + - Use a constant for the Wavpack4Header size instead of using sizeof. + It's written out into the data and not from the struct and who knows + what special alignment/padding requirements some C compilers have. + - gst_buffer_set_size() does not realloc the buffer when setting a + bigger size than allocated, it only allows growing up to the maximum + allocated size. Instead use a GstAdapter to collect all the blocks + and take out everything at once in the end. + - Check that enough data is actually available in the input and + otherwise handle it an error in all cases instead of silently + ignoring it. + +Among other things this fixes out of bounds writes because the code +assumed gst_buffer_set_size() can grow the buffer and simply wrote after +the end of the buffer. + +Thanks to Natalie Silvanovich for reporting. + +Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/859 + +Part-of: +--- + gst/matroska/matroska-demux.c | 99 +++++++++++++++++++---------------- + gst/matroska/matroska-ids.h | 2 + + 2 files changed, 55 insertions(+), 46 deletions(-) + +diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c +index e878e0d66..68215d2ca 100644 +--- a/gst/matroska/matroska-demux.c ++++ b/gst/matroska/matroska-demux.c +@@ -3856,6 +3856,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 */ +@@ -3863,10 +3869,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; +@@ -3891,9 +3897,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; +@@ -3902,6 +3910,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; + } + +@@ -3923,59 +3932,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 429213f77..8d4a685a9 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), +-- +GitLab diff --git a/backport-CVE-2021-3498.patch b/backport-CVE-2021-3498.patch new file mode 100644 index 0000000..4b0a98a --- /dev/null +++ b/backport-CVE-2021-3498.patch @@ -0,0 +1,37 @@ +From 6c461e90bc1eedce4b7e414d34c8a8a9162359b5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= +Date: Wed, 3 Mar 2021 11:31:52 +0200 +Subject: [PATCH] matroskademux: Initialize track context out parameter to NULL + before parsing + +Various error return paths don't set it to NULL and callers are only +checking if the pointer is NULL. As it's allocated on the stack this +usually contains random stack memory, and more often than not the memory +of a previously parsed track. + +This then causes all kinds of memory corruptions further down the line. + +Thanks to Natalie Silvanovich for reporting. + +Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/858 + +Part-of: +--- + gst/matroska/matroska-demux.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c +index d7b6f7edc..e878e0d66 100644 +--- a/gst/matroska/matroska-demux.c ++++ b/gst/matroska/matroska-demux.c +@@ -694,6 +694,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); +-- +GitLab diff --git a/gstreamer1-plugins-good.spec b/gstreamer1-plugins-good.spec index d306485..89d3588 100644 --- a/gstreamer1-plugins-good.spec +++ b/gstreamer1-plugins-good.spec @@ -3,13 +3,16 @@ Name: gstreamer1-plugins-good Version: 1.16.2 -Release: 2 +Release: 3 Summary: GStreamer plugins with good code and licensing License: LGPLv2+ URL: http://gstreamer.freedesktop.org/ Source0: http://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-%{version}.tar.xz Source1: gstreamer-good.appdata.xml +Patch6000: backport-CVE-2021-3497.patch +Patch6001: backport-CVE-2021-3498.patch + BuildRequires: gcc gcc-c++ gstreamer1-devel gstreamer1-plugins-base-devel flac-devel BuildRequires: gdk-pixbuf2-devel libjpeg-devel libpng-devel libshout-devel orc-devel BuildRequires: libsoup-devel libX11-devel libXext-devel libXdamage-devel libXfixes-devel @@ -84,6 +87,12 @@ install -p -D %{SOURCE1} %{buildroot}%{_metainfodir}/gstreamer-good.appdata.xml %doc %{_datadir}/gtk-doc/html/* %changelog +* Tue Aug 17 2021 yanglu - 1.16.2-3 +- Type:cves +- ID:CVE-2021-3497 CVE-2021-3498 +- SUG:NA +- DESC:fix CVE-2021-3497 CVE-2021-3498 + * Sat Nov 21 2020 gaihuiying - 1.16.2-2 - Type:bugfix - ID:NA -- Gitee