Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:GA
gstreamer-plugins-good.25486
gstreamer-CVE-2022-1922-matroska.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gstreamer-CVE-2022-1922-matroska.patch of Package gstreamer-plugins-good.25486
From ad6012159acf18c6b5c0f4edf037e8c9a2dbc966 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] 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 -urp gst-plugins-good-1.8.3.orig/gst/matroska/matroska-read-common.c gst-plugins-good-1.8.3/gst/matroska/matroska-read-common.c --- gst-plugins-good-1.8.3.orig/gst/matroska/matroska-read-common.c 2016-03-24 06:36:37.000000000 -0500 +++ gst-plugins-good-1.8.3/gst/matroska/matroska-read-common.c 2022-07-28 19:41:30.365175798 -0500 @@ -69,6 +69,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, @@ -76,19 +80,23 @@ gst_matroska_decompress_data (GstMatrosk 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; @@ -98,8 +106,8 @@ gst_matroska_decompress_data (GstMatrosk 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; @@ -112,10 +120,18 @@ gst_matroska_decompress_data (GstMatrosk inflateEnd (&zstream); break; } + if (new_size > G_MAXSIZE - 4000 || new_size + 4000 > MAX_DECOMPRESS_SIZE) { + GST_WARNING ("too big decompressed data"); + result = Z_MEM_ERROR; + break; + } + new_size += 4000; new_data = g_realloc (new_data, new_size); zstream.next_out = (Bytef *) (new_data + zstream.total_out); - zstream.avail_out += 4000; + /* 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 && result != Z_STREAM_END); if (result != Z_STREAM_END) { @@ -134,13 +150,11 @@ gst_matroska_decompress_data (GstMatrosk #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."); @@ -149,8 +163,8 @@ gst_matroska_decompress_data (GstMatrosk } 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; @@ -163,17 +177,31 @@ gst_matroska_decompress_data (GstMatrosk BZ2_bzDecompressEnd (&bzstream); break; } + if (new_size > G_MAXSIZE - 4000 || new_size + 4000 > MAX_DECOMPRESS_SIZE) { + GST_WARNING ("too big decompressed data"); + result = BZ_MEM_ERROR; + break; + } + new_size += 4000; new_data = g_realloc (new_data, new_size); - bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32); - bzstream.avail_out += 4000; + 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 && result != BZ_STREAM_END); if (result != BZ_STREAM_END) { ret = FALSE; goto out; } else { - new_size = bzstream.total_out_lo32; + new_size = + ((guint64) bzstream.total_out_hi32 << 32) + bzstream.total_out_lo32; BZ2_bzDecompressEnd (&bzstream); } #else @@ -184,7 +212,13 @@ gst_matroska_decompress_data (GstMatrosk } 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; @@ -198,6 +232,11 @@ gst_matroska_decompress_data (GstMatrosk result = lzo1x_decode (new_data, &out_size, data, &orig_size); if (orig_size > 0) { + if (new_size > G_MAXINT - 4000 || new_size + 4000 > MAX_DECOMPRESS_SIZE) { + GST_WARNING ("too big decompressed data"); + result = LZO_ERROR; + break; + } new_size += 4000; new_data = g_realloc (new_data, new_size); } @@ -216,6 +255,13 @@ gst_matroska_decompress_data (GstMatrosk } 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;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor