mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
qtdemux: fix allocation explosion with stsd entries
Previously, the user input for stsd entries is trusted completely, and so a maliciously crafted file could choose the length of the stsd entries arbitrarily and cause qtdemux to try to allocate up to 2GB of memory (half of a 32 bit max int). This patch fixes this by sanity checking the stsd input against the size of the entire stsd atom. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/670>
This commit is contained in:
parent
e6f66f4681
commit
738f32d5d0
2 changed files with 56 additions and 1 deletions
|
@ -10654,8 +10654,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->stsd_entries_length = stsd_entry_count = QT_UINT32 (stsd_data + 12);
|
stream->stsd_entries_length = stsd_entry_count = QT_UINT32 (stsd_data + 12);
|
||||||
if (stream->stsd_entries_length == 0)
|
/* each stsd entry must contain at least 8 bytes */
|
||||||
|
if (stream->stsd_entries_length == 0
|
||||||
|
|| stream->stsd_entries_length > stsd_len / 8) {
|
||||||
|
stream->stsd_entries_length = 0;
|
||||||
goto corrupt_file;
|
goto corrupt_file;
|
||||||
|
}
|
||||||
stream->stsd_entries = g_new0 (QtDemuxStreamStsdEntry, stsd_entry_count);
|
stream->stsd_entries = g_new0 (QtDemuxStreamStsdEntry, stsd_entry_count);
|
||||||
GST_LOG_OBJECT (qtdemux, "stsd len: %d", stsd_len);
|
GST_LOG_OBJECT (qtdemux, "stsd len: %d", stsd_len);
|
||||||
GST_LOG_OBJECT (qtdemux, "stsd entry count: %u", stsd_entry_count);
|
GST_LOG_OBJECT (qtdemux, "stsd entry count: %u", stsd_entry_count);
|
||||||
|
|
|
@ -123,6 +123,56 @@ GST_START_TEST (test_qtdemux_fuzzed0)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_qtdemux_fuzzed1)
|
||||||
|
{
|
||||||
|
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 claims it contains more stsd entries than it can possibly have,
|
||||||
|
* 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"
|
||||||
|
"oQkgHhEI1AAAAARozjyAAAAAIWW4BA5///wRRQAfHAxwABAJkxWTk6xWuuuupaupa6668AAAABJB"
|
||||||
|
"4CBX8Zd3d3d3d3d3eJ7E8ZAAAABWQeBAO+opFAYoDFAYoDFAYkeKAzx4oDFAYkcPHBQGePPHF6jj"
|
||||||
|
"HP0Qdj/og7H/SHY/6jsf9R2P+o7H/Udj/qOx/1HY/6jsf9R2P+o7H/Udj/qOx/1HY/AAAAAGQeBg"
|
||||||
|
"O8IwAAAABkHggDvCMAAAA1dtb292AAAAbG12aGQAAAAA1lbpxdZW6cYAAAfQAAAH0AABAAABAAAA"
|
||||||
|
"AAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
"AAAAAAAAAAAAAAAAAAACAAACpnRyYWsAAABcdGtoZAAAAAfWVunF1lbpxgAAAAEAAAAAAAAH0AAA"
|
||||||
|
"AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAQAAAAEA"
|
||||||
|
"AAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAB9AAAAAAAAEAAAAAAeFtZGlhAAAAIG1kaGQAAAAA"
|
||||||
|
"1lbpxdZW6cYAAAH0AAAB9FXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVv"
|
||||||
|
"SGFuZGxlcgAAAAGMbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAA"
|
||||||
|
"AAABAAAADHVybCAAAAABAAABTHN0YmwAAADAc3RzZAAAAADv/wABAAAAsGF2YzEAAAAAAAAAAQAA"
|
||||||
|
"AAAAAAAAAAAAAAAAAAAAQABAAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
"AAAAAAAAAAAY//8AAAAjYXZjQwFCwAz/4QAMZ0LADJWhCSAeEQjUAQAEaM48gAAAABRidHJ0AAAA"
|
||||||
|
"AAAAAAAAAAYIAAAAE2NvbHJuY2x4AAYAAQAGAAAAABBwYXNwAAAAAQAAAAEAAAAYc3R0cwAAAAAA"
|
||||||
|
"AAABAAAABQAAAGQAAAAUc3RzcwAAAAAAAAABAAAAAQAAABxzdHNjAAAAAAAAAAEAAAABAAAABQAA"
|
||||||
|
"AAEAAAAoc3RzegAAAAAAAAAAAAAABQAAAD0AAAAWAAAAWgAAAAoAAAAKAAAAFHN0Y28AAAAAAAAA"
|
||||||
|
"AQAAADAAAAA9dWR0YQAAADVtZXRhAAAAAAAAACFoZGxyAAAAAG1obHJtZGlyAAAAAAAAAAAAAAAA"
|
||||||
|
"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)
|
GST_START_TEST (test_qtdemux_input_gap)
|
||||||
{
|
{
|
||||||
GstElement *qtdemux;
|
GstElement *qtdemux;
|
||||||
|
@ -698,6 +748,7 @@ qtdemux_suite (void)
|
||||||
|
|
||||||
suite_add_tcase (s, tc_chain);
|
suite_add_tcase (s, tc_chain);
|
||||||
tcase_add_test (tc_chain, test_qtdemux_fuzzed0);
|
tcase_add_test (tc_chain, test_qtdemux_fuzzed0);
|
||||||
|
tcase_add_test (tc_chain, test_qtdemux_fuzzed1);
|
||||||
tcase_add_test (tc_chain, test_qtdemux_input_gap);
|
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_duplicated_moov);
|
||||||
tcase_add_test (tc_chain, test_qtdemux_stream_change);
|
tcase_add_test (tc_chain, test_qtdemux_stream_change);
|
||||||
|
|
Loading…
Reference in a new issue