[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#963591: marked as done (buster-pu: package exiv2/0.25-4+deb10u1)



Your message dated Sat, 01 Aug 2020 12:51:28 +0100
with message-id <43535efb498a168cf81452ca0c326f004f46adc6.camel@adam-barratt.org.uk>
and subject line Closing bugs for fixes included in 10.5 point release
has caused the Debian Bug report #963591,
regarding buster-pu: package exiv2/0.25-4+deb10u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
963591: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=963591
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu

I have prepared an update for exiv2 in jessie (0.24-4.1+deb8u2) related
to CVE-2018-16336 and also including a minor fix to the previous patch
for CVE-2018-10958 and CVE-2018-10999.

The patch for the jessie package applied to the stretch exiv2 package
with only one small change required.  I corresponded with the exiv2
maintainers and also Salvatore about whether I should upload this as a
security update.

Salvatore indicated that for stable he was inclined to consider that
this did not warrant a DSA and he recommended that I proceed with a
stable update for the next point release.

Please find attached the source debdiff.

Regards,

-Roberto
diff -Nru exiv2-0.25/debian/changelog exiv2-0.25/debian/changelog
--- exiv2-0.25/debian/changelog	2018-06-27 08:09:36.000000000 -0400
+++ exiv2-0.25/debian/changelog	2018-10-20 22:43:10.000000000 -0400
@@ -1,3 +1,13 @@
+exiv2 (0.25-3.1+deb9u2) stretch-security; urgency=high
+
+  * Non-maintainer upload by the Security Team.
+  * Minor adjustment to the patch for CVE-2018-10958 and CVE-2018-10999.  The
+    initial patch was overly restrictive in counting PNG image chunks.
+  * CVE-2018-16336: remote denial of service (heap-based buffer over-read) via
+    a crafted image file.
+
+ -- Roberto C. Sanchez <roberto@debian.org>  Sat, 20 Oct 2018 22:43:10 -0400
+
 exiv2 (0.25-3.1+deb9u1) stretch-security; urgency=high
 
   * Non-maintainer upload by the Security Team.
diff -Nru exiv2-0.25/debian/patches/CVE-2018-10958_10999_1_of_2.patch exiv2-0.25/debian/patches/CVE-2018-10958_10999_1_of_2.patch
--- exiv2-0.25/debian/patches/CVE-2018-10958_10999_1_of_2.patch	2018-06-27 08:09:36.000000000 -0400
+++ exiv2-0.25/debian/patches/CVE-2018-10958_10999_1_of_2.patch	2018-10-20 22:43:10.000000000 -0400
@@ -32,7 +32,7 @@
          }
          else if(type == iTXt_Chunk)
          {
-+            const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_-1], '\0');
++            const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_], '\0');
 +            if (nullSeparators < 2) throw Error(58);
 +
              // Extract a deflate compressed or uncompressed UTF-8 text chunk
diff -Nru exiv2-0.25/debian/patches/CVE-2018-10958_10999_2_of_2.patch exiv2-0.25/debian/patches/CVE-2018-10958_10999_2_of_2.patch
--- exiv2-0.25/debian/patches/CVE-2018-10958_10999_2_of_2.patch	2018-06-27 08:09:36.000000000 -0400
+++ exiv2-0.25/debian/patches/CVE-2018-10958_10999_2_of_2.patch	2018-10-20 22:43:10.000000000 -0400
@@ -14,7 +14,7 @@
 @@ -159,14 +159,24 @@
          else if(type == iTXt_Chunk)
          {
-             const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_-1], '\0');
+             const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_], '\0');
 -            if (nullSeparators < 2) throw Error(58);
 +            if (nullSeparators < 2) throw Error(58, "iTXt chunk: not enough null separators");
  
diff -Nru exiv2-0.25/debian/patches/CVE-2018-16336.patch exiv2-0.25/debian/patches/CVE-2018-16336.patch
--- exiv2-0.25/debian/patches/CVE-2018-16336.patch	1969-12-31 19:00:00.000000000 -0500
+++ exiv2-0.25/debian/patches/CVE-2018-16336.patch	2018-10-20 22:43:10.000000000 -0400
@@ -0,0 +1,130 @@
+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(-)
+
+--- exiv2-stretch.git.orig/src/pngchunk.cpp
++++ exiv2-stretch.git/src/pngchunk.cpp
+@@ -40,6 +40,8 @@
+ #include "iptc.hpp"
+ #include "image.hpp"
+ #include "error.hpp"
++#include "helper_functions.hpp"
++#include "safe_op.hpp"
+ 
+ // + standard includes
+ #include <sstream>
+@@ -127,6 +129,8 @@
+ 
+         if(type == zTXt_Chunk)
+         {
++            if (data.size_ < Safe::add(keysize, 2)) throw Error(58);
++
+             // Extract a deflate compressed Latin-1 text chunk
+ 
+             // we get the compression method after the key
+@@ -143,11 +147,13 @@
+             // compressed string after the compression technique spec
+             const byte* compressedText      = data.pData_ + keysize + 2;
+             unsigned int compressedTextSize = data.size_  - keysize - 2;
++            if (compressedTextSize >= data.size_) throw Error(58);
+ 
+             zlibUncompress(compressedText, compressedTextSize, arr);
+         }
+         else if(type == tEXt_Chunk)
+         {
++            if (data.size_ < Safe::add(keysize, 1)) throw Error(58);
+             // Extract a non-compressed Latin-1 text chunk
+ 
+             // the text comes after the key, but isn't null terminated
+@@ -158,6 +164,7 @@
+         }
+         else if(type == iTXt_Chunk)
+         {
++            if (data.size_ < Safe::add(keysize, 3)) throw Error(58);
+             const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_], '\0');
+             if (nullSeparators < 2) throw Error(58, "iTXt chunk: not enough null separators");
+ 
+@@ -178,41 +185,43 @@
+             }
+ 
+             // 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());
+-            // 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());
++            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());
+ 
+-            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 (data.size_ < Safe::add(static_cast<unsigned int>(Safe::add(keysize, 4)), languageTextSize)) throw Error(58);
++            // translated keyword string after the language description
++            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) || (compressionFlag == 0x01 && compressionMethod == 0x00)) {
++                if (Safe::add(static_cast<unsigned int>(keysize + 3 + languageTextSize + 1),
++                                  Safe::add(translatedKeyTextSize, 1u)) > data.size_) throw Error(58);
+ 
+-                // 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";
diff -Nru exiv2-0.25/debian/patches/CVE-2018-16336_prereq.patch exiv2-0.25/debian/patches/CVE-2018-16336_prereq.patch
--- exiv2-0.25/debian/patches/CVE-2018-16336_prereq.patch	1969-12-31 19:00:00.000000000 -0500
+++ exiv2-0.25/debian/patches/CVE-2018-16336_prereq.patch	2018-10-20 22:43:10.000000000 -0400
@@ -0,0 +1,105 @@
+--- /dev/null
++++ exiv2-stretch.git/src/helper_functions.cpp
+@@ -0,0 +1,38 @@
++// ********************************************************* -*- C++ -*-
++/*
++ * Copyright (C) 2004-2018 Exiv2 authors
++ * This program is part of the Exiv2 distribution.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
++ */
++/*!
++  @file    helper_functions.cpp
++  @brief   A collection of helper functions
++  @author  Dan Čermák (D4N)
++           <a href="mailto:dan.cermak@cgc-instruments.com";>dan.cermak@cgc-instruments.com</a>
++  @date    25-May-18, D4N: created
++ */
++
++#include "helper_functions.hpp"
++
++#include <string.h>
++
++
++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);
++}
+--- /dev/null
++++ exiv2-stretch.git/src/helper_functions.hpp
+@@ -0,0 +1,49 @@
++// ********************************************************* -*- C++ -*-
++/*
++ * Copyright (C) 2004-2018 Exiv2 authors
++ * This program is part of the Exiv2 distribution.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
++ */
++/*!
++  @file    helper_functions.hpp
++  @brief   A collection of helper functions
++  @author  Dan Čermák (D4N)
++           <a href="mailto:dan.cermak@cgc-instruments.com";>dan.cermak@cgc-instruments.com</a>
++  @date    25-May-18, D4N: created
++ */
++#ifndef HELPER_FUNCTIONS_HPP
++#define HELPER_FUNCTIONS_HPP
++
++#include <string>
++
++/*!
++  @brief Convert a (potentially not null terminated) array into a
++  std::string.
++
++  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);
++
++#endif  // HELPER_FUNCTIONS_HPP
+--- exiv2-stretch.git.orig/src/Makefile
++++ exiv2-stretch.git/src/Makefile
+@@ -120,7 +120,8 @@
+ 	 value.cpp             \
+ 	 version.cpp           \
+ 	 xmp.cpp               \
+-	 xmpsidecar.cpp
++	 xmpsidecar.cpp        \
++	 helper_functions.cpp
+ ifdef ENABLE_VIDEO
+ CCSRC += asfvideo.cpp          \
+ 	 matroskavideo.cpp     \
diff -Nru exiv2-0.25/debian/patches/series exiv2-0.25/debian/patches/series
--- exiv2-0.25/debian/patches/series	2018-06-27 08:09:36.000000000 -0400
+++ exiv2-0.25/debian/patches/series	2018-10-20 22:43:10.000000000 -0400
@@ -10,3 +10,5 @@
 CVE-2018-12265_prereq.patch
 CVE-2018-12265.patch
 CVE-2018-12264.patch
+CVE-2018-16336_prereq.patch
+CVE-2018-16336.patch

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 10.5

Hi,

Each of these bugs relates to an update that was included in today's
stable point release.

Regards,

Adam

--- End Message ---

Reply to: