Fix CVE-2024-47544 and CVE-2024-47545

This commit is contained in:
starlet-dx 2024-12-20 11:21:26 +08:00
parent ef8cfc50bd
commit fa17e30ba7
5 changed files with 860 additions and 1 deletions

49
CVE-2024-47544.patch Normal file
View File

@ -0,0 +1,49 @@
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) {

243
CVE-2024-47545-pre1.patch Normal file
View File

@ -0,0 +1,243 @@
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;

116
CVE-2024-47545-pre2.patch Normal file
View File

@ -0,0 +1,116 @@
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'):

444
CVE-2024-47545.patch Normal file
View File

@ -0,0 +1,444 @@
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

@ -3,7 +3,7 @@
Name: gstreamer1-plugins-good
Version: 1.20.3
Release: 3
Release: 4
Summary: GStreamer plugins with good code and licensing
License: LGPLv2+
URL: http://gstreamer.freedesktop.org/
@ -33,6 +33,10 @@ 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
@ -198,6 +202,9 @@ install -p -D %{SOURCE1} %{buildroot}%{_metainfodir}/gstreamer-good.appdata.xml
%endif
%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