~ruther/guix-local

93bd4a37eedb475ec0e6015be8f78fc074a7f389 — Mark H Weaver 10 years ago bcc09d9
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.
3 files changed, 132 insertions(+), 1 deletions(-)

M gnu-system.am
M gnu/packages/image.scm
A gnu/packages/patches/freeimage-CVE-2015-0852.patch
M gnu-system.am => gnu-system.am +1 -0
@@ 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		\

M gnu/packages/image.scm => gnu/packages/image.scm +2 -1
@@ 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

A gnu/packages/patches/freeimage-CVE-2015-0852.patch => gnu/packages/patches/freeimage-CVE-2015-0852.patch +129 -0
@@ 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 ?