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>
This commit is contained in:
Sebastian Dröge 2024-09-26 14:17:02 +03:00 committed by GStreamer Marge Bot
parent 1d534ac209
commit c1cd838706

View file

@ -13704,47 +13704,53 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
} else { } else {
guint32 datalen = QT_UINT32 (stsd_entry_data + offset + 16); guint32 datalen = QT_UINT32 (stsd_entry_data + offset + 16);
const guint8 *data = stsd_entry_data + offset + 16; const guint8 *data = stsd_entry_data + offset + 16;
GNode *wavenode;
GNode *waveheadernode;
wavenode = g_node_new ((guint8 *) data); if (len < datalen || len - datalen < offset + 16) {
if (qtdemux_parse_node (qtdemux, wavenode, data, datalen)) { GST_WARNING_OBJECT (qtdemux, "Not enough data for waveheadernode");
const guint8 *waveheader; } else {
guint32 headerlen; GNode *wavenode;
GNode *waveheadernode;
waveheadernode = qtdemux_tree_get_child_by_type (wavenode, fourcc); wavenode = g_node_new ((guint8 *) data);
if (waveheadernode) { if (qtdemux_parse_node (qtdemux, wavenode, data, datalen)) {
waveheader = (const guint8 *) waveheadernode->data; const guint8 *waveheader;
headerlen = QT_UINT32 (waveheader); guint32 headerlen;
if (headerlen > 8) { waveheadernode =
gst_riff_strf_auds *header = NULL; qtdemux_tree_get_child_by_type (wavenode, fourcc);
GstBuffer *headerbuf; if (waveheadernode) {
GstBuffer *extra; waveheader = (const guint8 *) waveheadernode->data;
headerlen = QT_UINT32 (waveheader);
waveheader += 8; if (headerlen > 8) {
headerlen -= 8; gst_riff_strf_auds *header = NULL;
GstBuffer *headerbuf;
GstBuffer *extra;
headerbuf = gst_buffer_new_and_alloc (headerlen); waveheader += 8;
gst_buffer_fill (headerbuf, 0, waveheader, headerlen); headerlen -= 8;
if (gst_riff_parse_strf_auds (GST_ELEMENT_CAST (qtdemux), headerbuf = gst_buffer_new_and_alloc (headerlen);
headerbuf, &header, &extra)) { gst_buffer_fill (headerbuf, 0, waveheader, headerlen);
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) if (gst_riff_parse_strf_auds (GST_ELEMENT_CAST (qtdemux),
gst_buffer_unref (extra); headerbuf, &header, &extra)) {
g_free (header); 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
} else GST_DEBUG ("Didn't find waveheadernode for this codec");
GST_DEBUG ("Didn't find waveheadernode for this codec"); }
g_node_destroy (wavenode);
} }
g_node_destroy (wavenode);
} }
} else if (esds) { } else if (esds) {
gst_qtdemux_handle_esds (qtdemux, stream, entry, esds, gst_qtdemux_handle_esds (qtdemux, stream, entry, esds,