summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2015-10-02 12:52:00 -0400
committerMark H Weaver <mhw@netris.org>2015-10-02 12:53:21 -0400
commit93bd4a37eedb475ec0e6015be8f78fc074a7f389 (patch)
tree486e5401aee94a30b14c16332a3e39d94dd26b72
parentbcc09d9ac1d174be06610a772e9cb27a959d53c0 (diff)
downloadguix-93bd4a37eedb475ec0e6015be8f78fc074a7f389.tar.gz
gnu: freeimage: Add fix for CVE-2015-0852.
* gnu/packages/patches/freeimage-CVE-2015-0852.patch: New file.
* gnu-system.am (dist_patch_DATA): Add it.
* gnu/packages/image.scm (freeimage)[source]: Add patch.
-rw-r--r--gnu-system.am1
-rw-r--r--gnu/packages/image.scm3
-rw-r--r--gnu/packages/patches/freeimage-CVE-2015-0852.patch129
3 files changed, 132 insertions, 1 deletions
diff --git a/gnu-system.am b/gnu-system.am
index 17012af51b..2964367192 100644
--- a/gnu-system.am
+++ b/gnu-system.am
@@ -452,6 +452,7 @@ dist_patch_DATA =						\
   gnu/packages/patches/flex-bison-tests.patch			\
   gnu/packages/patches/flint-ldconfig.patch			\
   gnu/packages/patches/fltk-shared-lib-defines.patch		\
+  gnu/packages/patches/freeimage-CVE-2015-0852.patch		\
   gnu/packages/patches/fuse-CVE-2015-3202.patch			\
   gnu/packages/patches/gawk-shell.patch				\
   gnu/packages/patches/gcc-arm-link-spec-fix.patch		\
diff --git a/gnu/packages/image.scm b/gnu/packages/image.scm
index 456f42f497..26f1be9a2f 100644
--- a/gnu/packages/image.scm
+++ b/gnu/packages/image.scm
@@ -469,7 +469,8 @@ supplies a generic doubly-linked list and some string functions.")
                   ".zip"))
             (sha256
              (base32
-              "12bz57asdcfsz3zr9i9nska0fb6h3z2aizy412qjqkixkginbz7v"))))
+              "12bz57asdcfsz3zr9i9nska0fb6h3z2aizy412qjqkixkginbz7v"))
+            (patches (list (search-patch "freeimage-CVE-2015-0852.patch")))))
    (build-system gnu-build-system)
    (arguments
     '(#:phases (alist-delete
diff --git a/gnu/packages/patches/freeimage-CVE-2015-0852.patch b/gnu/packages/patches/freeimage-CVE-2015-0852.patch
new file mode 100644
index 0000000000..34d538e925
--- /dev/null
+++ b/gnu/packages/patches/freeimage-CVE-2015-0852.patch
@@ -0,0 +1,129 @@
+Copied from Debian.
+
+Description: fix integer overflow
+Origin: upstream
+ http://freeimage.cvs.sourceforge.net/viewvc/freeimage/FreeImage/Source/FreeImage/PluginPCX.cpp?view=patch&r1=1.17&r2=1.18&pathrev=MAIN
+ http://freeimage.cvs.sourceforge.net/viewvc/freeimage/FreeImage/Source/FreeImage/PluginPCX.cpp?view=patch&r1=1.18&r2=1.19&pathrev=MAIN
+Bug-Debian: https://bugs.debian.org/797165
+Last-Update: 2015-09-14
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+Index: freeimage/Source/FreeImage/PluginPCX.cpp
+===================================================================
+--- freeimage.orig/Source/FreeImage/PluginPCX.cpp
++++ freeimage/Source/FreeImage/PluginPCX.cpp
+@@ -347,12 +347,14 @@ Load(FreeImageIO *io, fi_handle handle,
+ 
+ 	try {
+ 		// check PCX identifier
+-
+-		long start_pos = io->tell_proc(handle);
+-		BOOL validated = pcx_validate(io, handle);		
+-		io->seek_proc(handle, start_pos, SEEK_SET);
+-		if(!validated) {
+-			throw FI_MSG_ERROR_MAGIC_NUMBER;
++		// (note: should have been already validated using FreeImage_GetFileType but check again)
++		{
++			long start_pos = io->tell_proc(handle);
++			BOOL validated = pcx_validate(io, handle);
++			io->seek_proc(handle, start_pos, SEEK_SET);
++			if(!validated) {
++				throw FI_MSG_ERROR_MAGIC_NUMBER;
++			}
+ 		}
+ 
+ 		// process the header
+@@ -366,20 +368,38 @@ Load(FreeImageIO *io, fi_handle handle,
+ 		SwapHeader(&header);
+ #endif
+ 
+-		// allocate a new DIB
++		// process the window
++		const WORD *window = header.window;	// left, upper, right,lower pixel coord.
++		const int left		= window[0];
++		const int top		= window[1];
++		const int right		= window[2];
++		const int bottom	= window[3];
+ 
+-		unsigned width = header.window[2] - header.window[0] + 1;
+-		unsigned height = header.window[3] - header.window[1] + 1;
+-		unsigned bitcount = header.bpp * header.planes;
+-
+-		if (bitcount == 24) {
+-			dib = FreeImage_AllocateHeader(header_only, width, height, bitcount, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+-		} else {
+-			dib = FreeImage_AllocateHeader(header_only, width, height, bitcount);			
++		// check image size
++		if((left >= right) || (top >= bottom)) {
++			throw FI_MSG_ERROR_PARSING;
+ 		}
+ 
+-		// if the dib couldn't be allocated, throw an error
++		const unsigned width = right - left + 1;
++		const unsigned height = bottom - top + 1;
++		const unsigned bitcount = header.bpp * header.planes;
++
++		// allocate a new DIB
++		switch(bitcount) {
++			case 1:
++			case 4:
++			case 8:
++				dib = FreeImage_AllocateHeader(header_only, width, height, bitcount);
++				break;
++			case 24:
++				dib = FreeImage_AllocateHeader(header_only, width, height, bitcount, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
++				break;
++			default:
++				throw FI_MSG_ERROR_DIB_MEMORY;
++				break;
++		}
+ 
++		// if the dib couldn't be allocated, throw an error
+ 		if (!dib) {
+ 			throw FI_MSG_ERROR_DIB_MEMORY;
+ 		}
+@@ -426,19 +446,23 @@ Load(FreeImageIO *io, fi_handle handle,
+ 
+ 				if (palette_id == 0x0C) {
+ 					BYTE *cmap = (BYTE*)malloc(768 * sizeof(BYTE));
+-					io->read_proc(cmap, 768, 1, handle);
+ 
+-					pal = FreeImage_GetPalette(dib);
+-					BYTE *pColormap = &cmap[0];
++					if(cmap) {
++						io->read_proc(cmap, 768, 1, handle);
+ 
+-					for(int i = 0; i < 256; i++) {
+-						pal[i].rgbRed   = pColormap[0];
+-						pal[i].rgbGreen = pColormap[1];
+-						pal[i].rgbBlue  = pColormap[2];
+-						pColormap += 3;
++						pal = FreeImage_GetPalette(dib);
++						BYTE *pColormap = &cmap[0];
++
++						for(int i = 0; i < 256; i++) {
++							pal[i].rgbRed   = pColormap[0];
++							pal[i].rgbGreen = pColormap[1];
++							pal[i].rgbBlue  = pColormap[2];
++							pColormap += 3;
++						}
++
++						free(cmap);
+ 					}
+ 
+-					free(cmap);
+ 				}
+ 
+ 				// wrong palette ID, perhaps a gray scale is needed ?
+@@ -466,9 +490,9 @@ Load(FreeImageIO *io, fi_handle handle,
+ 		// calculate the line length for the PCX and the DIB
+ 
+ 		// length of raster line in bytes
+-		unsigned linelength = header.bytes_per_line * header.planes;
++		const unsigned linelength = header.bytes_per_line * header.planes;
+ 		// length of DIB line (rounded to DWORD) in bytes
+-		unsigned pitch = FreeImage_GetPitch(dib);
++		const unsigned pitch = FreeImage_GetPitch(dib);
+ 
+ 		// run-length encoding ?
+