Fixes for CVE-2022-1920, CVE-2022-1921, CVE-2022-1922, CVE-2022-1923,

CVE-2022-1924, CVE-2022-1925, CVE-2022-2122
  Resolves: rhbz#2131034, rhbz#2131039, rhbz#2131045, rhbz#2131049,
            rhbz#2131054, rhbz#2131060, rhbz#2131064
This commit is contained in:
Wim Taymans 2022-11-11 10:57:15 +01:00
parent 7349bd0497
commit b934ccf6c5
5 changed files with 400 additions and 1 deletions

View File

@ -0,0 +1,65 @@
From bcfe7befea53869e7836be912ee7efe875877169 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Wed, 18 May 2022 12:00:48 +0300
Subject: [PATCH 1/4] avidemux: Fix integer overflow resulting in heap
corruption in DIB buffer inversion code
Check that width*bpp/8 doesn't overflow a guint and also that
height*stride fits into the provided buffer without overflowing.
Thanks to Adam Doupe for analyzing and reporting the issue.
CVE: CVE-2022-1921
See https://gstreamer.freedesktop.org/security/sa-2022-0001.html
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1224
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2608>
---
gst/avi/gstavidemux.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index 25c97da03e..1c87c668d0 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -4971,8 +4971,8 @@ swap_line (guint8 * d1, guint8 * d2, guint8 * tmp, gint bytes)
static GstBuffer *
gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
{
- gint y, w, h;
- gint bpp, stride;
+ guint y, w, h;
+ guint bpp, stride;
guint8 *tmp = NULL;
GstMapInfo map;
guint32 fourcc;
@@ -4999,12 +4999,23 @@ gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
h = stream->strf.vids->height;
w = stream->strf.vids->width;
bpp = stream->strf.vids->bit_cnt ? stream->strf.vids->bit_cnt : 8;
+
+ if ((guint64) w * ((guint64) bpp / 8) > G_MAXUINT - 4) {
+ GST_WARNING ("Width x stride overflows");
+ return buf;
+ }
+
+ if (w == 0 || h == 0) {
+ GST_WARNING ("Zero width or height");
+ return buf;
+ }
+
stride = GST_ROUND_UP_4 (w * (bpp / 8));
buf = gst_buffer_make_writable (buf);
gst_buffer_map (buf, &map, GST_MAP_READWRITE);
- if (map.size < (stride * h)) {
+ if (map.size < ((guint64) stride * (guint64) h)) {
GST_WARNING ("Buffer is smaller than reported Width x Height x Depth");
gst_buffer_unmap (buf, &map);
return buf;
--
2.38.1

View File

@ -0,0 +1,209 @@
From 22eb3dc56d8cb71af2c2d413ae587cc401704780 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Wed, 18 May 2022 11:24:37 +0300
Subject: [PATCH 2/4] matroskademux: Fix integer overflows in zlib/bz2/etc
decompression code
Various variables were of smaller types than needed and there were no
checks for any overflows when doing additions on the sizes. This is all
checked now.
In addition the size of the decompressed data is limited to 120MB now as
any larger sizes are likely pathological and we can avoid out of memory
situations in many cases like this.
Also fix a bug where the available output size on the next iteration in
the zlib/bz2 decompression code was provided too large and could
potentially lead to out of bound writes.
Thanks to Adam Doupe for analyzing and reporting the issue.
CVE: CVE-2022-1922, CVE-2022-1923, CVE-2022-1924, CVE-2022-1925
https://gstreamer.freedesktop.org/security/sa-2022-0002.html
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1225
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2610>
---
gst/matroska/matroska-read-common.c | 76 +++++++++++++++++++++++------
1 file changed, 61 insertions(+), 15 deletions(-)
diff --git a/gst/matroska/matroska-read-common.c b/gst/matroska/matroska-read-common.c
index 90d6e38e17..0ee9a787a4 100644
--- a/gst/matroska/matroska-read-common.c
+++ b/gst/matroska/matroska-read-common.c
@@ -70,6 +70,10 @@ typedef struct
gboolean audio_only;
} TargetTypeContext;
+/* 120MB as maximum decompressed data size. Anything bigger is likely
+ * pathological, and like this we avoid out of memory situations in many cases
+ */
+#define MAX_DECOMPRESS_SIZE (120 * 1024 * 1024)
static gboolean
gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
@@ -77,19 +81,23 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
GstMatroskaTrackCompressionAlgorithm algo)
{
guint8 *new_data = NULL;
- guint new_size = 0;
+ gsize new_size = 0;
guint8 *data = *data_out;
- guint size = *size_out;
+ const gsize size = *size_out;
gboolean ret = TRUE;
+ if (size > G_MAXUINT32) {
+ GST_WARNING ("too large compressed data buffer.");
+ ret = FALSE;
+ goto out;
+ }
+
if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
#ifdef HAVE_ZLIB
/* zlib encoded data */
z_stream zstream;
- guint orig_size;
int result;
- orig_size = size;
zstream.zalloc = (alloc_func) 0;
zstream.zfree = (free_func) 0;
zstream.opaque = (voidpf) 0;
@@ -99,8 +107,8 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
goto out;
}
zstream.next_in = (Bytef *) data;
- zstream.avail_in = orig_size;
- new_size = orig_size;
+ zstream.avail_in = size;
+ new_size = size;
new_data = g_malloc (new_size);
zstream.avail_out = new_size;
zstream.next_out = (Bytef *) new_data;
@@ -114,10 +122,18 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
break;
}
+ if (new_size > G_MAXSIZE - 4096 || new_size + 4096 > MAX_DECOMPRESS_SIZE) {
+ GST_WARNING ("too big decompressed data");
+ result = Z_MEM_ERROR;
+ break;
+ }
+
new_size += 4096;
new_data = g_realloc (new_data, new_size);
zstream.next_out = (Bytef *) (new_data + zstream.total_out);
- zstream.avail_out += 4096;
+ /* avail_out is an unsigned int */
+ g_assert (new_size - zstream.total_out <= G_MAXUINT);
+ zstream.avail_out = new_size - zstream.total_out;
} while (zstream.avail_in > 0);
if (result != Z_STREAM_END) {
@@ -137,13 +153,11 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
#ifdef HAVE_BZ2
/* bzip2 encoded data */
bz_stream bzstream;
- guint orig_size;
int result;
bzstream.bzalloc = NULL;
bzstream.bzfree = NULL;
bzstream.opaque = NULL;
- orig_size = size;
if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
GST_WARNING ("bzip2 initialization failed.");
@@ -152,8 +166,8 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
}
bzstream.next_in = (char *) data;
- bzstream.avail_in = orig_size;
- new_size = orig_size;
+ bzstream.avail_in = size;
+ new_size = size;
new_data = g_malloc (new_size);
bzstream.avail_out = new_size;
bzstream.next_out = (char *) new_data;
@@ -167,17 +181,31 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
break;
}
+ if (new_size > G_MAXSIZE - 4096 || new_size + 4096 > MAX_DECOMPRESS_SIZE) {
+ GST_WARNING ("too big decompressed data");
+ result = BZ_MEM_ERROR;
+ break;
+ }
+
new_size += 4096;
new_data = g_realloc (new_data, new_size);
- bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
- bzstream.avail_out += 4096;
+ bzstream.next_out =
+ (char *) (new_data + ((guint64) bzstream.total_out_hi32 << 32) +
+ bzstream.total_out_lo32);
+ /* avail_out is an unsigned int */
+ g_assert (new_size - ((guint64) bzstream.total_out_hi32 << 32) +
+ bzstream.total_out_lo32 <= G_MAXUINT);
+ bzstream.avail_out =
+ new_size - ((guint64) bzstream.total_out_hi32 << 32) +
+ bzstream.total_out_lo32;
} while (bzstream.avail_in > 0);
if (result != BZ_STREAM_END) {
ret = FALSE;
g_free (new_data);
} else {
- new_size = bzstream.total_out_lo32;
+ new_size =
+ ((guint64) bzstream.total_out_hi32 << 32) + bzstream.total_out_lo32;
}
BZ2_bzDecompressEnd (&bzstream);
@@ -189,7 +217,13 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
} else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
/* lzo encoded data */
int result;
- int orig_size, out_size;
+ gint orig_size, out_size;
+
+ if (size > G_MAXINT) {
+ GST_WARNING ("too large compressed data buffer.");
+ ret = FALSE;
+ goto out;
+ }
orig_size = size;
out_size = size;
@@ -203,6 +237,11 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
result = lzo1x_decode (new_data, &out_size, data, &orig_size);
if (orig_size > 0) {
+ if (new_size > G_MAXINT - 4096 || new_size + 4096 > MAX_DECOMPRESS_SIZE) {
+ GST_WARNING ("too big decompressed data");
+ result = LZO_ERROR;
+ break;
+ }
new_size += 4096;
new_data = g_realloc (new_data, new_size);
}
@@ -221,6 +260,13 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
} else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
/* header stripped encoded data */
if (enc->comp_settings_length > 0) {
+ if (size > G_MAXSIZE - enc->comp_settings_length
+ || size + enc->comp_settings_length > MAX_DECOMPRESS_SIZE) {
+ GST_WARNING ("too big decompressed data");
+ ret = FALSE;
+ goto out;
+ }
+
new_data = g_malloc (size + enc->comp_settings_length);
new_size = size + enc->comp_settings_length;
--
2.38.1

View File

@ -0,0 +1,55 @@
From 24267889a717e1e799037a0f1841d5416eb56e75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 30 May 2022 10:15:37 +0300
Subject: [PATCH 3/4] qtdemux: Fix integer overflows in zlib decompression code
Various variables were of smaller types than needed and there were no
checks for any overflows when doing additions on the sizes. This is all
checked now.
In addition the size of the decompressed data is limited to 200MB now as
any larger sizes are likely pathological and we can avoid out of memory
situations in many cases like this.
Also fix a bug where the available output size on the next iteration in
the zlib decompression code was provided too large and could
potentially lead to out of bound writes.
Thanks to Adam Doupe for analyzing and reporting the issue.
CVE: tbd
https://gstreamer.freedesktop.org/security/sa-2022-0003.html
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1225
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2610>
---
gst/isomp4/qtdemux.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 182d0bc06f..a9cbbd4cd3 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -7611,10 +7611,16 @@ qtdemux_inflate (void *z_buffer, guint z_length, guint * length)
break;
}
+ if (*length > G_MAXUINT - 4096 || *length > QTDEMUX_MAX_SAMPLE_INDEX_SIZE) {
+ GST_WARNING ("too big decompressed data");
+ ret = Z_MEM_ERROR;
+ break;
+ }
+
*length += 4096;
buffer = (guint8 *) g_realloc (buffer, *length);
z.next_out = (Bytef *) (buffer + z.total_out);
- z.avail_out += 4096;
+ z.avail_out += *length - z.total_out;
} while (z.avail_in > 0);
if (ret != Z_STREAM_END) {
--
2.38.1

View File

@ -0,0 +1,55 @@
From c0ac3357342599cc09397c6af0e696770ae94548 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Wed, 18 May 2022 10:23:15 +0300
Subject: [PATCH 4/4] matroskademux: Avoid integer-overflow resulting in heap
corruption in WavPack header handling code
blocksize + WAVPACK4_HEADER_SIZE might overflow gsize, which then
results in allocating a very small buffer. Into that buffer blocksize
data is memcpy'd later which then causes out of bound writes and can
potentially lead to anything from crashes to remote code execution.
Thanks to Adam Doupe for analyzing and reporting the issue.
CVE: CVE-2022-1920
https://gstreamer.freedesktop.org/security/sa-2022-0004.html
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1226
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2612>
---
gst/matroska/matroska-demux.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 0e47ee7b5e..b7d009de90 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -3893,7 +3893,8 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
} else {
guint8 *outdata = NULL;
gsize buf_size, size;
- guint32 block_samples, flags, crc, blocksize;
+ guint32 block_samples, flags, crc;
+ gsize blocksize;
GstAdapter *adapter;
adapter = gst_adapter_new ();
@@ -3934,6 +3935,13 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
return GST_FLOW_ERROR;
}
+ if (blocksize > G_MAXSIZE - WAVPACK4_HEADER_SIZE) {
+ GST_ERROR_OBJECT (element, "Too big wavpack buffer");
+ gst_buffer_unmap (*buf, &map);
+ g_object_unref (adapter);
+ return GST_FLOW_ERROR;
+ }
+
g_assert (newbuf == NULL);
newbuf =
--
2.38.1

View File

@ -17,7 +17,7 @@
Name: gstreamer1-plugins-good
Version: 1.18.4
Release: 5%{?gitcommit:.git%{shortcommit}}%{?dist}
Release: 6%{?gitcommit:.git%{shortcommit}}%{?dist}
Summary: GStreamer plugins with good code and licensing
License: LGPLv2+
@ -32,6 +32,11 @@ Source0: http://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugin
%endif
Patch0: %{name}-gcc11.patch
Patch1: 0001-avidemux-Fix-integer-overflow-resulting-in-heap-corr.patch
Patch2: 0002-matroskademux-Fix-integer-overflows-in-zlib-bz2-etc-.patch
Patch3: 0003-qtdemux-Fix-integer-overflows-in-zlib-decompression-.patch
Patch4: 0004-matroskademux-Avoid-integer-overflow-resulting-in-he.patch
# Register as an AppStream component to be visible in the software center
# NOTE: It would be *awesome* if this file was maintained by the upstream
# project, translated and installed into the right place during `make install`.
@ -165,6 +170,10 @@ to be installed.
%prep
%setup -q -n gst-plugins-good-%{version}
%patch0 -p2
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build
%meson \
@ -300,6 +309,12 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -fv {} ';'
%changelog
* Fri Nov 11 2022 Wim Taymans <wtaymans@redhat.com> - 1.18.4-6
- Fixes for CVE-2022-1920, CVE-2022-1921, CVE-2022-1922, CVE-2022-1923,
CVE-2022-1924, CVE-2022-1925, CVE-2022-2122
Resolves: rhbz#2131034, rhbz#2131039, rhbz#2131045, rhbz#2131049,
rhbz#2131054, rhbz#2131060, rhbz#2131064
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.18.4-5
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688