From b127354429edc7d0c45bafaa8e0bf20d20dc10f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Fri, 17 Aug 2018 16:39:16 +0200 Subject: [PATCH 1/4] Simplify string_from_unterminated by using strnlen() --- src/helper_functions.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/helper_functions.cpp b/src/helper_functions.cpp index ba8bd6d4..623fbc1d 100644 --- a/src/helper_functions.cpp +++ b/src/helper_functions.cpp @@ -28,14 +28,12 @@ #include "helper_functions.hpp" -#include +#include std::string string_from_unterminated(const char* data, size_t data_length) { - const char* termination = std::find(data, data + data_length, 0); - // if find returned the end iterator => no \0 found - const size_t string_length = termination == data + data_length ? data_length : termination - data; + const size_t StringLength = strnlen(data, data_length); - return std::string(data, string_length); + return std::string(data, StringLength); } From 6da77e2c644d04e6e459d12a133730af22b8c1dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Fri, 17 Aug 2018 16:39:49 +0200 Subject: [PATCH 2/4] Add documentation for parameters of string_from_unterminated --- src/helper_functions.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/helper_functions.hpp b/src/helper_functions.hpp index d138490b..d70cbc1e 100644 --- a/src/helper_functions.hpp +++ b/src/helper_functions.hpp @@ -37,6 +37,13 @@ Convert a C style string that may or may not be null terminated safely into a std::string. The string's termination is either set at the first \0 or after data_length characters. + + @param[in] data A c-string from which the std::string shall be + constructed. Does not need to be null terminated. + @param[in] data_length An upper bound for the string length (must be at most + the allocated length of `buffer`). If no null terminator is found in data, + then the resulting std::string will be null terminated at `data_length`. + */ std::string string_from_unterminated(const char* data, size_t data_length); From 35b3e596edacd2437c2c5d3dd2b5c9502626163d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Fri, 17 Aug 2018 16:41:05 +0200 Subject: [PATCH 3/4] Add overflow & overread checks to PngChunk::parseTXTChunk() This function was creating a lot of new pointers and strings without properly checking the array bounds. This commit adds several calls to enforce(), making sure that the pointers stay within bounds. Strings are now created using the helper function string_from_unterminated() to prevent overreads in the constructor of std::string. This fixes #400 --- src/pngchunk_int.cpp | 63 ++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/src/pngchunk_int.cpp b/src/pngchunk_int.cpp index e087e47c..f13594bd 100644 --- a/src/pngchunk_int.cpp +++ b/src/pngchunk_int.cpp @@ -34,6 +34,8 @@ #include "image.hpp" #include "error.hpp" #include "enforce.hpp" +#include "helper_functions.hpp" +#include "safe_op.hpp" // + standard includes #include @@ -133,6 +135,8 @@ namespace Exiv2 { if(type == zTXt_Chunk) { + enforce(data.size_ >= Safe::add(keysize, 2), Exiv2::kerCorruptedMetadata); + // Extract a deflate compressed Latin-1 text chunk // we get the compression method after the key @@ -149,11 +153,13 @@ namespace Exiv2 { // compressed string after the compression technique spec const byte* compressedText = data.pData_ + keysize + 2; unsigned int compressedTextSize = data.size_ - keysize - 2; + enforce(compressedTextSize < data.size_, kerCorruptedMetadata); zlibUncompress(compressedText, compressedTextSize, arr); } else if(type == tEXt_Chunk) { + enforce(data.size_ >= Safe::add(keysize, 1), Exiv2::kerCorruptedMetadata); // Extract a non-compressed Latin-1 text chunk // the text comes after the key, but isn't null terminated @@ -164,6 +170,7 @@ namespace Exiv2 { } else if(type == iTXt_Chunk) { + enforce(data.size_ >= Safe::add(keysize, 3), Exiv2::kerCorruptedMetadata); const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_], '\0'); enforce(nullSeparators >= 2, Exiv2::kerCorruptedMetadata); @@ -178,41 +185,45 @@ namespace Exiv2 { enforce(compressionMethod == 0x00, Exiv2::kerCorruptedMetadata); // language description string after the compression technique spec - std::string languageText((const char*)(data.pData_ + keysize + 3)); - unsigned int languageTextSize = static_cast(languageText.size()); + const size_t languageTextMaxSize = data.size_ - keysize - 3; + std::string languageText = + string_from_unterminated((const char*)(data.pData_ + Safe::add(keysize, 3)), languageTextMaxSize); + const unsigned int languageTextSize = static_cast(languageText.size()); + + enforce(data.size_ >= Safe::add(static_cast(Safe::add(keysize, 4)), languageTextSize), + Exiv2::kerCorruptedMetadata); // translated keyword string after the language description - std::string translatedKeyText((const char*)(data.pData_ + keysize + 3 + languageTextSize +1)); - unsigned int translatedKeyTextSize = static_cast(translatedKeyText.size()); + std::string translatedKeyText = + string_from_unterminated((const char*)(data.pData_ + keysize + 3 + languageTextSize + 1), + data.size_ - (keysize + 3 + languageTextSize + 1)); + const unsigned int translatedKeyTextSize = static_cast(translatedKeyText.size()); - if ( compressionFlag == 0x00 ) - { - // then it's an uncompressed iTXt chunk -#ifdef DEBUG - std::cout << "Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field\n"; -#endif + if ((compressionFlag == 0x00) || (compressionFlag == 0x01 && compressionMethod == 0x00)) { + enforce(Safe::add(static_cast(keysize + 3 + languageTextSize + 1), + Safe::add(translatedKeyTextSize, 1u)) <= data.size_, + Exiv2::kerCorruptedMetadata); - // the text comes after the translated keyword, but isn't null terminated const byte* text = data.pData_ + keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1; - long textsize = data.size_ - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1); + const long textsize = data.size_ - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1); - arr.alloc(textsize); - arr = DataBuf(text, textsize); - } - else if ( compressionFlag == 0x01 && compressionMethod == 0x00 ) - { - // then it's a zlib compressed iTXt chunk + if (compressionFlag == 0x00) { + // then it's an uncompressed iTXt chunk #ifdef DEBUG - std::cout << "Exiv2::PngChunk::parseTXTChunk: We found a zlib compressed iTXt field\n"; + std::cout << "Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field\n"; #endif - // the compressed text comes after the translated keyword, but isn't null terminated - const byte* compressedText = data.pData_ + keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1; - long compressedTextSize = data.size_ - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1); + arr.alloc(textsize); + arr = DataBuf(text, textsize); + } else if (compressionFlag == 0x01 && compressionMethod == 0x00) { + // then it's a zlib compressed iTXt chunk +#ifdef DEBUG + std::cout << "Exiv2::PngChunk::parseTXTChunk: We found a zlib compressed iTXt field\n"; +#endif - zlibUncompress(compressedText, compressedTextSize, arr); - } - else - { + // the compressed text comes after the translated keyword, but isn't null terminated + zlibUncompress(text, textsize, arr); + } + } else { // then it isn't zlib compressed and we are sunk #ifdef DEBUG std::cerr << "Exiv2::PngChunk::parseTXTChunk: Non-standard iTXt compression method.\n"; From dadd1d19f9eb547437927d2a5c4cbae561c8c2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Fri, 17 Aug 2018 16:49:27 +0200 Subject: [PATCH 4/4] Add reproducer for #400 to the test suite --- test/data/issue_400_poc1 | Bin 0 -> 372 bytes test/data/issue_400_poc2 | Bin 0 -> 8759 bytes tests/bugfixes/github/test_issue_400.py | 22 ++++++++++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 test/data/issue_400_poc1 create mode 100644 test/data/issue_400_poc2 create mode 100644 tests/bugfixes/github/test_issue_400.py diff --git a/test/data/issue_400_poc1 b/test/data/issue_400_poc1 new file mode 100644 index 0000000000000000000000000000000000000000..8c8491c0699d3d1114da567b6b6e9518a362918c GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv(Ey(i*Z(j86qxz{Oxl?<#xv6x zGFHw3@|jA4{DK))n@`^!0pu}Og+!Dvbg;^L06Clm9+AaB8pQTsa66f82V|ssx;Tbt zoZox#G;f1~fNNk9XV`-435++IObj?h5}5u@e~@q7tSw$OU42hWLvl-9L!b5Wq(i=| z_1MghE;(h-93k+5ZHBqd6_<+>x+5&y#hyq+?%!C8<`)MX5lF!N|bSRM)^r*U&J;z}U*bz{;0L z1Vuw`eoAIqC5i?kD`P_|6GMoGiCWXn12ss3YzWRzD=AMbO8x)8fgveX!8128JvAsb SF{QHbWU38N5re0zp9=uZBzpM( literal 0 HcmV?d00001 diff --git a/test/data/issue_400_poc2 b/test/data/issue_400_poc2 new file mode 100644 index 0000000000000000000000000000000000000000..479d02070cd051dae4b57dc937f3bfd2cb0835ac GIT binary patch literal 8759 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 Q`H!e9uO?S6WAycZ0M|nb_W%F@ literal 0 HcmV?d00001 diff --git a/tests/bugfixes/github/test_issue_400.py b/tests/bugfixes/github/test_issue_400.py new file mode 100644 index 00000000..9e87977a --- /dev/null +++ b/tests/bugfixes/github/test_issue_400.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +import system_tests + + +class parseTXTChunkOutOfBoundsRead(metaclass=system_tests.CaseMeta): + + url = "https://github.com/Exiv2/exiv2/issues/400" + + filenames = [ + system_tests.path("$data_path/issue_400_poc" + str(i)) for i in (1, 2) + ] + + commands = ["$exiv2 " + fname for fname in filenames] + stdout = [""] * 2 + stderr = [ + """$exiv2_exception_message """ + fname + """: +$kerCorruptedMetadata +""" + for fname in filenames + ] + retval = [1] * 2