diff --git a/src/quicktimevideo.cpp b/src/quicktimevideo.cpp index 5cd34bb058..2d6cab1058 100644 --- a/src/quicktimevideo.cpp +++ b/src/quicktimevideo.cpp @@ -848,7 +848,7 @@ void QuickTimeVideo::CameraTagsDecoder(size_t size) { void QuickTimeVideo::userDataDecoder(size_t outer_size, size_t recursion_depth) { enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata); - size_t cur_pos = io_->tell(); + const size_t start_pos = io_->tell(); const TagVocabulary* td; const TagVocabulary* tv; const TagVocabulary* tv_internal; @@ -859,6 +859,7 @@ void QuickTimeVideo::userDataDecoder(size_t outer_size, size_t recursion_depth) std::memset(buf.data(), 0x0, buf.size()); while ((size_internal / 4 != 0) && (size_internal > 0)) { + const size_t loop_start_pos = io_->tell(); buf.data()[4] = '\0'; io_->readOrThrow(buf.data(), 4); const size_t size = buf.read_uint32(0, bigEndian); @@ -910,9 +911,11 @@ void QuickTimeVideo::userDataDecoder(size_t outer_size, size_t recursion_depth) else if (td) tagDecoder(buf, size - 8, recursion_depth + 1); + + enforce(io_->tell() <= loop_start_pos + size, Exiv2::ErrorCode::kerCorruptedMetadata); } - io_->seek(cur_pos + outer_size, BasicIo::beg); + io_->seek(start_pos + outer_size, BasicIo::beg); } // QuickTimeVideo::userDataDecoder void QuickTimeVideo::NikonTagsDecoder(size_t size) { diff --git a/test/data/issue_ghsa_fgw8_p7pr_37cp_poc.mov b/test/data/issue_ghsa_fgw8_p7pr_37cp_poc.mov new file mode 100644 index 0000000000..b27037e2ff Binary files /dev/null and b/test/data/issue_ghsa_fgw8_p7pr_37cp_poc.mov differ diff --git a/tests/bugfixes/github/test_issue_ghsa_fgw8_p7pr_37cp.py b/tests/bugfixes/github/test_issue_ghsa_fgw8_p7pr_37cp.py new file mode 100644 index 0000000000..4b570e232d --- /dev/null +++ b/tests/bugfixes/github/test_issue_ghsa_fgw8_p7pr_37cp.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path, check_no_ASAN_UBSAN_errors + +class QuickTimeVideo_userDataDecoder_infinite_loop(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/security/advisories/GHSA-fgw8-p7pr-37cp + """ + url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-fgw8-p7pr-37cp" + + filename = path("$data_path/issue_ghsa_fgw8_p7pr_37cp_poc.mov") + commands = ["$exiv2 $filename"] + stdout = [""] + stderr = [ + """$exiv2_exception_message """ + filename + """: +$kerCorruptedMetadata +"""] + retval = [1] diff --git a/tests/regression_tests/test_regression_allfiles.py b/tests/regression_tests/test_regression_allfiles.py index 8601cca3d0..d1d9b7926b 100644 --- a/tests/regression_tests/test_regression_allfiles.py +++ b/tests/regression_tests/test_regression_allfiles.py @@ -124,6 +124,7 @@ def get_valid_files(data_dir): "issue_ghsa_38h4_fx85_qcx7_poc.tiff", "issue_ghsa_496f_x7cq_cq39_poc.jpg", "issue_ghsa_9mxq_4j5g_5wrp.crw", + "issue_ghsa_fgw8_p7pr_37cp_poc.mov", "pocIssue283.jpg", "poc_1522.jp2", "xmpsdk.xmp",