From: Justin Chadwell Date: Mon, 13 Jul 2020 09:37:19 +0000 (+0100) Subject: qtdemux: fix crashes when input stream contained no stsd entries X-Git-Tag: 1.19.3~509^2~482 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e6f66f46818f61e8cd111c9f951955d12bc19c54;p=platform%2Fupstream%2Fgstreamer.git 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: --- diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c index 00956a6..b8c14fa 100644 --- a/gst/isomp4/qtdemux.c +++ b/gst/isomp4/qtdemux.c @@ -10654,6 +10654,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 44aa9b4..cd9dc69 100644 --- a/tests/check/elements/qtdemux.c +++ b/tests/check/elements/qtdemux.c @@ -22,6 +22,7 @@ #include "qtdemux.h" #include +#include 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);