1 Star 0 Fork 20

shirely/exiv2

forked from src-openEuler/exiv2 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
CVE-2018-16336.patch 7.03 KB
一键复制 编辑 原始数据 按行查看 历史
dogsheng 提交于 2019-12-25 15:45 . Package init
From 35b3e596edacd2437c2c5d3dd2b5c9502626163d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <dan.cermak@cgc-instruments.com>
Date: Fri, 17 Aug 2018 16:41:05 +0200
Subject: [PATCH] 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.cpp b/src/pngchunk.cpp
index e087e47cb..f13594bd8 100644
--- a/src/pngchunk.cpp
+++ b/src/pngchunk.cpp
@@ -34,6 +34,7 @@
#include "image.hpp"
#include "error.hpp"
#include "enforce.hpp"
+#include "safe_op.hpp"
// + standard includes
#include <sstream>
@@ -55,6 +54,13 @@ EXIV2_RCSID("@(#) $Id: pngchunk.cpp 3777 2015-05-02 11:55:40Z ahuggel $")
#include <zlib.h> // To uncompress or compress text chunk
+/* Added as support of CVE-2018-16336 */
+std::string string_from_unterminated(const char* data, size_t data_length)
+{
+ const size_t StringLength = strnlen(data, data_length);
+
+ return std::string(data, StringLength);
+}
/*
URLs to find informations about PNG chunks :
@@ -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,7 +170,8 @@ 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,40 +185,44 @@ 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<unsigned int>(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<unsigned int>(languageText.size());
+
+ enforce(data.size_ >= Safe::add(static_cast<unsigned int>(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<unsigned int>(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<unsigned int>(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<unsigned int>(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";
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/shirely16/exiv2.git
git@gitee.com:shirely16/exiv2.git
shirely16
exiv2
exiv2
master

搜索帮助