From 9da3ed6491693f2a227bcfa10f1598f1f7fad22f Mon Sep 17 00:00:00 2001 From: Tim-Philipp Müller Date: Thu, 20 Aug 2009 01:39:17 +0100 Subject: qtdemux: add qt_atom_parse_has_remaining() to avoid overflows with _get_remaining() --- gst/qtdemux/qtatomparser.h | 7 +++++++ gst/qtdemux/qtdemux.c | 12 ++++++------ gst/qtdemux/qtdemux_dump.c | 34 +++++++++++++++++----------------- 3 files changed, 30 insertions(+), 23 deletions(-) (limited to 'gst/qtdemux') diff --git a/gst/qtdemux/qtatomparser.h b/gst/qtdemux/qtatomparser.h index ce32b980..7669ec0f 100644 --- a/gst/qtdemux/qtatomparser.h +++ b/gst/qtdemux/qtatomparser.h @@ -38,6 +38,13 @@ qt_atom_parser_get_remaining (QtAtomParser * parser) return parser->size - parser->byte; } +static inline gboolean +qt_atom_parser_has_remaining (QtAtomParser * parser, guint64 min_remaining) +{ + return G_LIKELY (parser->size >= min_remaining) && + G_LIKELY ((parser->size - min_remaining) >= parser->byte); +} + static inline gboolean qt_atom_parser_skip (QtAtomParser * parser, guint nbytes) { diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index fbfd6d08..f9a7eed0 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -3573,7 +3573,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, /* set the sample sizes */ if (sample_size == 0) { /* different sizes for each sample */ - if (qt_atom_parser_get_remaining (&stsz) < 4 * (n_samples)) + if (!qt_atom_parser_has_remaining (&stsz, 4 * n_samples)) goto corrupt_file; for (i = 0; i < n_samples; i++) { @@ -3592,7 +3592,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, !qt_atom_parser_get_uint32 (&stsc, &n_samples_per_chunk)) goto corrupt_file; - if (qt_atom_parser_get_remaining (&stsc) < 12 * n_samples_per_chunk) + if (!qt_atom_parser_has_remaining (&stsc, 12 * n_samples_per_chunk)) goto corrupt_file; index = 0; @@ -3665,7 +3665,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, GST_LOG_OBJECT (qtdemux, "%u timestamp blocks", n_sample_times); /* make sure there's enough data */ - if (qt_atom_parser_get_remaining (&stts) < (n_sample_times * (2 * 4))) + if (!qt_atom_parser_has_remaining (&stts, n_sample_times * (2 * 4))) goto corrupt_file; timestamp = 0; @@ -3732,7 +3732,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, stream->all_keyframe = TRUE; } else { /* make sure there's enough data */ - if (qt_atom_parser_get_remaining (&stss) < (n_sample_syncs * 4)) + if (!qt_atom_parser_has_remaining (&stss, n_sample_syncs * 4)) goto corrupt_file; for (i = 0; i < n_sample_syncs; i++) { /* note that the first sample is index 1, not 0 */ @@ -3755,7 +3755,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, * samples */ } else { /* make sure there's enough data */ - if (qt_atom_parser_get_remaining (&stps) < (n_sample_syncs * 4)) + if (!qt_atom_parser_has_remaining (&stps, n_sample_syncs * 4)) goto corrupt_file; for (i = 0; i < n_sample_syncs; i++) { /* note that the first sample is index 1, not 0 */ @@ -3802,7 +3802,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, sample_index = 0; timestamp = 0; - if (qt_atom_parser_get_remaining (&stsc) < 12 * n_samples_per_chunk) + if (!qt_atom_parser_has_remaining (&stsc, 12 * n_samples_per_chunk)) goto corrupt_file; for (i = 0; i < n_samples_per_chunk; i++) { diff --git a/gst/qtdemux/qtdemux_dump.c b/gst/qtdemux/qtdemux_dump.c index fe2ed750..52ad1c4e 100644 --- a/gst/qtdemux/qtdemux_dump.c +++ b/gst/qtdemux/qtdemux_dump.c @@ -36,7 +36,7 @@ gboolean qtdemux_dump_mvhd (GstQTDemux * qtdemux, QtAtomParser * data, int depth) { - if (qt_atom_parser_get_remaining (data) < 100) + if (!qt_atom_parser_has_remaining (data, 100)) return FALSE; GST_LOG ("%*s version/flags: %08x", depth, "", GET_UINT32 (data)); @@ -112,7 +112,7 @@ qtdemux_dump_elst (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s n entries: %d", depth, "", num_entries); - if (qt_atom_parser_get_remaining (data) < (num_entries * (4 + 4 + 4))) + if (!qt_atom_parser_has_remaining (data, num_entries * (4 + 4 + 4))) return FALSE; for (i = 0; i < num_entries; i++) { @@ -163,7 +163,7 @@ qtdemux_dump_hdlr (GstQTDemux * qtdemux, QtAtomParser * data, int depth) guint32 version, type, subtype, manufacturer; const gchar *name; - if (qt_atom_parser_get_remaining (data) < (4 + 4 + 4 + 4 + 4 + 4 + 1)) + if (!qt_atom_parser_has_remaining (data, 4 + 4 + 4 + 4 + 4 + 4 + 1)) return FALSE; version = GET_UINT32 (data); @@ -189,7 +189,7 @@ qtdemux_dump_hdlr (GstQTDemux * qtdemux, QtAtomParser * data, int depth) guint len; len = qt_atom_parser_get_uint8_unchecked (data); - if (qt_atom_parser_get_remaining (data) >= len) { + if (qt_atom_parser_has_remaining (data, len)) { memcpy (buf, qt_atom_parser_peek_bytes_unchecked (data), len); buf[len] = '\0'; GST_LOG ("%*s name: %s", depth, "", buf); @@ -201,7 +201,7 @@ qtdemux_dump_hdlr (GstQTDemux * qtdemux, QtAtomParser * data, int depth) gboolean qtdemux_dump_vmhd (GstQTDemux * qtdemux, QtAtomParser * data, int depth) { - if (qt_atom_parser_get_remaining (data) < (4 + 4)) + if (!qt_atom_parser_has_remaining (data, 4 + 4)) return FALSE; GST_LOG ("%*s version/flags: %08x", depth, "", GET_UINT32 (data)); @@ -301,7 +301,7 @@ qtdemux_dump_stts (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s n entries: %d", depth, "", num_entries); - if (qt_atom_parser_get_remaining (data) < (num_entries * (4 + 4))) + if (!qt_atom_parser_has_remaining (data, num_entries * (4 + 4))) return FALSE; for (i = 0; i < num_entries; i++) { @@ -323,7 +323,7 @@ qtdemux_dump_stps (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s n entries: %d", depth, "", num_entries); - if (qt_atom_parser_get_remaining (data) < (num_entries * 4)) + if (!qt_atom_parser_has_remaining (data, num_entries * 4)) return FALSE; for (i = 0; i < num_entries; i++) { @@ -344,7 +344,7 @@ qtdemux_dump_stss (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s n entries: %d", depth, "", num_entries); - if (qt_atom_parser_get_remaining (data) < (num_entries * 4)) + if (!qt_atom_parser_has_remaining (data, num_entries * 4)) return FALSE; for (i = 0; i < num_entries; i++) { @@ -365,7 +365,7 @@ qtdemux_dump_stsc (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s n entries: %d", depth, "", num_entries); - if (qt_atom_parser_get_remaining (data) < (num_entries * (4 + 4 + 4))) + if (!qt_atom_parser_has_remaining (data, num_entries * (4 + 4 + 4))) return FALSE; for (i = 0; i < num_entries; i++) { @@ -394,8 +394,8 @@ qtdemux_dump_stsz (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s n entries: %d", depth, "", num_entries); #if 0 - if (qt_atom_parser_get_remaining (data) < (num_entries * 4))) - goto too_short; + if (!qt_atom_parser_has_remaining (data, num_entries * 4))) + return FALSE; for (i = 0; i < num_entries; i++) { GST_LOG ("%*s sample size: %u", depth, "", GET_UINT32 (data)); } @@ -416,7 +416,7 @@ qtdemux_dump_stco (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s n entries: %d", depth, "", num_entries); - if (qt_atom_parser_get_remaining (data) < (num_entries * 4)) + if (!qt_atom_parser_has_remaining (data, num_entries * 4)) return FALSE; for (i = 0; i < num_entries; i++) { @@ -437,7 +437,7 @@ qtdemux_dump_ctts (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s n entries: %d", depth, "", num_entries); - if (qt_atom_parser_get_remaining (data) < (num_entries * (4 + 4))) + if (!qt_atom_parser_has_remaining (data, num_entries * (4 + 4))) return FALSE; for (i = 0; i < num_entries; i++) { @@ -460,7 +460,7 @@ qtdemux_dump_co64 (GstQTDemux * qtdemux, QtAtomParser * data, int depth) GST_LOG ("%*s version/flags: %08x", depth, "", ver_flags); GST_LOG ("%*s n entries: %d", depth, "", num_entries); - if (qt_atom_parser_get_remaining (data) < (num_entries * 8)) + if (!qt_atom_parser_has_remaining (data, num_entries * 8)) return FALSE; for (i = 0; i < num_entries; i++) { @@ -473,7 +473,7 @@ qtdemux_dump_co64 (GstQTDemux * qtdemux, QtAtomParser * data, int depth) gboolean qtdemux_dump_dcom (GstQTDemux * qtdemux, QtAtomParser * data, int depth) { - if (qt_atom_parser_get_remaining (data) < 4) + if (!qt_atom_parser_has_remaining (data, 4)) return FALSE; GST_LOG ("%*s compression type: %" GST_FOURCC_FORMAT, depth, "", @@ -484,7 +484,7 @@ qtdemux_dump_dcom (GstQTDemux * qtdemux, QtAtomParser * data, int depth) gboolean qtdemux_dump_cmvd (GstQTDemux * qtdemux, QtAtomParser * data, int depth) { - if (qt_atom_parser_get_remaining (data) < 4) + if (!qt_atom_parser_has_remaining (data, 4)) return FALSE; GST_LOG ("%*s length: %d", depth, "", GET_UINT32 (data)); @@ -508,7 +508,7 @@ static gboolean qtdemux_node_dump_foreach (GNode * node, gpointer qtdemux) { QtAtomParser parser; - guint8 *buffer = (guint8 *) node->data; + guint8 *buffer = (guint8 *) node->data; // FIXME: move to byte reader guint32 node_length; guint32 fourcc; const QtNodeType *type; -- cgit