Compare commits

..

No commits in common. "dc7b1245f96667a8866ce72a05c76e1cb8609651" and "3c3f46750d4b9bf547eff0a9ddab9eae56c7dbe4" have entirely different histories.

32 changed files with 286 additions and 2553 deletions

View File

@ -1,54 +0,0 @@
From dbbfc917fe616ff3343a03fc8e9533d39777ce6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Tue, 13 Jun 2023 13:20:16 +0300
Subject: [PATCH 1/2] flacparse: Avoid integer overflow in available data check
for image tags
If the image length as stored in the file is some bogus integer then
adding it to the current byte readers position can overflow and wrongly
have the check for enough available data succeed.
This then later can cause NULL pointer dereferences or out of bounds
reads/writes when actually reading the image data.
Fixes ZDI-CAN-20775
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2661
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4894>
---
.../gst/audioparsers/gstflacparse.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/gst/audioparsers/gstflacparse.c b/gst/audioparsers/gstflacparse.c
index a53b7ebc776..8ee450c65ac 100644
--- a/gst/audioparsers/gstflacparse.c
+++ b/gst/audioparsers/gstflacparse.c
@@ -1111,6 +1111,7 @@ gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
GstMapInfo map;
guint32 img_len = 0, img_type = 0;
guint32 img_mimetype_len = 0, img_description_len = 0;
+ const guint8 *img_data;
gst_buffer_map (buffer, &map, GST_MAP_READ);
gst_byte_reader_init (&reader, map.data, map.size);
@@ -1137,7 +1138,7 @@ gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
goto error;
- if (gst_byte_reader_get_pos (&reader) + img_len > map.size)
+ if (!gst_byte_reader_get_data (&reader, img_len, &img_data))
goto error;
GST_INFO_OBJECT (flacparse, "Got image of %d bytes", img_len);
@@ -1146,8 +1147,7 @@ gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
if (flacparse->tags == NULL)
flacparse->tags = gst_tag_list_new_empty ();
- gst_tag_list_add_id3_image (flacparse->tags,
- map.data + gst_byte_reader_get_pos (&reader), img_len, img_type);
+ gst_tag_list_add_id3_image (flacparse->tags, img_data, img_len, img_type);
}
gst_buffer_unmap (buffer, &map);
--
GitLab

View File

@ -1,58 +0,0 @@
From ae61a604c03ca07226a88e15fdb5487ad2096add Mon Sep 17 00:00:00 2001
From: Antonio Morales <antonio-morales@github.com>
Date: Thu, 26 Sep 2024 18:39:37 +0300
Subject: [PATCH 01/12] qtdemux: Fix integer overflow when allocating the
samples table for fragmented MP4
This can lead to out of bounds writes and NULL pointer dereferences.
Fixes GHSL-2024-094, GHSL-2024-237, GHSL-2024-241
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3839
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index c2d8b5e0f134..a88dcaf2d3ef 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -3364,6 +3364,7 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
gint i;
guint8 *data;
guint entry_size, dur_offset, size_offset, flags_offset = 0, ct_offset = 0;
+ guint new_n_samples;
QtDemuxSample *sample;
gboolean ismv = FALSE;
gint64 initial_offset;
@@ -3475,14 +3476,13 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
goto fail;
data = (guint8 *) gst_byte_reader_peek_data_unchecked (trun);
- if (stream->n_samples + samples_count >=
- QTDEMUX_MAX_SAMPLE_INDEX_SIZE / sizeof (QtDemuxSample))
+ if (!g_uint_checked_add (&new_n_samples, stream->n_samples, samples_count) ||
+ new_n_samples >= QTDEMUX_MAX_SAMPLE_INDEX_SIZE / sizeof (QtDemuxSample))
goto index_too_big;
GST_DEBUG_OBJECT (qtdemux, "allocating n_samples %u * %u (%.2f MB)",
- stream->n_samples + samples_count, (guint) sizeof (QtDemuxSample),
- (stream->n_samples + samples_count) *
- sizeof (QtDemuxSample) / (1024.0 * 1024.0));
+ new_n_samples, (guint) sizeof (QtDemuxSample),
+ (new_n_samples) * sizeof (QtDemuxSample) / (1024.0 * 1024.0));
/* create a new array of samples if it's the first sample parsed */
if (stream->n_samples == 0) {
@@ -3491,7 +3491,7 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
/* or try to reallocate it with space enough to insert the new samples */
} else
stream->samples = g_try_renew (QtDemuxSample, stream->samples,
- stream->n_samples + samples_count);
+ new_n_samples);
if (stream->samples == NULL)
goto out_of_memory;
--
GitLab

View File

@ -1,39 +0,0 @@
From 1d534ac209e4042d08513f8cd448b9b12187aacd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Thu, 26 Sep 2024 09:20:28 +0300
Subject: [PATCH 05/12] qtdemux: Make sure only an even number of bytes is
processed when handling CEA608 data
An odd number of bytes would lead to out of bound reads and writes, and doesn't
make any sense as CEA608 comes in byte pairs.
Strip off any leftover bytes and assume everything before that is valid.
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-195
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3841
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index dbd42817c00b..4339943e347b 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -6145,6 +6145,11 @@ convert_to_s334_1a (const guint8 * ccpair, guint8 ccpair_size, guint field,
guint8 *storage;
gsize i;
+ /* Strip off any leftover odd bytes and assume everything before is valid */
+ if (ccpair_size % 2 != 0) {
+ ccpair_size -= 1;
+ }
+
/* We are converting from pairs to triplets */
*res = ccpair_size / 2 * 3;
storage = g_malloc (*res);
--
GitLab

View File

@ -1,51 +0,0 @@
From c0dceda8e969f74f2326539c1f0368c2fd7afcd7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 30 Sep 2024 16:32:48 +0300
Subject: [PATCH 1/7] matroskademux: Only unmap GstMapInfo in WavPack header
extraction error paths if previously mapped
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-197
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3863
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8057>
---
gst/matroska/matroska-demux.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 41725e83a607..9e0de058e64a 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -3891,7 +3891,6 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
GstMatroskaTrackAudioContext *audiocontext =
(GstMatroskaTrackAudioContext *) stream;
GstBuffer *newbuf = NULL;
- GstMapInfo map, outmap;
guint8 *buf_data, *data;
Wavpack4Header wvh;
@@ -3908,11 +3907,11 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
if (audiocontext->channels <= 2) {
guint32 block_samples, tmp;
+ GstMapInfo outmap;
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;
}
@@ -3950,6 +3949,7 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
*buf = newbuf;
audiocontext->wvpk_block_index += block_samples;
} else {
+ GstMapInfo map, outmap;
guint8 *outdata = NULL;
gsize buf_size, size;
guint32 block_samples, flags, crc;
--
GitLab

View File

@ -1,115 +0,0 @@
From c1cd838706d29cab9479e7b5e6ec63ff8ad59b61 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Thu, 26 Sep 2024 14:17:02 +0300
Subject: [PATCH 06/12] qtdemux: Make sure enough data is available before
reading wave header node
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-236
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3843
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 84 ++++++++++---------
1 file changed, 45 insertions(+), 39 deletions(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 4339943e347b..062140d3dd5f 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -13704,47 +13704,53 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
} else {
guint32 datalen = QT_UINT32 (stsd_entry_data + offset + 16);
const guint8 *data = stsd_entry_data + offset + 16;
- GNode *wavenode;
- GNode *waveheadernode;
-
- wavenode = g_node_new ((guint8 *) data);
- if (qtdemux_parse_node (qtdemux, wavenode, data, datalen)) {
- const guint8 *waveheader;
- guint32 headerlen;
-
- waveheadernode = qtdemux_tree_get_child_by_type (wavenode, fourcc);
- if (waveheadernode) {
- waveheader = (const guint8 *) waveheadernode->data;
- headerlen = QT_UINT32 (waveheader);
-
- if (headerlen > 8) {
- gst_riff_strf_auds *header = NULL;
- GstBuffer *headerbuf;
- GstBuffer *extra;
-
- waveheader += 8;
- headerlen -= 8;
-
- headerbuf = gst_buffer_new_and_alloc (headerlen);
- gst_buffer_fill (headerbuf, 0, waveheader, headerlen);
-
- if (gst_riff_parse_strf_auds (GST_ELEMENT_CAST (qtdemux),
- headerbuf, &header, &extra)) {
- gst_caps_unref (entry->caps);
- /* FIXME: Need to do something with the channel reorder map */
- entry->caps =
- gst_riff_create_audio_caps (header->format, NULL, header,
- extra, NULL, NULL, NULL);
-
- if (extra)
- gst_buffer_unref (extra);
- g_free (header);
+
+ if (len < datalen || len - datalen < offset + 16) {
+ GST_WARNING_OBJECT (qtdemux, "Not enough data for waveheadernode");
+ } else {
+ GNode *wavenode;
+ GNode *waveheadernode;
+
+ wavenode = g_node_new ((guint8 *) data);
+ if (qtdemux_parse_node (qtdemux, wavenode, data, datalen)) {
+ const guint8 *waveheader;
+ guint32 headerlen;
+
+ waveheadernode =
+ qtdemux_tree_get_child_by_type (wavenode, fourcc);
+ if (waveheadernode) {
+ waveheader = (const guint8 *) waveheadernode->data;
+ headerlen = QT_UINT32 (waveheader);
+
+ if (headerlen > 8) {
+ gst_riff_strf_auds *header = NULL;
+ GstBuffer *headerbuf;
+ GstBuffer *extra;
+
+ waveheader += 8;
+ headerlen -= 8;
+
+ headerbuf = gst_buffer_new_and_alloc (headerlen);
+ gst_buffer_fill (headerbuf, 0, waveheader, headerlen);
+
+ if (gst_riff_parse_strf_auds (GST_ELEMENT_CAST (qtdemux),
+ headerbuf, &header, &extra)) {
+ gst_caps_unref (entry->caps);
+ /* FIXME: Need to do something with the channel reorder map */
+ entry->caps =
+ gst_riff_create_audio_caps (header->format, NULL,
+ header, extra, NULL, NULL, NULL);
+
+ if (extra)
+ gst_buffer_unref (extra);
+ g_free (header);
+ }
}
- }
- } else
- GST_DEBUG ("Didn't find waveheadernode for this codec");
+ } else
+ GST_DEBUG ("Didn't find waveheadernode for this codec");
+ }
+ g_node_destroy (wavenode);
}
- g_node_destroy (wavenode);
}
} else if (esds) {
gst_qtdemux_handle_esds (qtdemux, stream, entry, esds,
--
GitLab

View File

@ -1,49 +0,0 @@
Backport of:
From 8e884e4e31649a9fc19095d6501a1143b074aba8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 27 Sep 2024 09:47:50 +0300
Subject: [PATCH] qtdemux: Fix error handling when parsing cenc sample groups
fails
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-238, GHSL-2024-239, GHSL-2024-240
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3846
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8060>
---
.../gst-plugins-good/gst/isomp4/qtdemux.c | 25 ++++++++++++++-----
1 file changed, 19 insertions(+), 6 deletions(-)
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -11090,12 +11090,15 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
if (stream->subtype != FOURCC_soun) {
GST_ERROR_OBJECT (qtdemux,
"Unexpeced stsd type 'aavd' outside 'soun' track");
+ goto corrupt_file;
} else {
/* encrypted audio with sound sample description v0 */
GNode *enc = qtdemux_tree_get_child_by_type (stsd, fourcc);
stream->protected = TRUE;
- if (!qtdemux_parse_protection_aavd (qtdemux, stream, enc, &fourcc))
+ if (!qtdemux_parse_protection_aavd (qtdemux, stream, enc, &fourcc)) {
GST_ERROR_OBJECT (qtdemux, "Failed to parse protection scheme info");
+ goto corrupt_file;
+ }
}
}
@@ -11104,8 +11107,10 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
* with the same type */
GNode *enc = qtdemux_tree_get_child_by_type (stsd, fourcc);
stream->protected = TRUE;
- if (!qtdemux_parse_protection_scheme_info (qtdemux, stream, enc, &fourcc))
+ if (!qtdemux_parse_protection_scheme_info (qtdemux, stream, enc, &fourcc)) {
GST_ERROR_OBJECT (qtdemux, "Failed to parse protection scheme info");
+ goto corrupt_file;
+ }
}
if (stream->subtype == FOURCC_vide) {

View File

@ -1,243 +0,0 @@
From fd96fc23c53dcd95becfcca06d471e92923265ab Mon Sep 17 00:00:00 2001
From: Justin Chadwell <me@jedevc.com>
Date: Wed, 2 Sep 2020 10:49:40 +0100
Subject: [PATCH] qtdemux: use unsigned int types to store result of QT_UINT32
In a few cases throughout qtdemux, the results of QT_UINT32 were being
stored in a signed integer, which could cause subtle bugs in the case of
an integer overflow, even allowing the the result to equal a negative
number!
This patch prevents this by simply storing the results of this function
call properly in an unsigned integer type. Additionally, we fix up the
length checking with stsd parsing to prevent cases of child atoms
exceeding their parent atom sizes.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3344>
---
.../gst-plugins-good/gst/isomp4/qtdemux.c | 76 ++++++++++++-------
1 file changed, 47 insertions(+), 29 deletions(-)
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -10074,8 +10074,8 @@ qtdemux_parse_segments (GstQTDemux * qtd
stream->segments = NULL;
if ((edts = qtdemux_tree_get_child_by_type (trak, FOURCC_edts))) {
GNode *elst;
- gint n_segments;
- gint segment_number, entry_size;
+ guint n_segments;
+ guint segment_number, entry_size;
guint64 time;
GstClockTime stime;
const guint8 *buffer;
@@ -10783,7 +10783,7 @@ qtdemux_parse_stereo_svmi_atom (GstQTDem
/*parse svmi header if existing */
svmi = qtdemux_tree_get_child_by_type (stbl, FOURCC_svmi);
if (svmi) {
- guint len = QT_UINT32 ((guint8 *) svmi->data);
+ guint32 len = QT_UINT32 ((guint8 *) svmi->data);
guint32 version = QT_UINT32 ((guint8 *) svmi->data + 8);
if (!version) {
GstVideoMultiviewMode mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
@@ -11190,7 +11190,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
break;
}
} else {
- gint i, j, start, end;
+ guint i, j, start, end;
if (len < 94)
goto corrupt_file;
@@ -11306,7 +11306,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
if (pasp) {
const guint8 *pasp_data = (const guint8 *) pasp->data;
- gint len = QT_UINT32 (pasp_data);
+ guint len = QT_UINT32 (pasp_data);
if (len == 16) {
CUR_STREAM (stream)->par_w = QT_UINT32 (pasp_data + 8);
@@ -11322,7 +11322,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
if (fiel) {
const guint8 *fiel_data = (const guint8 *) fiel->data;
- gint len = QT_UINT32 (fiel_data);
+ guint len = QT_UINT32 (fiel_data);
if (len == 10) {
CUR_STREAM (stream)->interlace_mode = GST_READ_UINT8 (fiel_data + 8);
@@ -11332,7 +11332,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
if (colr) {
const guint8 *colr_data = (const guint8 *) colr->data;
- gint len = QT_UINT32 (colr_data);
+ guint len = QT_UINT32 (colr_data);
if (len == 19 || len == 18) {
guint32 color_type = GST_READ_UINT32_LE (colr_data + 8);
@@ -11369,14 +11369,17 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
case FOURCC_avc1:
case FOURCC_avc3:
{
- gint len = QT_UINT32 (stsd_entry_data) - 0x56;
+ guint len = QT_UINT32 (stsd_entry_data);
+ len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *avc_data = stsd_entry_data + 0x56;
/* find avcC */
while (len >= 0x8) {
- gint size;
+ guint size;
- if (QT_UINT32 (avc_data) <= len)
+ if (QT_UINT32 (avc_data) <= 0x8)
+ size = 0;
+ else if (QT_UINT32 (avc_data) <= len)
size = QT_UINT32 (avc_data) - 0x8;
else
size = len - 0x8;
@@ -11483,14 +11486,17 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
case FOURCC_dvh1:
case FOURCC_dvhe:
{
- gint len = QT_UINT32 (stsd_entry_data) - 0x56;
+ guint len = QT_UINT32 (stsd_entry_data);
+ len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *hevc_data = stsd_entry_data + 0x56;
/* find hevc */
while (len >= 0x8) {
- gint size;
+ guint size;
- if (QT_UINT32 (hevc_data) <= len)
+ if (QT_UINT32 (hevc_data) <= 0x8)
+ size = 0;
+ else if (QT_UINT32 (hevc_data) <= len)
size = QT_UINT32 (hevc_data) - 0x8;
else
size = len - 0x8;
@@ -11546,7 +11552,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
if (glbl) {
guint8 *data;
GstBuffer *buf;
- gint len;
+ guint len;
GST_DEBUG_OBJECT (qtdemux, "found glbl data in stsd");
data = glbl->data;
@@ -11730,7 +11736,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
/* add codec_data if provided */
if (prefix) {
GstBuffer *buf;
- gint len;
+ guint len;
GST_DEBUG_OBJECT (qtdemux, "found prefix data in stsd");
data = prefix->data;
@@ -11752,7 +11758,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
GstBuffer *buf;
GstBuffer *seqh = NULL;
const guint8 *gamma_data = NULL;
- gint len = QT_UINT32 (stsd_data); /* FIXME review - why put the whole stsd in codec data? */
+ guint len = QT_UINT32 (stsd_data); /* FIXME review - why put the whole stsd in codec data? */
qtdemux_parse_svq3_stsd_data (qtdemux, stsd_entry_data, &gamma_data,
&seqh);
@@ -11904,14 +11910,17 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
}
case FOURCC_vc_1:
{
- gint len = QT_UINT32 (stsd_entry_data) - 0x56;
+ guint len = QT_UINT32 (stsd_entry_data);
+ len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *vc1_data = stsd_entry_data + 0x56;
/* find dvc1 */
while (len >= 8) {
- gint size;
+ guint size;
- if (QT_UINT32 (vc1_data) <= len)
+ if (QT_UINT32 (vc1_data) <= 8)
+ size = 0;
+ else if (QT_UINT32 (vc1_data) <= len)
size = QT_UINT32 (vc1_data) - 8;
else
size = len - 8;
@@ -11943,14 +11952,17 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
}
case FOURCC_av01:
{
- gint len = QT_UINT32 (stsd_entry_data) - 0x56;
+ guint len = QT_UINT32 (stsd_entry_data);
+ len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *av1_data = stsd_entry_data + 0x56;
/* find av1C */
while (len >= 0x8) {
- gint size;
+ guint size;
- if (QT_UINT32 (av1_data) <= len)
+ if (QT_UINT32 (av1_data) <= 0x8)
+ size = 0;
+ else if (QT_UINT32 (av1_data) <= len)
size = QT_UINT32 (av1_data) - 0x8;
else
size = len - 0x8;
@@ -12022,14 +12034,17 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
* vp08, vp09, and vp10 fourcc. */
case FOURCC_vp09:
{
- gint len = QT_UINT32 (stsd_entry_data) - 0x56;
+ guint len = QT_UINT32 (stsd_entry_data);
+ len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *vpcc_data = stsd_entry_data + 0x56;
/* find vpcC */
while (len >= 0x8) {
- gint size;
+ guint size;
- if (QT_UINT32 (vpcc_data) <= len)
+ if (QT_UINT32 (vpcc_data) <= 0x8)
+ size = 0;
+ else if (QT_UINT32 (vpcc_data) <= len)
size = QT_UINT32 (vpcc_data) - 0x8;
else
size = len - 0x8;
@@ -12177,7 +12192,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
} else if (stream->subtype == FOURCC_soun) {
GNode *wave;
- int version, samplesize;
+ guint version, samplesize;
guint16 compression_id;
gboolean amrwb = FALSE;
@@ -12492,7 +12507,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
}
case FOURCC_wma_:
{
- gint len = QT_UINT32 (stsd_entry_data) - offset;
+ guint len = QT_UINT32 (stsd_entry_data);
+ len = len <= offset ? 0 : len - offset;
const guint8 *wfex_data = stsd_entry_data + offset;
const gchar *codec_name = NULL;
gint version = 1;
@@ -12516,9 +12532,11 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
/* find wfex */
while (len >= 8) {
- gint size;
+ guint size;
- if (QT_UINT32 (wfex_data) <= len)
+ if (QT_UINT32 (wfex_data) <= 0x8)
+ size = 0;
+ else if (QT_UINT32 (wfex_data) <= len)
size = QT_UINT32 (wfex_data) - 8;
else
size = len - 8;

View File

@ -1,116 +0,0 @@
From d4bab55077c6a77bd80cb12a8b0d28020ef412a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Tue, 24 Sep 2024 09:50:34 +0300
Subject: [PATCH] qtdemux: Skip zero-sized boxes instead of stopping to look at
further boxes
A zero-sized box is not really a problem and can be skipped to look at any
possibly following ones.
BMD ATEM devices specifically write a zero-sized bmdc box in the sample
description, followed by the avcC box in case of h264. Previously the avcC box
would simply not be read at all and the file would be unplayable.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7564>
---
.../gst-plugins-good/gst/isomp4/qtdemux.c | 54 ++++++++++++-------
1 file changed, 36 insertions(+), 18 deletions(-)
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -11384,9 +11384,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
else
size = len - 0x8;
- if (size < 1)
- /* No real data, so break out */
- break;
+ /* No real data, so skip */
+ if (size < 1) {
+ len -= 8;
+ avc_data += 8;
+ continue;
+ }
switch (QT_FOURCC (avc_data + 0x4)) {
case FOURCC_avcC:
@@ -11501,9 +11504,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
else
size = len - 0x8;
- if (size < 1)
- /* No real data, so break out */
- break;
+ /* No real data, so skip */
+ if (size < 1) {
+ len -= 8;
+ hevc_data += 8;
+ continue;
+ }
switch (QT_FOURCC (hevc_data + 0x4)) {
case FOURCC_hvcC:
@@ -11925,9 +11931,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
else
size = len - 8;
- if (size < 1)
- /* No real data, so break out */
- break;
+ /* No real data, so skip */
+ if (size < 1) {
+ len -= 8;
+ vc1_data += 8;
+ continue;
+ }
switch (QT_FOURCC (vc1_data + 0x4)) {
case GST_MAKE_FOURCC ('d', 'v', 'c', '1'):
@@ -11967,9 +11976,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
else
size = len - 0x8;
- if (size < 1)
- /* No real data, so break out */
- break;
+ /* No real data, so skip */
+ if (size < 1) {
+ len -= 8;
+ av1_data += 8;
+ continue;
+ }
switch (QT_FOURCC (av1_data + 0x4)) {
case FOURCC_av1C:
@@ -12049,9 +12061,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
else
size = len - 0x8;
- if (size < 1)
- /* No real data, so break out */
- break;
+ /* No real data, so skip */
+ if (size < 1) {
+ len -= 8;
+ vpcc_data += 8;
+ continue;
+ }
switch (QT_FOURCC (vpcc_data + 0x4)) {
case FOURCC_vpcC:
@@ -12541,9 +12556,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
else
size = len - 8;
- if (size < 1)
- /* No real data, so break out */
- break;
+ /* No real data, so skip */
+ if (size < 1) {
+ len -= 8;
+ wfex_data += 8;
+ continue;
+ }
switch (QT_FOURCC (wfex_data + 4)) {
case GST_MAKE_FOURCC ('w', 'f', 'e', 'x'):

View File

@ -1,444 +0,0 @@
Backport of:
From fe9d5d37234aca04fef7248184177168905a7a69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 27 Sep 2024 00:12:57 +0300
Subject: [PATCH] qtdemux: Fix length checks and offsets in stsd entry parsing
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-242
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3845
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8060>
---
.../gst-plugins-good/gst/isomp4/qtdemux.c | 218 +++++++-----------
1 file changed, 79 insertions(+), 139 deletions(-)
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -11369,43 +11369,35 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
case FOURCC_avc1:
case FOURCC_avc3:
{
- guint len = QT_UINT32 (stsd_entry_data);
+ guint32 len = QT_UINT32 (stsd_entry_data);
len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *avc_data = stsd_entry_data + 0x56;
/* find avcC */
- while (len >= 0x8) {
- guint size;
+ while (len >= 8) {
+ guint32 size = QT_UINT32 (avc_data);
- if (QT_UINT32 (avc_data) <= 0x8)
- size = 0;
- else if (QT_UINT32 (avc_data) <= len)
- size = QT_UINT32 (avc_data) - 0x8;
- else
- size = len - 0x8;
-
- /* No real data, so skip */
- if (size < 1) {
- len -= 8;
- avc_data += 8;
- continue;
- }
+ if (size < 8 || size > len)
+ break;
- switch (QT_FOURCC (avc_data + 0x4)) {
+ switch (QT_FOURCC (avc_data + 4)) {
case FOURCC_avcC:
{
/* parse, if found */
GstBuffer *buf;
+ if (size < 8 + 1)
+ break;
+
GST_DEBUG_OBJECT (qtdemux, "found avcC codec_data in stsd");
/* First 4 bytes are the length of the atom, the next 4 bytes
* are the fourcc, the next 1 byte is the version, and the
* subsequent bytes are profile_tier_level structure like data. */
gst_codec_utils_h264_caps_set_level_and_profile (entry->caps,
- avc_data + 8 + 1, size - 1);
- buf = gst_buffer_new_and_alloc (size);
- gst_buffer_fill (buf, 0, avc_data + 0x8, size);
+ avc_data + 8 + 1, size - 8 - 1);
+ buf = gst_buffer_new_and_alloc (size - 8);
+ gst_buffer_fill (buf, 0, avc_data + 8, size - 8);
gst_caps_set_simple (entry->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
@@ -11416,6 +11408,9 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
{
GstBuffer *buf;
+ if (size < 8 + 40 + 1)
+ break;
+
GST_DEBUG_OBJECT (qtdemux, "found strf codec_data in stsd");
/* First 4 bytes are the length of the atom, the next 4 bytes
@@ -11423,17 +11418,14 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
* next 1 byte is the version, and the
* subsequent bytes are sequence parameter set like data. */
- size -= 40; /* we'll be skipping BITMAPINFOHEADER */
- if (size > 1) {
- gst_codec_utils_h264_caps_set_level_and_profile
- (entry->caps, avc_data + 8 + 40 + 1, size - 1);
+ gst_codec_utils_h264_caps_set_level_and_profile
+ (entry->caps, avc_data + 8 + 40 + 1, size - 8 - 40 - 1);
- buf = gst_buffer_new_and_alloc (size);
- gst_buffer_fill (buf, 0, avc_data + 8 + 40, size);
- gst_caps_set_simple (entry->caps,
- "codec_data", GST_TYPE_BUFFER, buf, NULL);
- gst_buffer_unref (buf);
- }
+ buf = gst_buffer_new_and_alloc (size - 8 - 40);
+ gst_buffer_fill (buf, 0, avc_data + 8 + 40, size - 8 - 40);
+ gst_caps_set_simple (entry->caps,
+ "codec_data", GST_TYPE_BUFFER, buf, NULL);
+ gst_buffer_unref (buf);
break;
}
case FOURCC_btrt:
@@ -11441,11 +11433,11 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
guint avg_bitrate, max_bitrate;
/* bufferSizeDB, maxBitrate and avgBitrate - 4 bytes each */
- if (size < 12)
+ if (size < 8 + 12)
break;
- max_bitrate = QT_UINT32 (avc_data + 0xc);
- avg_bitrate = QT_UINT32 (avc_data + 0x10);
+ max_bitrate = QT_UINT32 (avc_data + 8 + 4);
+ avg_bitrate = QT_UINT32 (avc_data + 8 + 8);
if (!max_bitrate && !avg_bitrate)
break;
@@ -11477,8 +11469,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
break;
}
- len -= size + 8;
- avc_data += size + 8;
+ len -= size;
+ avc_data += size;
}
break;
@@ -11489,44 +11481,36 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
case FOURCC_dvh1:
case FOURCC_dvhe:
{
- guint len = QT_UINT32 (stsd_entry_data);
+ guint32 len = QT_UINT32 (stsd_entry_data);
len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *hevc_data = stsd_entry_data + 0x56;
/* find hevc */
- while (len >= 0x8) {
- guint size;
+ while (len >= 8) {
+ guint32 size = QT_UINT32 (hevc_data);
- if (QT_UINT32 (hevc_data) <= 0x8)
- size = 0;
- else if (QT_UINT32 (hevc_data) <= len)
- size = QT_UINT32 (hevc_data) - 0x8;
- else
- size = len - 0x8;
-
- /* No real data, so skip */
- if (size < 1) {
- len -= 8;
- hevc_data += 8;
- continue;
- }
+ if (size < 8 || size > len)
+ break;
- switch (QT_FOURCC (hevc_data + 0x4)) {
+ switch (QT_FOURCC (hevc_data + 4)) {
case FOURCC_hvcC:
{
/* parse, if found */
GstBuffer *buf;
+ if (size < 8 + 1)
+ break;
+
GST_DEBUG_OBJECT (qtdemux, "found hvcC codec_data in stsd");
/* First 4 bytes are the length of the atom, the next 4 bytes
* are the fourcc, the next 1 byte is the version, and the
* subsequent bytes are sequence parameter set like data. */
gst_codec_utils_h265_caps_set_level_tier_and_profile
- (entry->caps, hevc_data + 8 + 1, size - 1);
+ (entry->caps, hevc_data + 8 + 1, size - 8 - 1);
- buf = gst_buffer_new_and_alloc (size);
- gst_buffer_fill (buf, 0, hevc_data + 0x8, size);
+ buf = gst_buffer_new_and_alloc (size - 8);
+ gst_buffer_fill (buf, 0, hevc_data + 8, size - 8);
gst_caps_set_simple (entry->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
@@ -11535,8 +11519,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
default:
break;
}
- len -= size + 8;
- hevc_data += size + 8;
+ len -= size;
+ hevc_data += size;
}
break;
}
@@ -11916,36 +11900,25 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
}
case FOURCC_vc_1:
{
- guint len = QT_UINT32 (stsd_entry_data);
+ guint32 len = QT_UINT32 (stsd_entry_data);
len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *vc1_data = stsd_entry_data + 0x56;
/* find dvc1 */
while (len >= 8) {
- guint size;
+ guint32 size = QT_UINT32 (vc1_data);
- if (QT_UINT32 (vc1_data) <= 8)
- size = 0;
- else if (QT_UINT32 (vc1_data) <= len)
- size = QT_UINT32 (vc1_data) - 8;
- else
- size = len - 8;
-
- /* No real data, so skip */
- if (size < 1) {
- len -= 8;
- vc1_data += 8;
- continue;
- }
+ if (size < 8 || size > len)
+ break;
- switch (QT_FOURCC (vc1_data + 0x4)) {
+ switch (QT_FOURCC (vc1_data + 4)) {
case GST_MAKE_FOURCC ('d', 'v', 'c', '1'):
{
GstBuffer *buf;
GST_DEBUG_OBJECT (qtdemux, "found dvc1 codec_data in stsd");
- buf = gst_buffer_new_and_alloc (size);
- gst_buffer_fill (buf, 0, vc1_data + 8, size);
+ buf = gst_buffer_new_and_alloc (size - 8);
+ gst_buffer_fill (buf, 0, vc1_data + 8, size - 8);
gst_caps_set_simple (entry->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
@@ -11954,36 +11927,25 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
default:
break;
}
- len -= size + 8;
- vc1_data += size + 8;
+ len -= size;
+ vc1_data += size;
}
break;
}
case FOURCC_av01:
{
- guint len = QT_UINT32 (stsd_entry_data);
+ guint32 len = QT_UINT32 (stsd_entry_data);
len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *av1_data = stsd_entry_data + 0x56;
/* find av1C */
- while (len >= 0x8) {
- guint size;
+ while (len >= 8) {
+ guint32 size = QT_UINT32 (av1_data);
- if (QT_UINT32 (av1_data) <= 0x8)
- size = 0;
- else if (QT_UINT32 (av1_data) <= len)
- size = QT_UINT32 (av1_data) - 0x8;
- else
- size = len - 0x8;
-
- /* No real data, so skip */
- if (size < 1) {
- len -= 8;
- av1_data += 8;
- continue;
- }
+ if (size < 8 || size > len)
+ break;
- switch (QT_FOURCC (av1_data + 0x4)) {
+ switch (QT_FOURCC (av1_data + 4)) {
case FOURCC_av1C:
{
/* parse, if found */
@@ -11994,7 +11956,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
"found av1C codec_data in stsd of size %d", size);
/* not enough data, just ignore and hope for the best */
- if (size < 5)
+ if (size < 8 + 5)
break;
/* Content is:
@@ -12020,10 +11982,10 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
"presentation-delay", G_TYPE_INT,
(gint) (pres_delay_field & 0x0F) + 1, NULL);
}
- if (size > 5) {
- buf = gst_buffer_new_and_alloc (size - 5);
+ if (size > 8 + 5) {
+ buf = gst_buffer_new_and_alloc (size - 8 - 5);
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
- gst_buffer_fill (buf, 0, av1_data + 13, size - 5);
+ gst_buffer_fill (buf, 0, av1_data + 13, size - 8 - 5);
gst_caps_set_simple (entry->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
@@ -12034,8 +11996,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
break;
}
- len -= size + 8;
- av1_data += size + 8;
+ len -= size;
+ av1_data += size;
}
break;
@@ -12046,29 +12008,18 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
* vp08, vp09, and vp10 fourcc. */
case FOURCC_vp09:
{
- guint len = QT_UINT32 (stsd_entry_data);
+ guint32 len = QT_UINT32 (stsd_entry_data);
len = len <= 0x56 ? 0 : len - 0x56;
const guint8 *vpcc_data = stsd_entry_data + 0x56;
/* find vpcC */
- while (len >= 0x8) {
- guint size;
+ while (len >= 8) {
+ guint32 size = QT_UINT32 (vpcc_data);
- if (QT_UINT32 (vpcc_data) <= 0x8)
- size = 0;
- else if (QT_UINT32 (vpcc_data) <= len)
- size = QT_UINT32 (vpcc_data) - 0x8;
- else
- size = len - 0x8;
-
- /* No real data, so skip */
- if (size < 1) {
- len -= 8;
- vpcc_data += 8;
- continue;
- }
+ if (size < 8 || size > len)
+ break;
- switch (QT_FOURCC (vpcc_data + 0x4)) {
+ switch (QT_FOURCC (vpcc_data + 4)) {
case FOURCC_vpcC:
{
const gchar *profile_str = NULL;
@@ -12084,7 +12035,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
/* the meaning of "size" is length of the atom body, excluding
* atom length and fourcc fields */
- if (size < 12)
+ if (size < 8 + 12)
break;
/* Content is:
@@ -12190,8 +12141,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
break;
}
- len -= size + 8;
- vpcc_data += size + 8;
+ len -= size;
+ vpcc_data += size;
}
break;
@@ -12522,7 +12473,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
}
case FOURCC_wma_:
{
- guint len = QT_UINT32 (stsd_entry_data);
+ guint32 len = QT_UINT32 (stsd_entry_data);
len = len <= offset ? 0 : len - offset;
const guint8 *wfex_data = stsd_entry_data + offset;
const gchar *codec_name = NULL;
@@ -12547,21 +12498,10 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
/* find wfex */
while (len >= 8) {
- guint size;
+ guint32 size = QT_UINT32 (wfex_data);
- if (QT_UINT32 (wfex_data) <= 0x8)
- size = 0;
- else if (QT_UINT32 (wfex_data) <= len)
- size = QT_UINT32 (wfex_data) - 8;
- else
- size = len - 8;
-
- /* No real data, so skip */
- if (size < 1) {
- len -= 8;
- wfex_data += 8;
- continue;
- }
+ if (size < 8 || size > len)
+ break;
switch (QT_FOURCC (wfex_data + 4)) {
case GST_MAKE_FOURCC ('w', 'f', 'e', 'x'):
@@ -12606,12 +12546,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
"width", G_TYPE_INT, wfex.wBitsPerSample,
"depth", G_TYPE_INT, wfex.wBitsPerSample, NULL);
- if (size > wfex.cbSize) {
+ if (size > 8 + wfex.cbSize) {
GstBuffer *buf;
- buf = gst_buffer_new_and_alloc (size - wfex.cbSize);
+ buf = gst_buffer_new_and_alloc (size - 8 - wfex.cbSize);
gst_buffer_fill (buf, 0, wfex_data + 8 + wfex.cbSize,
- size - wfex.cbSize);
+ size - 8 - wfex.cbSize);
gst_caps_set_simple (entry->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
@@ -12628,8 +12568,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux
default:
break;
}
- len -= size + 8;
- wfex_data += size + 8;
+ len -= size;
+ wfex_data += size;
}
break;
}

View File

@ -1,32 +0,0 @@
From bfebca8307ae79223616fd27e8b402118787d394 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Thu, 26 Sep 2024 19:16:19 +0300
Subject: [PATCH 11/12] qtdemux: Check for invalid atom length when extracting
Closed Caption data
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-243
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3849
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 4b9ce20ad37b..7731b2c2c93b 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -6193,7 +6193,7 @@ extract_cc_from_data (QtDemuxStream * stream, const guint8 * data, gsize size,
goto invalid_cdat;
atom_length = QT_UINT32 (data);
fourcc = QT_FOURCC (data + 4);
- if (G_UNLIKELY (atom_length > size || atom_length == 8))
+ if (G_UNLIKELY (atom_length > size || atom_length <= 8))
goto invalid_cdat;
GST_DEBUG_OBJECT (stream->pad, "here");
--
GitLab

View File

@ -1,33 +0,0 @@
From 519d86d9f36d80eb64148cd2d330b28a28be2755 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 27 Sep 2024 00:31:36 +0300
Subject: [PATCH 12/12] qtdemux: Add size check for parsing SMI / SEQH atom
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-244
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3853
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 7731b2c2c93b..5422e9f1d6f8 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -11198,8 +11198,9 @@ qtdemux_parse_svq3_stsd_data (GstQTDemux * qtdemux,
GST_WARNING_OBJECT (qtdemux, "Unexpected second SEQH SMI atom "
" found, ignoring");
} else {
+ /* Note: The size does *not* include the fourcc and the size field itself */
seqh_size = QT_UINT32 (data + 4);
- if (seqh_size > 0) {
+ if (seqh_size > 0 && seqh_size <= size - 8) {
_seqh = gst_buffer_new_and_alloc (seqh_size);
gst_buffer_fill (_seqh, 0, data + 8, seqh_size);
}
--
GitLab

View File

@ -1,44 +0,0 @@
From 19359e2b2548927cbfd46a526d704cce5a65c2b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 27 Sep 2024 10:38:50 +0300
Subject: [PATCH 09/12] qtdemux: Make sure there are enough offsets to read
when parsing samples
While this specific case is also caught when initializing co_chunk, the error
is ignored in various places and calling into the function would lead to out of
bounds reads if the error message doesn't cause the pipeline to be shut down
fast enough.
To avoid this, no matter what, make sure enough offsets are available when
parsing them. While this is potentially slower, the same is already done in the
non-chunks_are_samples case.
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-245
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3847
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 127ed77f6dba..07272f38c421 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -10635,9 +10635,9 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, guint32 n)
goto done;
}
- cur->offset =
- qt_atom_parser_get_offset_unchecked (&stream->co_chunk,
- stream->co_size);
+ if (!qt_atom_parser_get_offset (&stream->co_chunk,
+ stream->co_size, &cur->offset))
+ goto corrupt_file;
GST_LOG_OBJECT (qtdemux, "Created entry %d with offset "
"%" G_GUINT64_FORMAT, j, cur->offset);
--
GitLab

View File

@ -1,93 +0,0 @@
From 7d3f221d8795cd6910f375774a50ffe7c19d0538 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 27 Sep 2024 10:39:30 +0300
Subject: [PATCH 10/12] qtdemux: Actually handle errors returns from various
functions instead of ignoring them
Ignoring them might cause the element to continue as if all is fine despite the
internal state being inconsistent. This can lead to all kinds of follow-up
issues, including memory safety issues.
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-245
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3847
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index ba80392..f5ea797 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -4657,10 +4657,15 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
beach:
if (ret == GST_FLOW_EOS && (qtdemux->got_moov || qtdemux->media_caps)) {
/* digested all data, show what we have */
- qtdemux_prepare_streams (qtdemux);
+ ret = qtdemux_prepare_streams (qtdemux);
+ if (ret != GST_FLOW_OK)
+ return ret;
+
QTDEMUX_EXPOSE_LOCK (qtdemux);
ret = qtdemux_expose_streams (qtdemux);
QTDEMUX_EXPOSE_UNLOCK (qtdemux);
+ if (ret != GST_FLOW_OK)
+ return ret;
qtdemux->state = QTDEMUX_STATE_MOVIE;
GST_DEBUG_OBJECT (qtdemux, "switching state to STATE_MOVIE (%d)",
@@ -7275,13 +7280,21 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
gst_qtdemux_stream_concat (demux,
demux->old_streams, demux->active_streams);
- qtdemux_parse_moov (demux, data, demux->neededbytes);
+ if (!qtdemux_parse_moov (demux, data, demux->neededbytes)) {
+ ret = GST_FLOW_ERROR;
+ break;
+ }
qtdemux_node_dump (demux, demux->moov_node);
qtdemux_parse_tree (demux);
- qtdemux_prepare_streams (demux);
+ ret = qtdemux_prepare_streams (demux);
+ if (ret != GST_FLOW_OK)
+ break;
+
QTDEMUX_EXPOSE_LOCK (demux);
- qtdemux_expose_streams (demux);
+ ret = qtdemux_expose_streams (demux);
QTDEMUX_EXPOSE_UNLOCK (demux);
+ if (ret != GST_FLOW_OK)
+ break;
demux->got_moov = TRUE;
@@ -7372,8 +7385,10 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
/* in MSS we need to expose the pads after the first moof as we won't get a moov */
if (demux->mss_mode && !demux->exposed) {
QTDEMUX_EXPOSE_LOCK (demux);
- qtdemux_expose_streams (demux);
+ ret = qtdemux_expose_streams (demux);
QTDEMUX_EXPOSE_UNLOCK (demux);
+ if (ret != GST_FLOW_OK)
+ goto done;
}
gst_qtdemux_check_send_pending_segment (demux);
@@ -13350,8 +13365,10 @@ qtdemux_prepare_streams (GstQTDemux * qtdemux)
/* parse the initial sample for use in setting the frame rate cap */
while (sample_num == 0 && sample_num < stream->n_samples) {
- if (!qtdemux_parse_samples (qtdemux, stream, sample_num))
+ if (!qtdemux_parse_samples (qtdemux, stream, sample_num)) {
+ ret = GST_FLOW_ERROR;
break;
+ }
++sample_num;
}
}
--
2.33.0

View File

@ -1,58 +0,0 @@
From 5a9e80c01b4b49c6c7630a6d08b600114f38c0db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 27 Sep 2024 15:50:54 +0300
Subject: [PATCH 04/12] qtdemux: Check sizes of stsc/stco/stts before trying to
merge entries
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-246
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3854
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 52d5a35c0ba0..dbd42817c00b 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -10040,6 +10040,21 @@ qtdemux_merge_sample_table (GstQTDemux * qtdemux, QtDemuxStream * stream)
return;
}
+ if (gst_byte_reader_get_remaining (&stream->stts) < 8) {
+ GST_DEBUG_OBJECT (qtdemux, "Too small stts");
+ return;
+ }
+
+ if (stream->stco.size < 8) {
+ GST_DEBUG_OBJECT (qtdemux, "Too small stco");
+ return;
+ }
+
+ if (stream->n_samples_per_chunk == 0) {
+ GST_DEBUG_OBJECT (qtdemux, "No samples per chunk");
+ return;
+ }
+
/* Parse the stts to get the sample duration and number of samples */
gst_byte_reader_skip_unchecked (&stream->stts, 4);
stts_duration = gst_byte_reader_get_uint32_be_unchecked (&stream->stts);
@@ -10051,6 +10066,13 @@ qtdemux_merge_sample_table (GstQTDemux * qtdemux, QtDemuxStream * stream)
GST_DEBUG_OBJECT (qtdemux, "sample_duration %d, num_chunks %u", stts_duration,
num_chunks);
+ if (gst_byte_reader_get_remaining (&stream->stsc) <
+ stream->n_samples_per_chunk * 3 * 4 +
+ (stream->n_samples_per_chunk - 1) * 4) {
+ GST_DEBUG_OBJECT (qtdemux, "Too small stsc");
+ return;
+ }
+
/* Now parse stsc, convert chunks into single samples and generate a
* new stsc, stts and stsz from this information */
gst_byte_writer_init (&stsc);
--
GitLab

View File

@ -1,95 +0,0 @@
From 3cdf206f4fc5a9860bfe1437ed3d01e7d23c6c3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 30 Sep 2024 16:22:19 +0300
Subject: [PATCH] jpegdec: Directly error out on negotiation failures
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-247
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3862
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8040>
---
ext/jpeg/gstjpegdec.c | 22 ++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/ext/jpeg/gstjpegdec.c b/ext/jpeg/gstjpegdec.c
index 51bc2d14bf0e..7523419835ee 100644
--- a/ext/jpeg/gstjpegdec.c
+++ b/ext/jpeg/gstjpegdec.c
@@ -1068,13 +1068,14 @@ gst_jpeg_turbo_parse_ext_fmt_convert (GstJpegDec * dec, gint * clrspc)
}
#endif
-static void
+static gboolean
gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc,
gboolean interlaced)
{
GstVideoCodecState *outstate;
GstVideoInfo *info;
GstVideoFormat format;
+ gboolean res;
#ifdef JCS_EXTENSIONS
if (dec->format_convert) {
@@ -1104,7 +1105,7 @@ gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc,
height == GST_VIDEO_INFO_HEIGHT (info) &&
format == GST_VIDEO_INFO_FORMAT (info)) {
gst_video_codec_state_unref (outstate);
- return;
+ return TRUE;
}
gst_video_codec_state_unref (outstate);
}
@@ -1118,6 +1119,8 @@ gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc,
outstate =
gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec), format,
width, height, dec->input_state);
+ if (!outstate)
+ return FALSE;
switch (clrspc) {
case JCS_RGB:
@@ -1142,10 +1145,12 @@ gst_jpeg_dec_negotiate (GstJpegDec * dec, gint width, gint height, gint clrspc,
gst_video_codec_state_unref (outstate);
- gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec));
+ res = gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec));
GST_DEBUG_OBJECT (dec, "max_v_samp_factor=%d", dec->cinfo.max_v_samp_factor);
GST_DEBUG_OBJECT (dec, "max_h_samp_factor=%d", dec->cinfo.max_h_samp_factor);
+
+ return res;
}
static GstFlowReturn
@@ -1425,8 +1430,9 @@ gst_jpeg_dec_handle_frame (GstVideoDecoder * bdec, GstVideoCodecFrame * frame)
num_fields = 1;
}
- gst_jpeg_dec_negotiate (dec, width, output_height,
- dec->cinfo.jpeg_color_space, num_fields == 2);
+ if (!gst_jpeg_dec_negotiate (dec, width, output_height,
+ dec->cinfo.jpeg_color_space, num_fields == 2))
+ goto negotiation_failed;
state = gst_video_decoder_get_output_state (bdec);
ret = gst_video_decoder_allocate_output_frame (bdec, frame);
@@ -1558,6 +1564,12 @@ map_failed:
ret = GST_FLOW_ERROR;
goto exit;
}
+negotiation_failed:
+ {
+ GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL), ("failed to negotiate"));
+ ret = GST_FLOW_NOT_NEGOTIATED;
+ goto exit;
+ }
decode_error:
{
gchar err_msg[JMSG_LENGTH_MAX];
--
GitLab

View File

@ -1,43 +0,0 @@
From 395f2b3ffdc5e600b49e950f62df46e4ad2265ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 30 Sep 2024 19:04:51 +0300
Subject: [PATCH] matroskademux: Don't take data out of an empty adapter when
processing WavPack frames
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-249
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3865
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8057>
---
gst/matroska/matroska-demux.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 2a3df8b6c512..4e546b439ccc 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -4042,11 +4042,16 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
}
gst_buffer_unmap (*buf, &map);
- newbuf = gst_adapter_take_buffer (adapter, gst_adapter_available (adapter));
+ size = gst_adapter_available (adapter);
+ if (size > 0) {
+ newbuf = gst_adapter_take_buffer (adapter, size);
+ gst_buffer_copy_into (newbuf, *buf,
+ GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
+ } else {
+ newbuf = NULL;
+ }
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;
--
GitLab

View File

@ -1,44 +0,0 @@
From c20eff779d932fd1c1dbac1e62397578d8861241 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 30 Sep 2024 19:06:03 +0300
Subject: [PATCH] matroskademux: Skip over laces directly when postprocessing
the frame fails
Otherwise NULL buffers might be handled afterwards.
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-249
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3865
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8057>
---
gst/matroska/matroska-demux.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 4e546b439ccc..a35f79f02381 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -4988,6 +4988,18 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
if (stream->postprocess_frame) {
GST_LOG_OBJECT (demux, "running post process");
ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub);
+ if (ret != GST_FLOW_OK) {
+ gst_clear_buffer (&sub);
+ goto next_lace;
+ }
+
+ if (sub == NULL) {
+ GST_WARNING_OBJECT (demux,
+ "Postprocessing buffer with timestamp %" GST_TIME_FORMAT
+ " for stream %d failed", GST_TIME_ARGS (buffer_timestamp),
+ stream_num);
+ goto next_lace;
+ }
}
/* At this point, we have a sub-buffer pointing at data within a larger
--
GitLab

View File

@ -1,35 +0,0 @@
From 8aa1c185cf47042a0cc624ae3ff5b0545455fedf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 30 Sep 2024 18:25:53 +0300
Subject: [PATCH] matroskademux: Check for big enough WavPack codec private
data before accessing it
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-250
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3866
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8057>
---
gst/matroska/matroska-demux.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 2ed77b50d078..2a3df8b6c512 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -3894,6 +3894,11 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
guint8 *buf_data, *data;
Wavpack4Header wvh;
+ if (!stream->codec_priv || stream->codec_priv_size < 2) {
+ GST_ERROR_OBJECT (element, "No or too small wavpack codec private data");
+ return GST_FLOW_ERROR;
+ }
+
wvh.ck_id[0] = 'w';
wvh.ck_id[1] = 'v';
wvh.ck_id[2] = 'p';
--
GitLab

View File

@ -1,35 +0,0 @@
From b84a0f326350989b81b95f55ef513fdaa16487fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 30 Sep 2024 19:19:42 +0300
Subject: [PATCH] matroskademux: Skip over zero-sized Xiph stream headers
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-251
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3867
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8057>
---
gst/matroska/matroska-ids.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/gst/matroska/matroska-ids.c b/gst/matroska/matroska-ids.c
index f11b7c2ce31f..ba645f7306d9 100644
--- a/gst/matroska/matroska-ids.c
+++ b/gst/matroska/matroska-ids.c
@@ -189,8 +189,10 @@ gst_matroska_parse_xiph_stream_headers (gpointer codec_data,
if (offset + length[i] > codec_data_size)
goto error;
- hdr = gst_buffer_new_memdup (p + offset, length[i]);
- gst_buffer_list_add (list, hdr);
+ if (length[i] > 0) {
+ hdr = gst_buffer_new_memdup (p + offset, length[i]);
+ gst_buffer_list_add (list, hdr);
+ }
offset += length[i];
}
--
GitLab

View File

@ -1,40 +0,0 @@
From f8e398c46fc074f266edb3f20479c0ca31b52448 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Thu, 26 Sep 2024 22:16:06 +0300
Subject: [PATCH] qtdemux: Avoid integer overflow when parsing Theora extension
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-166
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3851
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8032>
---
gst/isomp4/qtdemux.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 5e3cb1b9e699..c2d8b5e0f134 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -8822,7 +8822,7 @@ qtdemux_parse_theora_extension (GstQTDemux * qtdemux, QtDemuxStream * stream,
end -= 8;
while (buf < end) {
- gint size;
+ guint32 size;
guint32 type;
size = QT_UINT32 (buf);
@@ -8830,7 +8830,7 @@ qtdemux_parse_theora_extension (GstQTDemux * qtdemux, QtDemuxStream * stream,
GST_LOG_OBJECT (qtdemux, "%p %p", buf, end);
- if (buf + size > end || size <= 0)
+ if (end - buf < size || size < 8)
break;
buf += 8;
--
GitLab

View File

@ -1,49 +0,0 @@
From 1d1c9d63be51d85f9b80f0c227d4b3469fee2534 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Wed, 2 Oct 2024 14:44:21 +0300
Subject: [PATCH] gdkpixbufdec: Check if initializing the video info actually
succeeded
Otherwise a 0-byte buffer would be allocated, which gives NULL memory when
mapped.
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-118
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3876
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8041>
---
ext/gdk_pixbuf/gstgdkpixbufdec.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/ext/gdk_pixbuf/gstgdkpixbufdec.c b/ext/gdk_pixbuf/gstgdkpixbufdec.c
index 5482998c0d60..de5f05496466 100644
--- a/ext/gdk_pixbuf/gstgdkpixbufdec.c
+++ b/ext/gdk_pixbuf/gstgdkpixbufdec.c
@@ -322,7 +322,8 @@ gst_gdk_pixbuf_dec_flush (GstGdkPixbufDec * filter)
gst_video_info_init (&info);
- gst_video_info_set_format (&info, fmt, width, height);
+ if (!gst_video_info_set_format (&info, fmt, width, height))
+ goto format_not_supported;
info.fps_n = filter->in_fps_n;
info.fps_d = filter->in_fps_d;
caps = gst_video_info_to_caps (&info);
@@ -384,6 +385,12 @@ channels_not_supported:
("%d channels not supported", n_channels));
return GST_FLOW_ERROR;
}
+format_not_supported:
+ {
+ GST_ELEMENT_ERROR (filter, STREAM, DECODE, (NULL),
+ ("%d channels with %dx%d not supported", n_channels, width, height));
+ return GST_FLOW_ERROR;
+ }
no_buffer:
{
GST_DEBUG ("Failed to create outbuffer - %s", gst_flow_get_name (ret));
--
GitLab

View File

@ -1,42 +0,0 @@
From 0870e87c7c02e28e22a09a7de0c5b1e5bed68c14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 4 Oct 2024 14:04:03 +0300
Subject: [PATCH] avisubtitle: Fix size checks and avoid overflows when
checking sizes
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-262
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3890
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8043>
---
gst/avi/gstavisubtitle.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/gst/avi/gstavisubtitle.c b/gst/avi/gstavisubtitle.c
index efc5f0405186..c816934da61c 100644
--- a/gst/avi/gstavisubtitle.c
+++ b/gst/avi/gstavisubtitle.c
@@ -196,7 +196,7 @@ gst_avi_subtitle_parse_gab2_chunk (GstAviSubtitle * sub, GstBuffer * buf)
/* read 'name' of subtitle */
name_length = GST_READ_UINT32_LE (map.data + 5 + 2);
GST_LOG_OBJECT (sub, "length of name: %u", name_length);
- if (map.size <= 17 + name_length)
+ if (G_MAXUINT32 - 17 < name_length || map.size < 17 + name_length)
goto wrong_name_length;
name_utf8 =
@@ -216,7 +216,8 @@ gst_avi_subtitle_parse_gab2_chunk (GstAviSubtitle * sub, GstBuffer * buf)
file_length = GST_READ_UINT32_LE (map.data + 13 + name_length);
GST_LOG_OBJECT (sub, "length srt/ssa file: %u", file_length);
- if (map.size < (17 + name_length + file_length))
+ if (G_MAXUINT32 - 17 - name_length < file_length
+ || map.size < 17 + name_length + file_length)
goto wrong_total_length;
/* store this, so we can send it again after a seek; note that we shouldn't
--
GitLab

View File

@ -1,402 +0,0 @@
From 13b48016b3ef1e822c393c2871b0a561ce19ecb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 4 Oct 2024 13:00:57 +0300
Subject: [PATCH 1/7] wavparse: Check for short reads when parsing headers in
pull mode
And also return the actual flow return to the caller instead of always returning
GST_FLOW_ERROR.
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-258, GHSL-2024-260
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3886
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3888
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8042>
---
gst/wavparse/gstwavparse.c | 63 ++++++++++++++-----
1 file changed, 46 insertions(+), 17 deletions(-)
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index d074f273c501..97d5591fae8f 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1097,6 +1097,24 @@ parse_ds64 (GstWavParse * wav, GstBuffer * buf)
return TRUE;
}
+static GstFlowReturn
+gst_wavparse_pull_range_exact (GstWavParse * wav, guint64 offset, guint size,
+ GstBuffer ** buffer)
+{
+ GstFlowReturn res;
+
+ res = gst_pad_pull_range (wav->sinkpad, offset, size, buffer);
+ if (res != GST_FLOW_OK)
+ return res;
+
+ if (gst_buffer_get_size (*buffer) < size) {
+ gst_clear_buffer (buffer);
+ return GST_FLOW_EOS;
+ }
+
+ return res;
+}
+
static GstFlowReturn
gst_wavparse_stream_headers (GstWavParse * wav)
{
@@ -1292,9 +1310,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
buf = NULL;
if ((res =
- gst_pad_pull_range (wav->sinkpad, wav->offset, 8,
+ gst_wavparse_pull_range_exact (wav, wav->offset, 8,
&buf)) != GST_FLOW_OK)
- goto header_read_error;
+ goto header_pull_error;
gst_buffer_map (buf, &map, GST_MAP_READ);
tag = GST_READ_UINT32_LE (map.data);
size = GST_READ_UINT32_LE (map.data + 4);
@@ -1397,9 +1415,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
gst_buffer_unref (buf);
buf = NULL;
if ((res =
- gst_pad_pull_range (wav->sinkpad, wav->offset + 8,
+ gst_wavparse_pull_range_exact (wav, wav->offset + 8,
data_size, &buf)) != GST_FLOW_OK)
- goto header_read_error;
+ goto header_pull_error;
gst_buffer_extract (buf, 0, &wav->fact, 4);
wav->fact = GUINT32_FROM_LE (wav->fact);
gst_buffer_unref (buf);
@@ -1444,9 +1462,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
gst_buffer_unref (buf);
buf = NULL;
if ((res =
- gst_pad_pull_range (wav->sinkpad, wav->offset + 8,
- size, &buf)) != GST_FLOW_OK)
- goto header_read_error;
+ gst_wavparse_pull_range_exact (wav, wav->offset + 8, size,
+ &buf)) != GST_FLOW_OK)
+ goto header_pull_error;
gst_buffer_map (buf, &map, GST_MAP_READ);
acid = (const gst_riff_acid *) map.data;
tempo = acid->tempo;
@@ -1484,9 +1502,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
gst_buffer_unref (buf);
buf = NULL;
if ((res =
- gst_pad_pull_range (wav->sinkpad, wav->offset, 12,
+ gst_wavparse_pull_range_exact (wav, wav->offset, 12,
&buf)) != GST_FLOW_OK)
- goto header_read_error;
+ goto header_pull_error;
gst_buffer_extract (buf, 8, &ltag, 4);
ltag = GUINT32_FROM_LE (ltag);
}
@@ -1513,9 +1531,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
buf = NULL;
if (data_size > 0) {
if ((res =
- gst_pad_pull_range (wav->sinkpad, wav->offset,
+ gst_wavparse_pull_range_exact (wav, wav->offset,
data_size, &buf)) != GST_FLOW_OK)
- goto header_read_error;
+ goto header_pull_error;
}
}
if (data_size > 0) {
@@ -1553,9 +1571,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
buf = NULL;
wav->offset += 12;
if ((res =
- gst_pad_pull_range (wav->sinkpad, wav->offset,
+ gst_wavparse_pull_range_exact (wav, wav->offset,
data_size, &buf)) != GST_FLOW_OK)
- goto header_read_error;
+ goto header_pull_error;
gst_buffer_map (buf, &map, GST_MAP_READ);
gst_wavparse_adtl_chunk (wav, (const guint8 *) map.data,
data_size);
@@ -1599,9 +1617,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
gst_buffer_unref (buf);
buf = NULL;
if ((res =
- gst_pad_pull_range (wav->sinkpad, wav->offset,
+ gst_wavparse_pull_range_exact (wav, wav->offset,
data_size, &buf)) != GST_FLOW_OK)
- goto header_read_error;
+ goto header_pull_error;
gst_buffer_map (buf, &map, GST_MAP_READ);
if (!gst_wavparse_cue_chunk (wav, (const guint8 *) map.data,
data_size)) {
@@ -1643,9 +1661,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
gst_buffer_unref (buf);
buf = NULL;
if ((res =
- gst_pad_pull_range (wav->sinkpad, wav->offset,
+ gst_wavparse_pull_range_exact (wav, wav->offset,
data_size, &buf)) != GST_FLOW_OK)
- goto header_read_error;
+ goto header_pull_error;
gst_buffer_map (buf, &map, GST_MAP_READ);
if (!gst_wavparse_smpl_chunk (wav, (const guint8 *) map.data,
data_size)) {
@@ -1797,6 +1815,17 @@ header_read_error:
("Couldn't read in header %d (%s)", res, gst_flow_get_name (res)));
goto fail;
}
+header_pull_error:
+ {
+ if (res == GST_FLOW_EOS) {
+ GST_WARNING_OBJECT (wav, "Couldn't pull header %d (%s)", res,
+ gst_flow_get_name (res));
+ } else {
+ GST_ELEMENT_ERROR (wav, STREAM, DEMUX, (NULL),
+ ("Couldn't pull header %d (%s)", res, gst_flow_get_name (res)));
+ }
+ goto exit;
+ }
}
/*
--
GitLab
From 4c198f4891cfabde868944d55ff98925e7beb757 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 4 Oct 2024 13:09:43 +0300
Subject: [PATCH 2/7] wavparse: Make sure enough data for the tag list tag is
available before parsing
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-258
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3886
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8042>
---
gst/wavparse/gstwavparse.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index 97d5591fae8f..21cb48c07eb3 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1489,6 +1489,10 @@ gst_wavparse_stream_headers (GstWavParse * wav)
case GST_RIFF_TAG_LIST:{
guint32 ltag;
+ /* Need at least the ltag */
+ if (size < 4)
+ goto exit;
+
if (wav->streaming) {
const guint8 *data = NULL;
--
GitLab
From 296e17b4ea81e5c228bb853f6037b654fdca7d47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 4 Oct 2024 13:15:27 +0300
Subject: [PATCH 3/7] wavparse: Fix parsing of acid chunk
Simply casting the bytes to a struct can lead to crashes because of unaligned
reads, and is also missing the endianness swapping that is necessary on big
endian architectures.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8042>
---
gst/wavparse/gstwavparse.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index 21cb48c07eb3..6a0c44638ea2 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1434,8 +1434,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
break;
}
case GST_RIFF_TAG_acid:{
- const gst_riff_acid *acid = NULL;
- const guint data_size = sizeof (gst_riff_acid);
+ const guint data_size = 24;
gfloat tempo;
GST_INFO_OBJECT (wav, "Have acid chunk");
@@ -1449,13 +1448,13 @@ gst_wavparse_stream_headers (GstWavParse * wav)
break;
}
if (wav->streaming) {
+ const guint8 *data;
if (!gst_wavparse_peek_chunk (wav, &tag, &size)) {
goto exit;
}
gst_adapter_flush (wav->adapter, 8);
- acid = (const gst_riff_acid *) gst_adapter_map (wav->adapter,
- data_size);
- tempo = acid->tempo;
+ data = gst_adapter_map (wav->adapter, data_size);
+ tempo = GST_READ_FLOAT_LE (data + 20);
gst_adapter_unmap (wav->adapter);
} else {
GstMapInfo map;
@@ -1466,8 +1465,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
&buf)) != GST_FLOW_OK)
goto header_pull_error;
gst_buffer_map (buf, &map, GST_MAP_READ);
- acid = (const gst_riff_acid *) map.data;
- tempo = acid->tempo;
+ tempo = GST_READ_FLOAT_LE (map.data + 20);
gst_buffer_unmap (buf, &map);
}
/* send data as tags */
--
GitLab
From c72025cabdfcb2fe30d24eda7bb9d1d01a1b6555 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 4 Oct 2024 13:21:44 +0300
Subject: [PATCH 4/7] wavparse: Check that at least 4 bytes are available
before parsing cue chunks
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8042>
---
gst/wavparse/gstwavparse.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index 6a0c44638ea2..5655ee3825ca 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -790,6 +790,11 @@ gst_wavparse_cue_chunk (GstWavParse * wav, const guint8 * data, guint32 size)
return TRUE;
}
+ if (size < 4) {
+ GST_WARNING_OBJECT (wav, "broken file %d", size);
+ return FALSE;
+ }
+
ncues = GST_READ_UINT32_LE (data);
if (size < 4 + ncues * 24) {
--
GitLab
From 93d79c22a82604adc5512557c1238f72f41188c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 4 Oct 2024 13:22:02 +0300
Subject: [PATCH 5/7] wavparse: Check that at least 32 bytes are available
before parsing smpl chunks
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-259
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3887
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8042>
---
gst/wavparse/gstwavparse.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index 5655ee3825ca..8a04805ed427 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -894,6 +894,9 @@ gst_wavparse_smpl_chunk (GstWavParse * wav, const guint8 * data, guint32 size)
{
guint32 note_number;
+ if (size < 32)
+ return FALSE;
+
/*
manufacturer_id = GST_READ_UINT32_LE (data);
product_id = GST_READ_UINT32_LE (data + 4);
--
GitLab
From 526d0eef0d850c8f2fa1bf0aef15a836797f1a67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 4 Oct 2024 13:27:27 +0300
Subject: [PATCH 6/7] wavparse: Fix clipping of size to the file size
The size does not include the 8 bytes tag and length, so an additional 8 bytes
must be removed here. 8 bytes are always available at this point because
otherwise the parsing of the tag and length right above would've failed.
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-260
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3888
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8042>
---
gst/wavparse/gstwavparse.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index 8a04805ed427..998cbb276dbf 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1338,10 +1338,11 @@ gst_wavparse_stream_headers (GstWavParse * wav)
}
/* Clip to upstream size if known */
- if (upstream_size > 0 && size + wav->offset > upstream_size) {
+ if (upstream_size > 0 && size + 8 + wav->offset > upstream_size) {
GST_WARNING_OBJECT (wav, "Clipping chunk size to file size");
g_assert (upstream_size >= wav->offset);
- size = upstream_size - wav->offset;
+ g_assert (upstream_size - wav->offset >= 8);
+ size = upstream_size - wav->offset - 8;
}
/* wav is a st00pid format, we don't know for sure where data starts.
--
GitLab
From 4f381d15014471b026020d0990a5f5a9f420a22b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Fri, 4 Oct 2024 13:51:00 +0300
Subject: [PATCH 7/7] wavparse: Check size before reading ds64 chunk
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-261
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3889
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8042>
---
gst/wavparse/gstwavparse.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index 998cbb276dbf..958868de6d9e 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1088,6 +1088,11 @@ parse_ds64 (GstWavParse * wav, GstBuffer * buf)
guint32 sampleCountLow, sampleCountHigh;
gst_buffer_map (buf, &map, GST_MAP_READ);
+ if (map.size < 6 * 4) {
+ GST_WARNING_OBJECT (wav, "Too small ds64 chunk (%" G_GSIZE_FORMAT ")",
+ map.size);
+ return FALSE;
+ }
dataSizeLow = GST_READ_UINT32_LE (map.data + 2 * 4);
dataSizeHigh = GST_READ_UINT32_LE (map.data + 3 * 4);
sampleCountLow = GST_READ_UINT32_LE (map.data + 4 * 4);
--
GitLab

View File

@ -1,36 +0,0 @@
From 474eb62d85b65de1f4a9389d28e4a380a0bf1d7b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Wed, 9 Oct 2024 11:52:52 -0400
Subject: [PATCH] matroskademux: Put a copy of the codec data into the A_MS/ACM
caps
The original codec data buffer is owned by matroskademux and does not
necessarily live as long as the caps.
Thanks to Antonio Morales for finding and reporting the issue.
Fixes GHSL-2024-280
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3894
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8057>
---
gst/matroska/matroska-demux.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index a35f79f02381..afde4ee62897 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -7183,8 +7183,7 @@ gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
/* 18 is the waveformatex size */
if (size > 18) {
- codec_data = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
- data + 18, size - 18, 0, size - 18, NULL, NULL);
+ codec_data = gst_buffer_new_memdup (data + 18, size - 18);
}
if (riff_audio_fmt)
--
GitLab

View File

@ -0,0 +1,200 @@
From 242f3cae6da748ac128e86b5cadcd406fa61aff6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/902>
---
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

View File

@ -0,0 +1,37 @@
From 6c461e90bc1eedce4b7e414d34c8a8a9162359b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/902>
---
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

Binary file not shown.

Binary file not shown.

View File

@ -1,89 +1,29 @@
%bcond_without extras
%bcond_without nasm
%bcond_with extras
%bcond_with qt
Name: gstreamer1-plugins-good
Version: 1.20.3
Version: 1.16.2
Release: 4
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
#https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4894.patch
Patch0: CVE-2023-37327.patch
Patch1: CVE-2024-47606.patch
Patch2: CVE-2024-47599.patch
Patch3: CVE-2024-47613.patch
Patch4: CVE-2024-47775_CVE-2024-47776_CVE-2024-47777_CVE-2024-47778.patch
Patch5: CVE-2024-47774.patch
Patch6: CVE-2024-47540.patch
Patch7: CVE-2024-47602.patch
Patch8: CVE-2024-47601-1.patch
Patch9: CVE-2024-47601-2.patch
Patch10: CVE-2024-47603.patch
Patch11: CVE-2024-47834.patch
Patch12: CVE-2024-47537.patch
Patch13: CVE-2024-47597-1.patch
Patch14: CVE-2024-47597-2.patch
Patch15: CVE-2024-47543.patch
Patch16: CVE-2024-47596.patch
Patch17: CVE-2024-47539.patch
Patch18: CVE-2024-47546.patch
Patch19: CVE-2024-47598.patch
Patch20: matroskademux-Fix-off-by-one-when-parsing-multi-channel-WavPack.patch
Patch21: qtdemux-Do-not-iterate-over-all-trun-entries-if-none.patch
Patch22: qtdemux-Fix-debug-output-during-trun-parsing.patch
Patch23: CVE-2024-47545-pre1.patch
Patch24: CVE-2024-47545-pre2.patch
Patch25: CVE-2024-47545.patch
Patch26: CVE-2024-47544.patch
BuildRequires: meson >= 0.48.0
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: gstreamer1-devel >= %{version}
BuildRequires: gstreamer1-plugins-base-devel >= %{version}
BuildRequires: cairo-devel >= 1.10.0
BuildRequires: cairo-gobject-devel >= 1.10.0
BuildRequires: flac-devel >= 1.1.4
BuildRequires: gdk-pixbuf2-devel
BuildRequires: libjpeg-devel
BuildRequires: libpng-devel >= 1.2.0
BuildRequires: libshout-devel
BuildRequires: libsoup-devel
BuildRequires: libX11-devel
BuildRequires: libXext-devel
BuildRequires: libXdamage-devel
BuildRequires: libXfixes-devel
BuildRequires: orc-devel
BuildRequires: pulseaudio-libs-devel
BuildRequires: speex-devel
BuildRequires: taglib-devel
BuildRequires: wavpack-devel
BuildRequires: libv4l-devel
BuildRequires: libvpx-devel >= 1.1.0
BuildRequires: gtk3-devel >= 3.4
BuildRequires: mesa-libGL-devel
BuildRequires: mesa-libGLES-devel
BuildRequires: mesa-libGLU-devel
BuildRequires: mesa-libEGL-devel
BuildRequires: lame-devel
BuildRequires: mpg123-devel
BuildRequires: twolame-devel
%if %{with nasm}
BuildRequires: nasm
%endif
%if %{with extras}
BuildRequires: jack-audio-connection-kit-devel
BuildRequires: libdv-devel
BuildRequires: libraw1394-devel libavc1394-devel
BuildRequires: libiec61883-devel
%endif
BuildRequires: libgudev-devel
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
BuildRequires: pulseaudio-libs-devel speex-devel taglib-devel wavpack-devel libv4l-devel
BuildRequires: libvpx-devel gtk3-devel mesa-libGL-devel libglvnd-devel lame-devel
BuildRequires: mesa-libEGL-devel mesa-libGLU-devel mpg123-devel twolame-devel libdv-devel
BuildRequires: libavc1394-devel libiec61883-devel libraw1394-devel gtk-doc
BuildRequires: chrpath
Provides: gstreamer1-plugins-mpg123 = %{version}-%{release}
Obsoletes: gstreamer1-plugins-mpg123 < %{version}-%{release}
Obsoletes: gstreamer1-plugins-good-help < 1.20.3
%description
GStreamer is a streaming media framework, based on graphs of filters which
@ -109,71 +49,34 @@ operate on media data.
GStreamer Good Plugins is a collection of well-supported plugins of
good quality and under the LGPL license.
%package qt
Summary: GStreamer "good" plugins qt qml plugin
Requires: %{name}%{?_isa} = %{version}-%{release}
BuildRequires: pkgconfig(Qt5Gui)
BuildRequires: pkgconfig(Qt5Qml)
BuildRequires: pkgconfig(Qt5Quick)
BuildRequires: pkgconfig(Qt5X11Extras)
BuildRequires: pkgconfig(Qt5WaylandClient)
Supplements: (gstreamer1-plugins-good and qt5-qtdeclarative)
%description qt
GStreamer is a streaming media framework, based on graphs of elements which
operate on media data.
GStreamer Good Plugins is a collection of well-supported plugins of
good quality and under the LGPL license.
This package (%{name}-qt) contains the qtsink output plugin.
%if %{with extras}
%package extras
Summary: Extra GStreamer plugins with good code and licensing
Requires: %{name}%{?_isa} = %{version}-%{release}
%description extras
GStreamer is a streaming media framework, based on graphs of filters
which operate on media data.
GStreamer Good Plugins is a collection of well-supported plugins of
good quality and under the LGPL license.
%{name}-extras contains extra "good" plugins
which are not used very much and require additional libraries
to be installed.
%endif
%package_help
%prep
%autosetup -n gst-plugins-good-%{version} -p1
%build
%meson \
-D doc=disabled \
-D asm=%{?with_nasm:enabled}%{!?with_nasm:disabled} \
-D orc=enabled \
-D monoscope=disabled \
-D aalib=disabled \
-D libcaca=disabled \
-D rpicamsrc=disabled \
-D jack=%{?with_extras:enabled}%{!?with_extras:disabled} \
-D dv=%{?with_extras:enabled}%{!?with_extras:disabled} \
-D dv1394=%{?with_extras:enabled}%{!?with_extras:disabled} \
%configure --disable-silent-rules --disable-fatal-warnings --enable-experimental \
--enable-gtk-doc --enable-orc --disable-monoscope --disable-aalib \
--disable-cairo --disable-libcaca --disable-jack \
--with-default-visualizer=autoaudiosink
%meson_build
%make_build
%install
%meson_install
%make_install
%delete_la_and_a
install -p -D %{SOURCE1} %{buildroot}%{_metainfodir}/gstreamer-good.appdata.xml
chrpath -d %{buildroot}%{_libdir}/gstreamer-1.0/libgstshout2.so
mkdir -p %{buildroot}/etc/ld.so.conf.d
echo "%{_libdir}" > %{buildroot}/etc/ld.so.conf.d/%{name}-%{_arch}.conf
%ldconfig_scriptlets
%files
%defattr(-,root,root)
%doc AUTHORS NEWS README.md README.static-linking RELEASE REQUIREMENTS
%doc AUTHORS
%license COPYING
%{_libdir}/gstreamer-1.0/*.so
%{_datadir}/locale/*
@ -181,47 +84,18 @@ install -p -D %{SOURCE1} %{buildroot}%{_metainfodir}/gstreamer-good.appdata.xml
%{_datadir}/gstreamer-1.0/presets/*.prs
%{_metainfodir}/gstreamer-good.appdata.xml
%exclude %{_libdir}/gstreamer-1.0/libgstgtk.so
%exclude %{_libdir}/gstreamer-1.0/libgstqmlgl.so
%exclude %{_libdir}/gstreamer-1.0/libgstjack.so
%exclude %{_libdir}/gstreamer-1.0/libgstdv.so
%exclude %{_libdir}/gstreamer-1.0/libgst1394.so
%config(noreplace) /etc/ld.so.conf.d/*
%files gtk
%defattr(-,root,root)
%{_libdir}/gstreamer-1.0/libgstgtk.so
%files qt
%{_libdir}/gstreamer-1.0/libgstqmlgl.so
%if %{with extras}
%files extras
# Plugins with external dependencies
%{_libdir}/gstreamer-1.0/libgstjack.so
%{_libdir}/gstreamer-1.0/libgstdv.so
%{_libdir}/gstreamer-1.0/libgst1394.so
%endif
%files help
%defattr(-,root,root)
%doc README REQUIREMENTS
%doc %{_datadir}/gtk-doc/html/*
%changelog
* Fri Dec 20 2024 yaoxin <yao_xin001@hoperun.com> - 1.20.3-4
- Fix CVE-2024-47544 and CVE-2024-47545
* Wed Dec 18 2024 yaoxin <yao_xin001@hoperun.com> - 1.20.3-3
- Fix cves:
CVE-2024-47606,CVE-2024-47599,CVE-2024-47613,CVE-2024-47775
CVE-2024-47776,CVE-2024-47777,CVE-2024-47778,CVE-2024-47774
CVE-2024-47540,CVE-2024-47602,CVE-2024-47601,CVE-2024-47603
CVE-2024-47834,CVE-2024-47537,CVE-2024-47597,CVE-2024-47543
CVE-2024-47596,CVE-2024-47539,CVE-2024-47546,CVE-2024-47598
* Fri Dec 15 2023 wangkai <13474090681@163.com> - 1.20.3-2
- Fix CVE-2023-37327
* Wed Nov 01 2023 wangkai <13474090681@163.com> - 1.20.3-1
- Update to 1.20.3
* Mon Jun 27 2022 yaoxin <yaoxin30@h-partners.com> - 1.16.2-5
- Fix CVE-2022-2122 CVE-2022-1920-to-CVE-2022-1925
* Fri Sep 10 2021 gaihuiying <gaihuiying1@huawei.com> - 1.16.2-4
- Type:bugfix
- ID:NA

View File

@ -1,27 +0,0 @@
From b7ad9a2c5d2b1d87a33dfd73b5e10b184b31a3d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 30 Sep 2024 16:33:39 +0300
Subject: [PATCH] matroskademux: Fix off-by-one when parsing multi-channel
WavPack
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8057>
---
gst/matroska/matroska-demux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 9e0de058e64a..2ed77b50d078 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -3976,7 +3976,7 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
data += 4;
size -= 4;
- while (size > 12) {
+ while (size >= 12) {
flags = GST_READ_UINT32_LE (data);
data += 4;
size -= 4;
--
GitLab

View File

@ -1,32 +0,0 @@
From 0f4dae9b01fcc4ec3a16d2386dfac432e011465b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Thu, 26 Sep 2024 18:41:39 +0300
Subject: [PATCH] qtdemux: Don't iterate over all trun entries if none of the
flags are set
Nothing would be printed anyway.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux_dump.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/gst/isomp4/qtdemux_dump.c b/gst/isomp4/qtdemux_dump.c
index 22da35e9e7ad..297b580ef038 100644
--- a/gst/isomp4/qtdemux_dump.c
+++ b/gst/isomp4/qtdemux_dump.c
@@ -836,6 +836,11 @@ qtdemux_dump_trun (GstQTDemux * qtdemux, GstByteReader * data, int depth)
GST_LOG ("%*s first-sample-flags: %u", depth, "", first_sample_flags);
}
+ /* Nothing to print below */
+ if ((flags & (TR_SAMPLE_DURATION | TR_SAMPLE_SIZE | TR_SAMPLE_FLAGS |
+ TR_COMPOSITION_TIME_OFFSETS)) == 0)
+ return TRUE;
+
for (i = 0; i < samples_count; i++) {
if (flags & TR_SAMPLE_DURATION) {
if (!gst_byte_reader_get_uint32_be (data, &sample_duration))
--
GitLab

View File

@ -1,69 +0,0 @@
From cbd659c58f3236596a47b45a2afe6130139cf661 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Thu, 26 Sep 2024 18:40:56 +0300
Subject: [PATCH] qtdemux: Fix debug output during trun parsing
Various integers are unsigned so print them as such. Also print the actual
allocation size if allocation fails, not only parts of it.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8059>
---
gst/isomp4/qtdemux.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index f71d04b..ba80392 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -3221,8 +3221,8 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
gint64 initial_offset;
gint32 min_ct = 0;
- GST_LOG_OBJECT (qtdemux, "parsing trun track-id %d; "
- "default dur %d, size %d, flags 0x%x, base offset %" G_GINT64_FORMAT ", "
+ GST_LOG_OBJECT (qtdemux, "parsing trun track-id %u; "
+ "default dur %u, size %u, flags 0x%x, base offset %" G_GINT64_FORMAT ", "
"decode ts %" G_GINT64_FORMAT, stream->track_id, d_sample_duration,
d_sample_size, d_sample_flags, *base_offset, decode_ts);
@@ -3250,7 +3250,7 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
/* note this is really signed */
if (!gst_byte_reader_get_int32_be (trun, &data_offset))
goto fail;
- GST_LOG_OBJECT (qtdemux, "trun data offset %d", data_offset);
+ GST_LOG_OBJECT (qtdemux, "trun data offset %u", data_offset);
/* default base offset = first byte of moof */
if (*base_offset == -1) {
GST_LOG_OBJECT (qtdemux, "base_offset at moof");
@@ -3272,7 +3272,7 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
GST_LOG_OBJECT (qtdemux, "running offset now %" G_GINT64_FORMAT,
*running_offset);
- GST_LOG_OBJECT (qtdemux, "trun offset %d, flags 0x%x, entries %d",
+ GST_LOG_OBJECT (qtdemux, "trun offset %u, flags 0x%x, entries %u",
data_offset, flags, samples_count);
if (flags & TR_FIRST_SAMPLE_FLAGS) {
@@ -3492,14 +3492,15 @@ fail:
}
out_of_memory:
{
- GST_WARNING_OBJECT (qtdemux, "failed to allocate %d samples",
- stream->n_samples);
+ GST_WARNING_OBJECT (qtdemux, "failed to allocate %u + %u samples",
+ stream->n_samples, samples_count);
return FALSE;
}
index_too_big:
{
- GST_WARNING_OBJECT (qtdemux, "not allocating index of %d samples, would "
- "be larger than %uMB (broken file?)", stream->n_samples,
+ GST_WARNING_OBJECT (qtdemux,
+ "not allocating index of %u + %u samples, would "
+ "be larger than %uMB (broken file?)", stream->n_samples, samples_count,
QTDEMUX_MAX_SAMPLE_INDEX_SIZE >> 20);
return FALSE;
}
--
2.33.0