Hola Maximiliano,

I forked your Salsa project but I had difficulty figuring out the proper
starting point for a branch.  It looks like master contains work for
both unstable and experimental in it.  I did use a Git repository to do
my work, but I began with importing exiv2_0.25-3.1.dsc.

That said, I have exported the indivdual commits as patches and attached
them to this mail.  You can use 'git apply' on them and it should just
work, except maybe for the placement of the changelog entry.

I did want to add two additional notes for your information:

1. My changes do not address CVE-2018-11037 (the only remaining open CVE
against the exiv2 package in Debian), since upstream has not yet fixed
it.  The issue in GitHub indicates it will be fixed in 0.27.

2. I had to make some adjustments to the error handling from the newer
upstream commits, as they have ported the "enforce" mechanism (similar
to assert) from D and it seemed to large a change to bring in for a
security update.  I requested a review of my patch from upstream in
GitHub (https://github.com/Exiv2/exiv2/issues/302) but have not yet
received a reply.  After submitting that request for review I did
patches for the remaining CVEs and encountered enough other erorr
handling code that I am comfortable with my approach, so I don't think
it that important that upstream has not yet replied.

I will leave it up to you integrate my patches, make the upload to
unstable, and coordinate the remaining transitions and advisory with the
security team.  You are welcome to use the DLA text I attached to the
first mail, or to write your own more detailed advisory as you prefer.

Regards,

-Roberto

On Thu, Jun 28, 2018 at 10:22:02AM +0200, Maximiliano Curia wrote:
> ¡Hola Roberto!
> 
> El 2018-06-28 a las 01:05 -0400, Roberto C. Sánchez escribió:
> > Hello all,
> 
> > I wanted to let you know that I have prepared updates of the exiv2
> > packages for jessie (LTS) and wheezy (ELTS).  The patches that I
> > prepared applied cleanly to the exiv2 package in stretch.
> 
> > The stretch packages that I built are here:
> 
> > https://people.debian.org/~roberto/
> 
> > I have also attached the DLA text I have published for the jessie
> > update.  It can serve as the basis of the DSA for stretch, if needed.
> 
> > If you prefer that I go ahead with uploading the packages that I have
> > prepared, please let me know.
> 
> Nice job, thanks for taking care of exiv2.
> 
> I would prefer if we have these changes applied in unstable first, if that's
> ok with you (which is the same as the stretch version so only the version
> needs to be changed for that).
> 
> About the changes, if you used a git repository to work on these changes it
> would be better to simply merge the individual commits instead of a
> monolithic change from the debdiff. So, if possible, could you send us a
> merge request from salsa, or a link to a public git with these changes?
> 
> If you prefer, go ahead and upload the modified package to unstable, we can
> deal with merging the changes afterwards.
> 
> Happy hacking,
> -- 
> "Don't let what you cannot do interfere with what you can do."
> -- Wooden's Rule
> Saludos /\/\ /\ >< `/



-- 
Roberto C. Sánchez
>From cbee4c7bbddf0b39d3abaf7e9d11743615c6f32f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= <[email protected]>
Date: Wed, 27 Jun 2018 08:14:54 -0400
Subject: [PATCH] * Non-maintainer upload by the Security Team. *
 CVE-2018-10958: denial of service through memory exhaustion and   application
 crash by a crafted PNG image. * CVE-2018-10999: a heap-based buffer over-read
 via a crafted PNG image.

---
 debian/changelog                                 |  9 ++++
 debian/patches/CVE-2018-10958_10999_1_of_2.patch | 52 +++++++++++++++++++++
 debian/patches/CVE-2018-10958_10999_2_of_2.patch | 59 ++++++++++++++++++++++++
 debian/patches/series                            |  2 +
 4 files changed, 122 insertions(+)
 create mode 100644 debian/patches/CVE-2018-10958_10999_1_of_2.patch
 create mode 100644 debian/patches/CVE-2018-10958_10999_2_of_2.patch

diff --git a/debian/changelog b/debian/changelog
index 0d5421cc..7d147205 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+exiv2 (0.25-3.1+deb9u1) stretch-security; urgency=high
+
+  * Non-maintainer upload by the Security Team.
+  * CVE-2018-10958: denial of service through memory exhaustion and
+    application crash by a crafted PNG image.
+  * CVE-2018-10999: a heap-based buffer over-read via a crafted PNG image.
+
+ -- Roberto C. Sanchez <[email protected]>  Wed, 27 Jun 2018 08:09:36 -0400
+
 exiv2 (0.25-3.1) unstable; urgency=medium
 
   * Non-maintainer upload.
diff --git a/debian/patches/CVE-2018-10958_10999_1_of_2.patch b/debian/patches/CVE-2018-10958_10999_1_of_2.patch
new file mode 100644
index 00000000..75f2ff20
--- /dev/null
+++ b/debian/patches/CVE-2018-10958_10999_1_of_2.patch
@@ -0,0 +1,52 @@
+From 2fb00c8a16ce93756cddd70536e361a49369ba88 Mon Sep 17 00:00:00 2001
+From: Luis Diaz Mas <[email protected]>
+Date: Sat, 19 May 2018 19:39:30 +0200
+Subject: [PATCH] Analyze minimum needed number of null separators in
+ PngChunk::parseTXTChunk
+
+This commit fixes the heap-buffer-overflow in PngChunk::parseTXTChunk.
+
+According to the specification:
+http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
+
+There must be 2 null separators when we start to analyze the language tag.
+
+(cherry picked from commit 2fb00c8a16ce93756cddd70536e361a49369ba88)
+[rcs: Backported to stretch]
+---
+ src/pngchunk.cpp                         | 5 +++++
+ tests/bugfixes/github/test_CVE_2018_10999.py | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+--- exiv2.git.orig/src/pngchunk.cpp
++++ exiv2.git/src/pngchunk.cpp
+@@ -49,6 +49,7 @@
+ #include <iostream>
+ #include <cassert>
+ #include <cstdio>
++#include <algorithm>
+ 
+ #include <zlib.h>     // To uncompress or compress text chunk
+ 
+@@ -157,6 +158,9 @@
+         }
+         else if(type == iTXt_Chunk)
+         {
++            const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_-1], '\0');
++            if (nullSeparators < 2) throw Error(58);
++
+             // Extract a deflate compressed or uncompressed UTF-8 text chunk
+ 
+             // we get the compression flag after the key
+--- exiv2.git.orig/src/error.cpp
++++ exiv2.git/src/error.cpp
+@@ -105,7 +105,8 @@
+         { 49, N_("TIFF directory %1 has too many entries") }, // %1=TIFF directory name
+         { 50, N_("Multiple TIFF array element tags %1 in one directory") }, // %1=tag number
+         { 51, N_("TIFF array element tag %1 has wrong type") }, // %1=tag number
+-        { 52, N_("%1 has invalid XMP value type `%2'") } // %1=key, %2=value type
++        { 52, N_("%1 has invalid XMP value type `%2'") }, // %1=key, %2=value type
++        { 58, N_("corrupted image metadata") }
+     };
+ 
+ }
diff --git a/debian/patches/CVE-2018-10958_10999_2_of_2.patch b/debian/patches/CVE-2018-10958_10999_2_of_2.patch
new file mode 100644
index 00000000..75a20270
--- /dev/null
+++ b/debian/patches/CVE-2018-10958_10999_2_of_2.patch
@@ -0,0 +1,59 @@
+From 3ad0050469e6ea63b4081f2a88c264ce8ab55c51 Mon Sep 17 00:00:00 2001
+From: Luis Diaz Mas <[email protected]>
+Date: Wed, 23 May 2018 10:34:20 +0200
+Subject: [PATCH] Check validity of compressionFlag & compressionMethod
+
+(cherry picked from commit 3ad0050469e6ea63b4081f2a88c264ce8ab55c51)
+[rcs: Backported to stretch]
+---
+ src/pngchunk.cpp | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- exiv2.git.orig/src/pngchunk.cpp
++++ exiv2.git/src/pngchunk.cpp
+@@ -159,14 +159,24 @@
+         else if(type == iTXt_Chunk)
+         {
+             const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_-1], '\0');
+-            if (nullSeparators < 2) throw Error(58);
++            if (nullSeparators < 2) throw Error(58, "iTXt chunk: not enough null separators");
+ 
+             // Extract a deflate compressed or uncompressed UTF-8 text chunk
+ 
+             // we get the compression flag after the key
+-            const byte* compressionFlag   = data.pData_ + keysize + 1;
++            const byte compressionFlag   = data.pData_[keysize + 1];
+             // we get the compression method after the compression flag
+-            const byte* compressionMethod = data.pData_ + keysize + 2;
++            const byte compressionMethod = data.pData_[keysize + 2];
++
++            if (compressionFlag != 0x00 && compressionFlag != 0x01)
++            {
++                    throw Error(58, "iTXt chunk: not valid value in compressionFlag");
++            }
++            if (compressionMethod != 0x00)
++            {
++                    throw Error(58, "iTXt chunk: not valid value in compressionMethod");
++            }
++
+             // 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());
+@@ -174,7 +184,7 @@
+             std::string translatedKeyText((const char*)(data.pData_ + keysize + 3 + languageTextSize +1));
+             unsigned int translatedKeyTextSize = static_cast<unsigned int>(translatedKeyText.size());
+ 
+-            if ( compressionFlag[0] == 0x00 )
++            if ( compressionFlag == 0x00 )
+             {
+                 // then it's an uncompressed iTXt chunk
+ #ifdef DEBUG
+@@ -188,7 +198,7 @@
+                 arr.alloc(textsize);
+                 arr = DataBuf(text, textsize);
+             }
+-            else if ( compressionFlag[0] == 0x01 && compressionMethod[0] == 0x00 )
++            else if ( compressionFlag == 0x01 && compressionMethod == 0x00 )
+             {
+                 // then it's a zlib compressed iTXt chunk
+ #ifdef DEBUG
diff --git a/debian/patches/series b/debian/patches/series
index b7f3a5c9..083f77bd 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,5 @@
 libtool_update.diff
 upstream-fix-casio-crash
 CVE-2017-9239.patch
+CVE-2018-10958_10999_1_of_2.patch
+CVE-2018-10958_10999_2_of_2.patch
-- 
2.11.0

>From 50a5bee33c1d65916186ac40187ef47f841e4484 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= <[email protected]>
Date: Wed, 27 Jun 2018 08:34:08 -0400
Subject: [PATCH] CVE-2018-10998: denial of service through memory exhaustion
 and application crash by a crafted image.

---
 debian/changelog                    |  2 +
 debian/patches/CVE-2018-10998.patch | 74 +++++++++++++++++++++++++++++++++++++
 debian/patches/series               |  1 +
 3 files changed, 77 insertions(+)
 create mode 100644 debian/patches/CVE-2018-10998.patch

diff --git a/debian/changelog b/debian/changelog
index 7d147205..318fcaa5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,8 @@ exiv2 (0.25-3.1+deb9u1) stretch-security; urgency=high
   * CVE-2018-10958: denial of service through memory exhaustion and
     application crash by a crafted PNG image.
   * CVE-2018-10999: a heap-based buffer over-read via a crafted PNG image.
+  * CVE-2018-10998: denial of service through memory exhaustion and
+    application crash by a crafted image.
 
  -- Roberto C. Sanchez <[email protected]>  Wed, 27 Jun 2018 08:09:36 -0400
 
diff --git a/debian/patches/CVE-2018-10998.patch b/debian/patches/CVE-2018-10998.patch
new file mode 100644
index 00000000..37dbb821
--- /dev/null
+++ b/debian/patches/CVE-2018-10998.patch
@@ -0,0 +1,74 @@
+From f4e8ed2fd48d012467b99552f0d6378302a23c75 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <[email protected]>
+Date: Mon, 11 Jun 2018 16:25:23 +0200
+Subject: [PATCH] Catch all exceptions not caught in exiv2 cli-tool
+
+It effectively looks the same as before, only now we don't call abort() but
+instead clean up everything gracefully.
+
+(cherry picked from commit f4e8ed2fd48d012467b99552f0d6378302a23c75)
+[rcs: Backported to stretch]
+---
+ src/exiv2.cpp | 48 +++++++++++++++++++++++++++---------------------
+ 1 file changed, 27 insertions(+), 21 deletions(-)
+
+--- exiv2-stretch.git.orig/src/exiv2.cpp
++++ exiv2-stretch.git/src/exiv2.cpp
+@@ -151,30 +151,36 @@
+         return 0;
+     }
+ 
+-    // Create the required action class
+-    Action::TaskFactory& taskFactory = Action::TaskFactory::instance();
+-    Action::Task::AutoPtr task
+-        = taskFactory.create(Action::TaskType(params.action_));
+-    assert(task.get());
+-
+-    // Process all files
+     int rc = 0;
+-    int n = 1;
+-    int s = static_cast<int>(params.files_.size());
+-    int w = s > 9 ? s > 99 ? 3 : 2 : 1;
+-    for (Params::Files::const_iterator i = params.files_.begin();
+-         i != params.files_.end(); ++i) {
+-        if (params.verbose_) {
+-            std::cout << _("File") << " " << std::setw(w) << std::right << n++ << "/" << s << ": "
+-                      << *i << std::endl;
++
++    try {
++        // Create the required action class
++        Action::TaskFactory& taskFactory = Action::TaskFactory::instance();
++        Action::Task::AutoPtr task = taskFactory.create(Action::TaskType(params.action_));
++        assert(task.get());
++
++        // Process all files
++        int n = 1;
++        int s = static_cast<int>(params.files_.size());
++        int w = s > 9 ? s > 99 ? 3 : 2 : 1;
++        for (Params::Files::const_iterator i = params.files_.begin(); i != params.files_.end(); ++i) {
++            if (params.verbose_) {
++                std::cout << _("File") << " " << std::setw(w) << std::right << n++ << "/" << s << ": " << *i
++                          << std::endl;
++            }
++            int ret = task->run(*i);
++            if (rc == 0)
++                rc = ret;
+         }
+-        int ret = task->run(*i);
+-        if (rc == 0) rc = ret;
+-    }
+ 
+-    taskFactory.cleanup();
+-    params.cleanup();
+-    Exiv2::XmpParser::terminate();
++        taskFactory.cleanup();
++        params.cleanup();
++        Exiv2::XmpParser::terminate();
++
++    } catch (const std::exception& exc) {
++        std::cerr << "Uncaught exception: " << exc.what() << std::endl;
++        rc = 1;
++    }
+ 
+     // Return a positive one byte code for better consistency across platforms
+     return static_cast<unsigned int>(rc) % 256;
diff --git a/debian/patches/series b/debian/patches/series
index 083f77bd..82a3f6d6 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,4 @@ upstream-fix-casio-crash
 CVE-2017-9239.patch
 CVE-2018-10958_10999_1_of_2.patch
 CVE-2018-10958_10999_2_of_2.patch
+CVE-2018-10998.patch
-- 
2.11.0

>From 77c901e91415aca19aae38482df09ad07297f53d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= <[email protected]>
Date: Wed, 27 Jun 2018 23:08:23 -0400
Subject: [PATCH] CVE-2018-11531: a heap-based buffer overflow and application
 crash by a crafted image.

---
 debian/changelog                           |  2 ++
 debian/patches/CVE-2018-11531_1_of_3.patch | 22 ++++++++++++++++++++++
 debian/patches/CVE-2018-11531_2_of_3.patch | 30 ++++++++++++++++++++++++++++++
 debian/patches/CVE-2018-11531_3_of_3.patch | 22 ++++++++++++++++++++++
 debian/patches/series                      |  3 +++
 5 files changed, 79 insertions(+)
 create mode 100644 debian/patches/CVE-2018-11531_1_of_3.patch
 create mode 100644 debian/patches/CVE-2018-11531_2_of_3.patch
 create mode 100644 debian/patches/CVE-2018-11531_3_of_3.patch

diff --git a/debian/changelog b/debian/changelog
index 318fcaa5..ebbf7c33 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,8 @@ exiv2 (0.25-3.1+deb9u1) stretch-security; urgency=high
   * CVE-2018-10999: a heap-based buffer over-read via a crafted PNG image.
   * CVE-2018-10998: denial of service through memory exhaustion and
     application crash by a crafted image.
+  * CVE-2018-11531: a heap-based buffer overflow and application crash by a
+    crafted image.
 
  -- Roberto C. Sanchez <[email protected]>  Wed, 27 Jun 2018 08:09:36 -0400
 
diff --git a/debian/patches/CVE-2018-11531_1_of_3.patch b/debian/patches/CVE-2018-11531_1_of_3.patch
new file mode 100644
index 00000000..09f4b52e
--- /dev/null
+++ b/debian/patches/CVE-2018-11531_1_of_3.patch
@@ -0,0 +1,22 @@
+From ed874703ad553338f973d537b8159d0eb4375cc4 Mon Sep 17 00:00:00 2001
+From: Luis Diaz Mas <[email protected]>
+Date: Fri, 25 May 2018 22:03:26 +0200
+Subject: [PATCH] Prevent call to memcpy with size==0
+
+(cherry picked from commit ed874703ad553338f973d537b8159d0eb4375cc4)
+[rcs: Backported to stretch]
+---
+ src/preview.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- exiv2-stretch.git.orig/src/preview.cpp
++++ exiv2-stretch.git/src/preview.cpp
+@@ -810,7 +810,7 @@
+                     for (int i = 0; i < sizes.count(); i++) {
+                         uint32_t offset = dataValue.toLong(i);
+                         uint32_t size = sizes.toLong(i);
+-                        if (offset + size <= static_cast<uint32_t>(io.size()))
++                        if (size!=0 && offset + size <= static_cast<uint32_t>(io.size()))
+                             memcpy(pos, base + offset, size);
+                         pos += size;
+                     }
diff --git a/debian/patches/CVE-2018-11531_2_of_3.patch b/debian/patches/CVE-2018-11531_2_of_3.patch
new file mode 100644
index 00000000..638c8a2c
--- /dev/null
+++ b/debian/patches/CVE-2018-11531_2_of_3.patch
@@ -0,0 +1,30 @@
+From 863aaebc92ff0b0ee3d302b7b5291002c043bc7b Mon Sep 17 00:00:00 2001
+From: Luis Diaz Mas <[email protected]>
+Date: Fri, 25 May 2018 22:16:25 +0200
+Subject: [PATCH] Use index to access buf.pData_
+
+(cherry picked from commit 863aaebc92ff0b0ee3d302b7b5291002c043bc7b)
+[rcs: Backported to stretch]
+---
+ src/preview.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- exiv2-stretch.git.orig/src/preview.cpp
++++ exiv2-stretch.git/src/preview.cpp
+@@ -806,13 +806,13 @@
+                 else {
+                     // FIXME: the buffer is probably copied twice, it should be optimized
+                     DataBuf buf(size_);
+-                    Exiv2::byte* pos = buf.pData_;
++                    uint32_t idxBuf = 0;
+                     for (int i = 0; i < sizes.count(); i++) {
+                         uint32_t offset = dataValue.toLong(i);
+                         uint32_t size = sizes.toLong(i);
+                         if (size!=0 && offset + size <= static_cast<uint32_t>(io.size()))
+-                            memcpy(pos, base + offset, size);
+-                        pos += size;
++                            memcpy(&buf.pData_[idxBuf], base + offset, size);
++                        idxBuf += size;
+                     }
+                     dataValue.setDataArea(buf.pData_, buf.size_);
+                 }
diff --git a/debian/patches/CVE-2018-11531_3_of_3.patch b/debian/patches/CVE-2018-11531_3_of_3.patch
new file mode 100644
index 00000000..3bedea47
--- /dev/null
+++ b/debian/patches/CVE-2018-11531_3_of_3.patch
@@ -0,0 +1,22 @@
+From 67a5a741153c876a6f1c189abb874721d1725c48 Mon Sep 17 00:00:00 2001
+From: Luis Diaz Mas <[email protected]>
+Date: Fri, 25 May 2018 22:20:03 +0200
+Subject: [PATCH] Throw when trying to write out of the buffer
+
+(cherry picked from commit 67a5a741153c876a6f1c189abb874721d1725c48)
+[rcs: Backported to stretch]
+---
+ src/preview.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- exiv2-stretch.git.orig/src/preview.cpp
++++ exiv2-stretch.git/src/preview.cpp
+@@ -810,6 +810,8 @@
+                     for (int i = 0; i < sizes.count(); i++) {
+                         uint32_t offset = dataValue.toLong(i);
+                         uint32_t size = sizes.toLong(i);
++                        if (idxBuf + size >= size_)
++                            throw Error(58);
+                         if (size!=0 && offset + size <= static_cast<uint32_t>(io.size()))
+                             memcpy(&buf.pData_[idxBuf], base + offset, size);
+                         idxBuf += size;
diff --git a/debian/patches/series b/debian/patches/series
index 82a3f6d6..2e905b11 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,6 @@ CVE-2017-9239.patch
 CVE-2018-10958_10999_1_of_2.patch
 CVE-2018-10958_10999_2_of_2.patch
 CVE-2018-10998.patch
+CVE-2018-11531_1_of_3.patch
+CVE-2018-11531_2_of_3.patch
+CVE-2018-11531_3_of_3.patch
-- 
2.11.0

>From 59304d21239418177812906c3a8afdcf258946b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= <[email protected]>
Date: Thu, 28 Jun 2018 00:05:04 -0400
Subject: [PATCH] * CVE-2018-12264: integer overflow leading to out of bounds
 read by a crafted image. (Closes: #901707) * CVE-2018-12265: integer overflow
 leading to out of bounds read by a crafted image. (Closes: #901706)

---
 debian/changelog                           |   4 +
 debian/patches/CVE-2018-12264.patch        |  40 ++++
 debian/patches/CVE-2018-12265.patch        |  38 ++++
 debian/patches/CVE-2018-12265_prereq.patch | 310 +++++++++++++++++++++++++++++
 debian/patches/series                      |   3 +
 5 files changed, 395 insertions(+)
 create mode 100644 debian/patches/CVE-2018-12264.patch
 create mode 100644 debian/patches/CVE-2018-12265.patch
 create mode 100644 debian/patches/CVE-2018-12265_prereq.patch

diff --git a/debian/changelog b/debian/changelog
index ebbf7c33..0414fd31 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -8,6 +8,10 @@ exiv2 (0.25-3.1+deb9u1) stretch-security; urgency=high
     application crash by a crafted image.
   * CVE-2018-11531: a heap-based buffer overflow and application crash by a
     crafted image.
+  * CVE-2018-12264: integer overflow leading to out of bounds read by a
+    crafted image. (Closes: #901707)
+  * CVE-2018-12265: integer overflow leading to out of bounds read by a
+    crafted image. (Closes: #901706)
 
  -- Roberto C. Sanchez <[email protected]>  Wed, 27 Jun 2018 08:09:36 -0400
 
diff --git a/debian/patches/CVE-2018-12264.patch b/debian/patches/CVE-2018-12264.patch
new file mode 100644
index 00000000..5866ed36
--- /dev/null
+++ b/debian/patches/CVE-2018-12264.patch
@@ -0,0 +1,40 @@
+From fe70939f54476e99046245ca69ff27012401f759 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <[email protected]>
+Date: Mon, 11 Jun 2018 18:37:36 +0200
+Subject: [PATCH] Fix addition overflows in range checks in LoaderTiff::getData
+
+Several checks for extracted values performed no overflow checks on the
+addition. They can be tricked into passing, albeit the individual summands are
+too large.
+=> use Safe::add() which now aborts when an overflow occurs
+This fixes #366
+
+(cherry picked from commit fe70939f54476e99046245ca69ff27012401f759)
+[rcs: Backported to stretch]
+---
+ src/preview.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- exiv2-stretch.git.orig/src/preview.cpp
++++ exiv2-stretch.git/src/preview.cpp
+@@ -802,7 +802,7 @@
+                     // this saves one copying of the buffer
+                     uint32_t offset = dataValue.toLong(0);
+                     uint32_t size = sizes.toLong(0);
+-                    if (offset + size <= static_cast<uint32_t>(io.size()))
++                    if (Safe::add(offset, size) <= static_cast<uint32_t>(io.size()))
+                         dataValue.setDataArea(base + offset, size);
+                 }
+                 else {
+@@ -812,9 +812,9 @@
+                     for (int i = 0; i < sizes.count(); i++) {
+                         uint32_t offset = dataValue.toLong(i);
+                         uint32_t size = sizes.toLong(i);
+-                        if (idxBuf + size >= size_)
++                        if (Safe::add(idxBuf, size) >= size_)
+                             throw Error(58);
+-                        if (size!=0 && offset + size <= static_cast<uint32_t>(io.size()))
++                        if (size!=0 && Safe::add(offset, size) <= static_cast<uint32_t>(io.size()))
+                             memcpy(&buf.pData_[idxBuf], base + offset, size);
+                         idxBuf += size;
+                     }
diff --git a/debian/patches/CVE-2018-12265.patch b/debian/patches/CVE-2018-12265.patch
new file mode 100644
index 00000000..1524bbd4
--- /dev/null
+++ b/debian/patches/CVE-2018-12265.patch
@@ -0,0 +1,38 @@
+From 937a1a2bd067b8b3b787f3757089d972f3a39853 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <[email protected]>
+Date: Mon, 11 Jun 2018 16:04:28 +0200
+Subject: [PATCH] Add offset_ and size_ safely in
+ LoaderExifJpeg::LoaderExifJpeg
+
+offset_ can become arbitrarily large and overflows once its added to size_,
+this causes all kinds of problems further in the code when offset_ is used
+again.
+=> Use Safe::add() to catch potential overflows
+This fixes #365.
+
+(cherry picked from commit 937a1a2bd067b8b3b787f3757089d972f3a39853)
+[rcs: Backported to stretch]
+---
+ src/preview.cpp | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- exiv2-stretch.git.orig/src/preview.cpp
++++ exiv2-stretch.git/src/preview.cpp
+@@ -36,6 +36,7 @@
+ 
+ #include "preview.hpp"
+ #include "futils.hpp"
++#include "safe_op.hpp"
+ 
+ #include "image.hpp"
+ #include "cr2image.hpp"
+@@ -546,7 +547,8 @@
+             }
+         }
+ 
+-        if (offset_ + size_ > static_cast<uint32_t>(image_.io().size())) return;
++        if (Safe::add(offset_, size_) > static_cast<uint32_t>(image_.io().size()))
++            return;
+ 
+         valid_ = true;
+     }
diff --git a/debian/patches/CVE-2018-12265_prereq.patch b/debian/patches/CVE-2018-12265_prereq.patch
new file mode 100644
index 00000000..f5812931
--- /dev/null
+++ b/debian/patches/CVE-2018-12265_prereq.patch
@@ -0,0 +1,310 @@
+--- /dev/null
++++ exiv2-jessie.git/src/safe_op.hpp
+@@ -0,0 +1,307 @@
++// ********************************************************* -*- C++ -*-
++/*
++ * Copyright (C) 2004-2018 Exiv2 maintainers
++ *
++ * 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    safe_op.hpp
++  @brief   Overflow checks for integers
++  @author  Dan Čermák (D4N)
++           <a href="mailto:[email protected]">[email protected]</a>
++  @date    14-Dec-17, D4N: created
++ */
++
++#ifndef SAFE_OP_HPP_
++#define SAFE_OP_HPP_
++
++#include <limits>
++#include <stdexcept>
++
++#ifdef _MSC_VER
++#include <Intsafe.h>
++#endif
++
++/*!
++ * @brief Arithmetic operations with overflow checks
++ */
++namespace Safe
++{
++    /*!
++     * @brief Helper functions for providing integer overflow checks.
++     *
++     * This namespace contains internal helper functions fallback_$op_overflow
++     * and builtin_$op_overflow (where $op is an arithmetic operation like add,
++     * subtract, etc.). Both provide the following interface:
++     *
++     * bool fallback/builtin_$op_overflow(T first, T second, T& result);
++     *
++     * where T is an integer type.
++     *
++     * Each function performs checks whether first $op second can be safely
++     * performed without overflows. If yes, the result is saved in result and
++     * false is returned. Otherwise true is returned and the contents of result
++     * are unspecified.
++     *
++     * fallback_$op_overflow implements a portable but slower overflow check.
++     * builtin_$op_overflow uses compiler builtins (when available) and should
++     * be faster. As builtins are not available for all types,
++     * builtin_$op_overflow falls back to fallback_$op_overflow when no builtin
++     * is available.
++     */
++    namespace Internal
++    {
++        /*!
++         * @brief Helper struct to determine whether a type is signed or unsigned
++         *
++         * This struct is a backport of std::is_signed from C++11. It has a public
++         * enum with the property VALUE which is true when the type is signed or
++         * false if it is unsigned.
++         */
++        template <typename T>
++        struct is_signed
++        {
++            enum
++            {
++                VALUE = T(-1) < T(0)
++            };
++        };
++
++        /*!
++         * @brief Helper struct for SFINAE, from C++11
++
++         * This struct has a public typedef called type typedef'd to T if B is
++         * true. Otherwise there is no typedef.
++         */
++        template <bool B, class T = void>
++        struct enable_if
++        {
++        };
++
++        /*!
++         * @brief Specialization of enable_if for the case B == true
++         */
++        template <class T>
++        struct enable_if<true, T>
++        {
++            typedef T type;
++        };
++
++        /*!
++         * @brief Check the addition of two numbers for overflows for signed
++         * integer types larger than int or with the same size as int.
++         *
++         * This function performs a check if summand_1 + summand_2 would
++         * overflow and returns true in that case. If no overflow occurs,
++         * the sum is saved in result and false is returned.
++         *
++         * @return true on overflow, false on no overflow
++         *
++         * @param[in] summand_1, summand_2 The summands with are added
++         * @param[out] result Result of the addition, only populated when no
++         * overflow occurs.
++         *
++         * Further information:
++         * https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
++         */
++        template <typename T>
++        typename enable_if<is_signed<T>::VALUE && sizeof(T) >= sizeof(int), bool>::type fallback_add_overflow(
++            T summand_1, T summand_2, T& result)
++        {
++            if (((summand_2 >= 0) && (summand_1 > std::numeric_limits<T>::max() - summand_2)) ||
++                ((summand_2 < 0) && (summand_1 < std::numeric_limits<T>::min() - summand_2))) {
++                return true;
++            } else {
++                result = summand_1 + summand_2;
++                return false;
++            }
++        }
++
++        /*!
++         * @brief Check the addition of two numbers for overflows for signed
++         * integer types smaller than int.
++         *
++         * This function adds summand_1 and summand_2 exploiting integer
++         * promotion rules, thereby not causing undefined behavior. The
++         * result is checked against the limits of T and true is returned if
++         * they are exceeded. Otherwise the sum is saved in result and false
++         * is returned.
++         *
++         * @return true on overflow, false on no overflow
++         *
++         * @param[in] summand_1, summand_2 The summands with are added
++         * @param[out] result Result of the addition, only populated when no
++         * overflow occurs.
++         *
++         * Further information:
++         * https://wiki.sei.cmu.edu/confluence/display/c/INT02-C.+Understand+integer+conversion+rules
++         */
++        template <typename T>
++        typename enable_if<is_signed<T>::VALUE && sizeof(T) < sizeof(int), bool>::type fallback_add_overflow(
++            T summand_1, T summand_2, T& result)
++        {
++            const int res = summand_1 + summand_2;
++            if ((res > std::numeric_limits<T>::max()) || (res < std::numeric_limits<T>::min())) {
++                return true;
++            } else {
++                result = static_cast<T>(res);
++                return false;
++            }
++        }
++
++        /*!
++         * @brief Check the addition of two numbers for overflows for unsigned
++         * integer types.
++         *
++         * This function adds summand_1 and summand_2 and checks after that if
++         * the operation overflowed. Since these are unsigned integers, no
++         * undefined behavior is invoked.
++         *
++         * @return true on overflow, false on no overflow
++         *
++         * @param[in] summand_1, summand_2 The summands with are added
++         * @param[out] result Result of the addition
++         *
++         * Further information:
++         * https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
++         */
++        template <typename T>
++        typename enable_if<!is_signed<T>::VALUE, bool>::type fallback_add_overflow(T summand_1, T summand_2, T& result)
++        {
++            result = summand_1 + summand_2;
++            return result < summand_1;
++        }
++
++        /*!
++         * @brief Overflow addition check using compiler intrinsics.
++         *
++         * This function behaves exactly like fallback_add_overflow() but it
++         * relies on compiler intrinsics instead. This version should be faster
++         * than the fallback version as it can fully utilize available CPU
++         * instructions & the compiler's diagnostic.
++         *
++         * However, as some compilers don't provide intrinsics for certain
++         * types, the default implementation is the version from fallback.
++         *
++         * This function is fully specialized for each compiler.
++         */
++        template <typename T>
++        bool builtin_add_overflow(T summand_1, T summand_2, T& result)
++        {
++            return fallback_add_overflow(summand_1, summand_2, result);
++        }
++
++#if defined(__GNUC__) || defined(__clang__)
++#if __GNUC__ >= 5 || __clang_major__ >= 3
++
++/*!
++ * This macro pastes a specialization of builtin_add_overflow using gcc's &
++ * clang's __builtin_(s/u)add(l)(l)_overlow()
++ *
++ * The add function is implemented by forwarding the parameters to the intrinsic
++ * and returning its value.
++ *
++ * The intrinsics are documented here:
++ * https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html#Integer-Overflow-Builtins
++ */
++#define SPECIALIZE_builtin_add_overflow(type, builtin_name)                               \
++    /* Full specialization of builtin_add_overflow for type using the */                  \
++    /* builtin_name intrinsic */                                                          \
++    template <>                                                                           \
++    inline bool builtin_add_overflow<type>(type summand_1, type summand_2, type & result) \
++    {                                                                                     \
++        return builtin_name(summand_1, summand_2, &result);                               \
++    }
++
++        SPECIALIZE_builtin_add_overflow(int, __builtin_sadd_overflow);
++        SPECIALIZE_builtin_add_overflow(long, __builtin_saddl_overflow);
++        SPECIALIZE_builtin_add_overflow(long long, __builtin_saddll_overflow);
++
++        SPECIALIZE_builtin_add_overflow(unsigned int, __builtin_uadd_overflow);
++        SPECIALIZE_builtin_add_overflow(unsigned long, __builtin_uaddl_overflow);
++        SPECIALIZE_builtin_add_overflow(unsigned long long, __builtin_uaddll_overflow);
++
++#undef SPECIALIZE_builtin_add_overflow
++#endif  // __GNUC__ >= 5 || __clang_major >= 3
++
++#elif defined(_MSC_VER)
++// intrinsics are not in available in MSVC 2005 and earlier
++#if _MSC_VER >= 1400
++
++/*!
++ * This macro pastes a specialization of builtin_add_overflow using MSVC's
++ * U(Int/Long/LongLong)Add.
++ *
++ * The add function is implemented by forwarding the parameters to the
++ * intrinsic. As MSVC's intrinsics return S_OK on success, this specialization
++ * returns whether the intrinsics return value does not equal S_OK. This ensures
++ * a uniform interface of the add function (false is returned when no overflow
++ * occurs, true on overflow).
++ *
++ * The intrinsics are documented here:
++ * https://msdn.microsoft.com/en-us/library/windows/desktop/ff516460(v=vs.85).aspx
++ */
++#define SPECIALIZE_builtin_add_overflow_WIN(type, builtin_name)                    \
++    template <>                                                                    \
++    inline bool builtin_add_overflow(type summand_1, type summand_2, type& result) \
++    {                                                                              \
++        return builtin_name(summand_1, summand_2, &result) != S_OK;                \
++    }
++
++        SPECIALIZE_builtin_add_overflow_WIN(unsigned int, UIntAdd);
++        SPECIALIZE_builtin_add_overflow_WIN(unsigned long, ULongAdd);
++        SPECIALIZE_builtin_add_overflow_WIN(unsigned long long, ULongLongAdd);
++
++#undef SPECIALIZE_builtin_add_overflow_WIN
++
++#endif  // _MSC_VER >= 1400
++#endif  // defined(_MSC_VER)
++
++    }  // namespace Internal
++
++    /*!
++     * @brief Safe addition, throws an exception on overflow.
++     *
++     * This function returns the result of summand_1 and summand_2 only when the
++     * operation would not overflow, otherwise an exception of type
++     * std::overflow_error is thrown.
++     *
++     * @param[in] summand_1, summand_2  summands to be summed up
++     * @return  the sum of summand_1 and summand_2
++     * @throws  std::overflow_error if the addition would overflow
++     *
++     * This function utilizes compiler builtins when available and should have a
++     * very small performance hit then. When builtins are unavailable, a more
++     * extensive check is required.
++     *
++     * Builtins are available for the following configurations:
++     * - GCC/Clang for signed and unsigned int, long and long long (not char & short)
++     * - MSVC for unsigned int, long and long long
++     */
++    template <typename T>
++    T add(T summand_1, T summand_2)
++    {
++        T res = 0;
++        if (Internal::builtin_add_overflow(summand_1, summand_2, res)) {
++            throw std::overflow_error("Overflow in addition");
++        }
++        return res;
++    }
++
++}  // namespace Safe
++
++#endif  // SAFE_OP_HPP_
diff --git a/debian/patches/series b/debian/patches/series
index 2e905b11..613c9e62 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -7,3 +7,6 @@ CVE-2018-10998.patch
 CVE-2018-11531_1_of_3.patch
 CVE-2018-11531_2_of_3.patch
 CVE-2018-11531_3_of_3.patch
+CVE-2018-12265_prereq.patch
+CVE-2018-12265.patch
+CVE-2018-12264.patch
-- 
2.11.0

_______________________________________________
pkg-kde-extras mailing list
[email protected]
https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-kde-extras

Reply via email to