From 9d45a1dcae165c2a471b776d4bc1010f137c2fd2 Mon Sep 17 00:00:00 2001 From: Kevin Backhouse Date: Wed, 7 Feb 2024 21:15:14 +0000 Subject: [PATCH 1/2] Regression test for https://github.com/Exiv2/exiv2/security/advisories/GHSA-g9xm-7538-mq8w --- test/data/issue_ghsa_g9xm_7538_mq8w_poc.mov | Bin 0 -> 248 bytes .../github/test_issue_ghsa_g9xm_7538_mq8w.py | 17 +++++++++++++++++ .../test_regression_allfiles.py | 1 + 3 files changed, 18 insertions(+) create mode 100644 test/data/issue_ghsa_g9xm_7538_mq8w_poc.mov create mode 100644 tests/bugfixes/github/test_issue_ghsa_g9xm_7538_mq8w.py diff --git a/test/data/issue_ghsa_g9xm_7538_mq8w_poc.mov b/test/data/issue_ghsa_g9xm_7538_mq8w_poc.mov new file mode 100644 index 0000000000000000000000000000000000000000..a1ee87782b2e82f22b324310f9154be89e6218a7 GIT binary patch literal 248 zcmZQzV30^FsVvAW&d*hVgZ~N)3=H0(DJ6+OTEWjb#2rYBF)%TlfGZ)y`2YVuAti8m Vuu7l?Fo27~7%&MSjZKI=T>u+_So#0} literal 0 HcmV?d00001 diff --git a/tests/bugfixes/github/test_issue_ghsa_g9xm_7538_mq8w.py b/tests/bugfixes/github/test_issue_ghsa_g9xm_7538_mq8w.py new file mode 100644 index 0000000000..2ff1d4ecc5 --- /dev/null +++ b/tests/bugfixes/github/test_issue_ghsa_g9xm_7538_mq8w.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, CopyTmpFiles, path, check_no_ASAN_UBSAN_errors + +class QuickTimeVideoNikonTagsDecoderOutOfBoundsRead(metaclass=CaseMeta): + """ + Regression test for the bug described in: + https://github.com/Exiv2/exiv2/security/advisories/GHSA-g9xm-7538-mq8w + """ + url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-g9xm-7538-mq8w" + + filename = path("$data_path/issue_ghsa_g9xm_7538_mq8w_poc.mov") + commands = ["$exiv2 $filename"] + retval = [1] + + compare_stdout = check_no_ASAN_UBSAN_errors + compare_stderr = check_no_ASAN_UBSAN_errors diff --git a/tests/regression_tests/test_regression_allfiles.py b/tests/regression_tests/test_regression_allfiles.py index 426a0c36f4..49ece7d635 100644 --- a/tests/regression_tests/test_regression_allfiles.py +++ b/tests/regression_tests/test_regression_allfiles.py @@ -117,6 +117,7 @@ def get_valid_files(data_dir): "issue_ghsa_7569_phvm_vwc2_poc.jp2", "issue_ghsa_mxw9_qx4c_6m8v_poc.jp2", "issue_ghsa_hrw9_ggg3_3r4r_poc.jpg", + "issue_ghsa_g9xm_7538_mq8w_poc.mov", "pocIssue283.jpg", "poc_1522.jp2", "xmpsdk.xmp", From 79ab2f6ae21059e394883f6c8e3b2a0bb97e7e48 Mon Sep 17 00:00:00 2001 From: Kevin Backhouse Date: Wed, 7 Feb 2024 21:37:59 +0000 Subject: [PATCH 2/2] Credit to OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64151 nul-terminate buf to avoid out-of-bounds read --- src/quicktimevideo.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/quicktimevideo.cpp b/src/quicktimevideo.cpp index 5c3a25bdf4..fccc08dc9f 100644 --- a/src/quicktimevideo.cpp +++ b/src/quicktimevideo.cpp @@ -906,7 +906,7 @@ void QuickTimeVideo::userDataDecoder(size_t size_external) { void QuickTimeVideo::NikonTagsDecoder(size_t size_external) { size_t cur_pos = io_->tell(); - DataBuf buf(200); + DataBuf buf(201); DataBuf buf2(4 + 1); uint32_t TagID = 0; uint16_t dataLength = 0; @@ -1027,14 +1027,16 @@ void QuickTimeVideo::NikonTagsDecoder(size_t size_external) { std::memset(buf.data(), 0x0, buf.size()); // Sanity check with an "unreasonably" large number - if (dataLength > 200) { + if (dataLength >= buf.size()) { #ifndef SUPPRESS_WARNINGS EXV_ERROR << "Xmp.video Nikon Tags, dataLength was found to be larger than 200." << " Entries considered invalid. Not Processed.\n"; #endif io_->seek(io_->tell() + dataLength, BasicIo::beg); + buf.data()[0] = '\0'; } else { io_->readOrThrow(buf.data(), dataLength); + buf.data()[dataLength] = '\0'; } if (td) {