diff mbox

[1/1] gnu: libtiff: Fix some buffer overflows.

Message ID cf7e5e0ee1c2226da19b0236d50ebb4879fb2a3e.1479241675.git.leo@famulari.name
State New
Headers show

Commit Message

Leo Famulari Nov. 15, 2016, 8:28 p.m. UTC
* gnu/packages/patches/libtiff-uint32-overflow.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/image.scm (libtiff/fixed)[source]: Use it.
---
 gnu/local.mk                                       |   1 +
 gnu/packages/image.scm                             |   1 +
 gnu/packages/patches/libtiff-uint32-overflow.patch | 102 +++++++++++++++++++++
 3 files changed, 104 insertions(+)
 create mode 100644 gnu/packages/patches/libtiff-uint32-overflow.patch

Comments

Kei Yamashita Nov. 16, 2016, 6:10 p.m. UTC | #1
Leo Famulari <leo@famulari.name> writes:

> * gnu/packages/patches/libtiff-uint32-overflow.patch: New file.
> * gnu/local.mk (dist_patch_DATA): Add it.
> * gnu/packages/image.scm (libtiff/fixed)[source]: Use it.
> ---
>  gnu/local.mk                                       |   1 +
>  gnu/packages/image.scm                             |   1 +
>  gnu/packages/patches/libtiff-uint32-overflow.patch | 102 +++++++++++++++++++++
>  3 files changed, 104 insertions(+)
>  create mode 100644 gnu/packages/patches/libtiff-uint32-overflow.patch
>
> diff --git a/gnu/local.mk b/gnu/local.mk
> index 513bd34..1c27767 100644
> --- a/gnu/local.mk
> +++ b/gnu/local.mk
> @@ -670,6 +670,7 @@ dist_patch_DATA =						\
>    %D%/packages/patches/libtiff-CVE-2016-9297.patch		\
>    %D%/packages/patches/libtiff-oob-accesses-in-decode.patch	\
>    %D%/packages/patches/libtiff-oob-write-in-nextdecode.patch	\
> +  %D%/packages/patches/libtiff-uint32-overflow.patch		\
>    %D%/packages/patches/libtool-skip-tests2.patch		\
>    %D%/packages/patches/libunwind-CVE-2015-3239.patch		\
>    %D%/packages/patches/libupnp-CVE-2016-6255.patch		\
> diff --git a/gnu/packages/image.scm b/gnu/packages/image.scm
> index d38344a..7458f4e 100644
> --- a/gnu/packages/image.scm
> +++ b/gnu/packages/image.scm
> @@ -291,6 +291,7 @@ collection of tools for doing simple manipulations of TIFF images.")
>                (patches (search-patches
>                           "libtiff-oob-accesses-in-decode.patch"
>                           "libtiff-oob-write-in-nextdecode.patch"
> +                         "libtiff-uint32-overflow.patch"
>                           "libtiff-CVE-2015-8665+CVE-2015-8683.patch"
>                           "libtiff-CVE-2016-3623.patch"
>                           "libtiff-CVE-2016-3945.patch"
> diff --git a/gnu/packages/patches/libtiff-uint32-overflow.patch b/gnu/packages/patches/libtiff-uint32-overflow.patch
> new file mode 100644
> index 0000000..b9b1bc2
> --- /dev/null
> +++ b/gnu/packages/patches/libtiff-uint32-overflow.patch
> @@ -0,0 +1,102 @@
> +Fix some buffer overflows:
> +
> +http://seclists.org/oss-sec/2016/q4/
> +http://bugzilla.maptools.org/show_bug.cgi?id=2592
> +
> +2016-11-11 Even Rouault <even.rouault at spatialys.com>
> +
> +        * tools/tiffcrop.c: fix multiple uint32 overflows in
> +        writeBufferToSeparateStrips(), writeBufferToContigTiles() and
> +        writeBufferToSeparateTiles() that could cause heap buffer
> +overflows.
> +        Reported by Henri Salo from Nixu Corporation.
> +        Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2592
> +
> +
> +/cvs/maptools/cvsroot/libtiff/ChangeLog,v  <--  ChangeLog
> +new revision: 1.1152; previous revision: 1.1151
> +/cvs/maptools/cvsroot/libtiff/tools/tiffcrop.c,v  <--  tools/tiffcrop.c
> +new revision: 1.43; previous revision: 1.42
> +
> +===================================================================
> +RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiffcrop.c,v
> +retrieving revision 1.42
> +retrieving revision 1.43
> +diff -u -r1.42 -r1.43
> +--- libtiff/tools/tiffcrop.c	14 Oct 2016 19:13:20 -0000	1.42
> ++++ libtiff/tools/tiffcrop.c	11 Nov 2016 19:33:06 -0000	1.43
> +@@ -148,6 +148,8 @@
> + #define PATH_MAX 1024
> + #endif
> + 
> ++#define TIFF_UINT32_MAX     0xFFFFFFFFU
> ++
> + #ifndef streq
> + #define	streq(a,b)	(strcmp((a),(b)) == 0)
> + #endif
> +@@ -1164,7 +1166,24 @@
> +   (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
> +   (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
> +   bytes_per_sample = (bps + 7) / 8;
> +-  rowsize = ((bps * spp * width) + 7) / 8; /* source has interleaved samples */
> ++  if( width == 0 ||
> ++      (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / width ||
> ++      bps * spp * width > TIFF_UINT32_MAX - 7U )
> ++  {
> ++      TIFFError(TIFFFileName(out),
> ++            "Error, uint32 overflow when computing (bps * spp * width) + 7");
> ++      return 1;
> ++  }
> ++  rowsize = ((bps * spp * width) + 7U) / 8; /* source has interleaved samples */
> ++  if( bytes_per_sample == 0 ||
> ++      rowsperstrip > TIFF_UINT32_MAX / bytes_per_sample ||
> ++      rowsperstrip * bytes_per_sample > TIFF_UINT32_MAX / (width + 1) )
> ++  {
> ++      TIFFError(TIFFFileName(out),
> ++                "Error, uint32 overflow when computing rowsperstrip * "
> ++                "bytes_per_sample * (width + 1)");
> ++      return 1;
> ++  }
> +   rowstripsize = rowsperstrip * bytes_per_sample * (width + 1); 
> + 
> +   obuf = _TIFFmalloc (rowstripsize);
> +@@ -1251,11 +1270,19 @@
> +     }
> +     }
> + 
> ++  if( imagewidth == 0 ||
> ++      (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / imagewidth ||
> ++      bps * spp * imagewidth > TIFF_UINT32_MAX - 7U )
> ++  {
> ++      TIFFError(TIFFFileName(out),
> ++            "Error, uint32 overflow when computing (imagewidth * bps * spp) + 7");
> ++      return 1;
> ++  }
> ++  src_rowsize = ((imagewidth * spp * bps) + 7U) / 8;
> ++
> +   tilebuf = _TIFFmalloc(tile_buffsize);
> +   if (tilebuf == 0)
> +     return 1;
> +-
> +-  src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
> +   for (row = 0; row < imagelength; row += tl)
> +     {
> +     nrow = (row + tl > imagelength) ? imagelength - row : tl;
> +@@ -1315,7 +1342,16 @@
> +   TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
> +   TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
> +   TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
> +-  src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
> ++
> ++  if( imagewidth == 0 ||
> ++      (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / imagewidth ||
> ++      bps * spp * imagewidth > TIFF_UINT32_MAX - 7 )
> ++  {
> ++      TIFFError(TIFFFileName(out),
> ++            "Error, uint32 overflow when computing (imagewidth * bps * spp) + 7");
> ++      return 1;
> ++  }
> ++  src_rowsize = ((imagewidth * spp * bps) + 7U) / 8;
> +          
> +   for (row = 0; row < imagelength; row += tl)
> +     {

The Guix linter tells me that ftp.remotesensing.org is not reachable. Is
it reachable for you? My connection could just be bad, or the server
temporarily down.

Otherwise, LGTM.
Leo Famulari Nov. 16, 2016, 7:13 p.m. UTC | #2
On Wed, Nov 16, 2016 at 01:10:56PM -0500, Kei Kebreau wrote:
> Leo Famulari <leo@famulari.name> writes:
> 
> > * gnu/packages/patches/libtiff-uint32-overflow.patch: New file.
> > * gnu/local.mk (dist_patch_DATA): Add it.
> > * gnu/packages/image.scm (libtiff/fixed)[source]: Use it.

> The Guix linter tells me that ftp.remotesensing.org is not reachable. Is
> it reachable for you? My connection could just be bad, or the server
> temporarily down.

The story of libtiff's domains is long and sordid. Here is the most
recent chapter:

http://www.asmail.be/msg0054885794.html

We should update our packaging to address this.

> Otherwise, LGTM.

Thanks for the review!
diff mbox

Patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 513bd34..1c27767 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -670,6 +670,7 @@  dist_patch_DATA =						\
   %D%/packages/patches/libtiff-CVE-2016-9297.patch		\
   %D%/packages/patches/libtiff-oob-accesses-in-decode.patch	\
   %D%/packages/patches/libtiff-oob-write-in-nextdecode.patch	\
+  %D%/packages/patches/libtiff-uint32-overflow.patch		\
   %D%/packages/patches/libtool-skip-tests2.patch		\
   %D%/packages/patches/libunwind-CVE-2015-3239.patch		\
   %D%/packages/patches/libupnp-CVE-2016-6255.patch		\
diff --git a/gnu/packages/image.scm b/gnu/packages/image.scm
index d38344a..7458f4e 100644
--- a/gnu/packages/image.scm
+++ b/gnu/packages/image.scm
@@ -291,6 +291,7 @@  collection of tools for doing simple manipulations of TIFF images.")
               (patches (search-patches
                          "libtiff-oob-accesses-in-decode.patch"
                          "libtiff-oob-write-in-nextdecode.patch"
+                         "libtiff-uint32-overflow.patch"
                          "libtiff-CVE-2015-8665+CVE-2015-8683.patch"
                          "libtiff-CVE-2016-3623.patch"
                          "libtiff-CVE-2016-3945.patch"
diff --git a/gnu/packages/patches/libtiff-uint32-overflow.patch b/gnu/packages/patches/libtiff-uint32-overflow.patch
new file mode 100644
index 0000000..b9b1bc2
--- /dev/null
+++ b/gnu/packages/patches/libtiff-uint32-overflow.patch
@@ -0,0 +1,102 @@ 
+Fix some buffer overflows:
+
+http://seclists.org/oss-sec/2016/q4/
+http://bugzilla.maptools.org/show_bug.cgi?id=2592
+
+2016-11-11 Even Rouault <even.rouault at spatialys.com>
+
+        * tools/tiffcrop.c: fix multiple uint32 overflows in
+        writeBufferToSeparateStrips(), writeBufferToContigTiles() and
+        writeBufferToSeparateTiles() that could cause heap buffer
+overflows.
+        Reported by Henri Salo from Nixu Corporation.
+        Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2592
+
+
+/cvs/maptools/cvsroot/libtiff/ChangeLog,v  <--  ChangeLog
+new revision: 1.1152; previous revision: 1.1151
+/cvs/maptools/cvsroot/libtiff/tools/tiffcrop.c,v  <--  tools/tiffcrop.c
+new revision: 1.43; previous revision: 1.42
+
+===================================================================
+RCS file: /cvs/maptools/cvsroot/libtiff/tools/tiffcrop.c,v
+retrieving revision 1.42
+retrieving revision 1.43
+diff -u -r1.42 -r1.43
+--- libtiff/tools/tiffcrop.c	14 Oct 2016 19:13:20 -0000	1.42
++++ libtiff/tools/tiffcrop.c	11 Nov 2016 19:33:06 -0000	1.43
+@@ -148,6 +148,8 @@
+ #define PATH_MAX 1024
+ #endif
+ 
++#define TIFF_UINT32_MAX     0xFFFFFFFFU
++
+ #ifndef streq
+ #define	streq(a,b)	(strcmp((a),(b)) == 0)
+ #endif
+@@ -1164,7 +1166,24 @@
+   (void) TIFFGetFieldDefaulted(out, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+   (void) TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
+   bytes_per_sample = (bps + 7) / 8;
+-  rowsize = ((bps * spp * width) + 7) / 8; /* source has interleaved samples */
++  if( width == 0 ||
++      (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / width ||
++      bps * spp * width > TIFF_UINT32_MAX - 7U )
++  {
++      TIFFError(TIFFFileName(out),
++            "Error, uint32 overflow when computing (bps * spp * width) + 7");
++      return 1;
++  }
++  rowsize = ((bps * spp * width) + 7U) / 8; /* source has interleaved samples */
++  if( bytes_per_sample == 0 ||
++      rowsperstrip > TIFF_UINT32_MAX / bytes_per_sample ||
++      rowsperstrip * bytes_per_sample > TIFF_UINT32_MAX / (width + 1) )
++  {
++      TIFFError(TIFFFileName(out),
++                "Error, uint32 overflow when computing rowsperstrip * "
++                "bytes_per_sample * (width + 1)");
++      return 1;
++  }
+   rowstripsize = rowsperstrip * bytes_per_sample * (width + 1); 
+ 
+   obuf = _TIFFmalloc (rowstripsize);
+@@ -1251,11 +1270,19 @@
+     }
+     }
+ 
++  if( imagewidth == 0 ||
++      (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / imagewidth ||
++      bps * spp * imagewidth > TIFF_UINT32_MAX - 7U )
++  {
++      TIFFError(TIFFFileName(out),
++            "Error, uint32 overflow when computing (imagewidth * bps * spp) + 7");
++      return 1;
++  }
++  src_rowsize = ((imagewidth * spp * bps) + 7U) / 8;
++
+   tilebuf = _TIFFmalloc(tile_buffsize);
+   if (tilebuf == 0)
+     return 1;
+-
+-  src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
+   for (row = 0; row < imagelength; row += tl)
+     {
+     nrow = (row + tl > imagelength) ? imagelength - row : tl;
+@@ -1315,7 +1342,16 @@
+   TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
+   TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
+   TIFFGetField(out, TIFFTAG_BITSPERSAMPLE, &bps);
+-  src_rowsize = ((imagewidth * spp * bps) + 7) / 8;
++
++  if( imagewidth == 0 ||
++      (uint32)bps * (uint32)spp > TIFF_UINT32_MAX / imagewidth ||
++      bps * spp * imagewidth > TIFF_UINT32_MAX - 7 )
++  {
++      TIFFError(TIFFFileName(out),
++            "Error, uint32 overflow when computing (imagewidth * bps * spp) + 7");
++      return 1;
++  }
++  src_rowsize = ((imagewidth * spp * bps) + 7U) / 8;
+          
+   for (row = 0; row < imagelength; row += tl)
+     {