summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Chadwell <justin.chadwell@pexip.com>2020-07-13 10:37:19 +0100
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>2020-09-25 12:41:06 +0000
commit7241f5d9c21ee3ead0294d6480a6fe5af4bf3b74 (patch)
tree92284040cd157e09188e5d1d51862180fcecdf3d
parentf11335034d1d901d73bef6c4da44bdb5a2cb44c1 (diff)
qtdemux: fix crashes when input stream contained no stsd entries
During trak parsing, we need to check for the existence of stsd_entries, otherwise, we end up with a NULL pointer to them. It is entirely possible for the stsd to exist, but for it to have no entries, which the previous checks did not take into account. This patch adds a simply check to ensure that all files that do not contain a stsd entry are deemed corrupt, and adds a test case to prevent a regression. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/749>
-rw-r--r--gst/isomp4/qtdemux.c2
-rw-r--r--tests/check/elements/qtdemux.c52
2 files changed, 54 insertions, 0 deletions
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index f22890eb9..76924cb9e 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -10657,6 +10657,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
}
stream->stsd_entries_length = stsd_entry_count = QT_UINT32 (stsd_data + 12);
+ if (stream->stsd_entries_length == 0)
+ goto corrupt_file;
stream->stsd_entries = g_new0 (QtDemuxStreamStsdEntry, stsd_entry_count);
GST_LOG_OBJECT (qtdemux, "stsd len: %d", stsd_len);
GST_LOG_OBJECT (qtdemux, "stsd entry count: %u", stsd_entry_count);
diff --git a/tests/check/elements/qtdemux.c b/tests/check/elements/qtdemux.c
index 44aa9b45c..cd9dc6950 100644
--- a/tests/check/elements/qtdemux.c
+++ b/tests/check/elements/qtdemux.c
@@ -22,6 +22,7 @@
#include "qtdemux.h"
#include <glib/gprintf.h>
+#include <gst/check/gstharness.h>
typedef struct
{
@@ -72,6 +73,56 @@ qtdemux_pad_added_cb (GstElement * element, GstPad * pad, CommonTestData * data)
(GstPadProbeCallback) qtdemux_probe, data, NULL);
}
+GST_START_TEST (test_qtdemux_fuzzed0)
+{
+ GstHarness *h;
+ GstBuffer *buf;
+ guchar *fuzzed_qtdemux;
+ gsize fuzzed_qtdemux_len;
+
+ /* The goal of this test is to check that qtdemux can properly handle
+ * a stream that does not contain any stsd entries, by correctly identifying
+ * the case and erroring out appropriately.
+ */
+
+ h = gst_harness_new_parse ("qtdemux");
+ gst_harness_set_src_caps_str (h, "video/quicktime");
+
+ fuzzed_qtdemux =
+ g_base64_decode
+ ("AAAAIGZ0eXBtcDQyAAAAAG1wNDJtcDQxaXNvbWlzbzIAAAAIZnJlZQAAAMltZGF0AAAADGdCwAyV"
+ "oQkgHhEI1AAAAARozjyAAAAAIWW4AA5///wRRQAfHAxwABAJkxWTk6xWuuuupaupa6668AAAABJB"
+ "4CBX8Zd3d3d3d3d3eJ7E8ZAAAABWQeBAO/wpFAYoDFAYoDFAYkeKAzx4+gAA+kcPHBQGePPHF6jj"
+ "HP0Qdj/og7H/SHY/6jsf9R2P+o7H/Udj/qOx/1HY/6jsf9R2P+o7H/Udj/qOx/1HY/AAAAAGQeBg"
+ "O8IwAAAABkHggDvCMAAAA1dtb292AAAAbG12aGQAAAAA1lbpxdZW6cYAAAfQAAAH0AABAAABAAAA"
+ "AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAAACAAACpnRyYWsAAABcdGtoZAAAAAfWVunF1lbpxgAAAAEAAAAAAAAH0AAA"
+ "AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAQAAAAEA"
+ "AAAAACRlZHRzAAAAHGVsc3QAAIAAAAAAAQAAB9AAAAAAAAEAAAAAAeFtZGlhAAAAIG1kaGQAAAAA"
+ "1lbpxdZW6cYAAAH0AAAB9FXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZUAAAAAAAAAAAAAAAFZpZGVv"
+ "SGFuZGxlcgAAAAGMbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAA"
+ "AAABAAAADHVybCAAAAABAAABTHN0YmwAAADAc3RzZAAAAAAAAAAAAAAAsGF2YzEAAAAAAAAAAQAA"
+ "AAAAAAAZAAAAAAAAAAAAQABAAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAY//8AAAAjYXZjQwFCwAz/4QAMZ0LADJWhCSAeEQjUAQAEaM48gAAAABRidHJ0AAAA"
+ "AAAAAAAAAAYIAAAAE2NvbHJuY2x4AAYAAQAGAAAAABBwYXNwAAAAAQAAAAEAAAAYc3R0cwAAAAAA"
+ "AAABAAAABQAAAAAAAAAUc3RzcwAAAAAAAAABAAAAAQAAABxzdHNjAAAAAAAAAAEAAAABAAAABQAA"
+ "AAEAAAAoc3RzegAAAAAAAAAAAAAAAQAAAAAAAAAWAAAAWgAAAAoAAAAKAAAAFHN0Y28AAAAAAAAA"
+ "AQAAADAAAAA9dWR0YQAAADVtZXRhAAAAAAAAACFoZGxyAAAAAG1obJJtZGlyAAAAAAAAAAAAAAAA"
+ "AAAAAAhpbHN0AAAAPXVkdGEAAAA1bWV0YQAAAAAAAAAhaGRscgAAAABtaGxybWRpcgAAAAAAAAAA"
+ "AAAAAAAAAAAIaWxzdA==", &fuzzed_qtdemux_len);
+
+ buf = gst_buffer_new_and_alloc (fuzzed_qtdemux_len);
+ gst_buffer_fill (buf, 0, fuzzed_qtdemux, fuzzed_qtdemux_len);
+ fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK);
+
+ fail_unless (gst_harness_buffers_received (h) == 0);
+
+ g_free (fuzzed_qtdemux);
+ gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
GST_START_TEST (test_qtdemux_input_gap)
{
GstElement *qtdemux;
@@ -646,6 +697,7 @@ qtdemux_suite (void)
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
+ tcase_add_test (tc_chain, test_qtdemux_fuzzed0);
tcase_add_test (tc_chain, test_qtdemux_input_gap);
tcase_add_test (tc_chain, test_qtdemux_duplicated_moov);
tcase_add_test (tc_chain, test_qtdemux_stream_change);