~ruther/guix-local

29c94dd522833b2603a651c14a5b06120bcf1829 — Efraim Flashner 2 years ago f410d49
gnu: freeimage: Patch 2 CVEs.

* gnu/packages/image.scm (freeimage)[source]: Add patches.
* gnu/packages/patches/freeimage-CVE-2020-21428.patch,
gnu/packages/patches/freeimage-CVE-2020-22524.patch: New files.
* gnu/local.mk (dist_patch_DATA): Register them.

Change-Id: Iec114f2295cafbc8b55e81c0d8e4a361fd653152
M gnu/local.mk => gnu/local.mk +2 -0
@@ 1189,6 1189,8 @@ dist_patch_DATA =						\
  %D%/packages/patches/freedink-engine-fix-sdl-hints.patch	\
  %D%/packages/patches/freeimage-libtiff-compat.patch		\
  %D%/packages/patches/freeimage-unbundle.patch		\
  %D%/packages/patches/freeimage-CVE-2020-21428.patch		\
  %D%/packages/patches/freeimage-CVE-2020-22524.patch		\
  %D%/packages/patches/fulcrum-1.9.1-unbundled-libraries.patch	\
  %D%/packages/patches/fuse-glibc-2.34.patch			\
  %D%/packages/patches/fuse-overlapping-headers.patch		\

M gnu/packages/image.scm => gnu/packages/image.scm +3 -1
@@ 1253,7 1253,9 @@ supplies a generic doubly-linked list and some string functions.")
              (patches
               (append
                (search-patches "freeimage-unbundle.patch"
                                "freeimage-libtiff-compat.patch")
                                "freeimage-libtiff-compat.patch"
                                "freeimage-CVE-2020-21428.patch"
                                "freeimage-CVE-2020-22524.patch")
                ;; Take one patch from Arch Linux that adds LibRaw 0.20 compatibility.
                (list (origin
                        (method url-fetch)

A gnu/packages/patches/freeimage-CVE-2020-21428.patch => gnu/packages/patches/freeimage-CVE-2020-21428.patch +17 -0
@@ 0,0 1,17 @@
https://sources.debian.org/data/main/f/freeimage/3.18.0%2Bds2-10/debian/patches/r1877-improved-DDS-plugin-against-malicious-images.patch

Origin: upstream, r1877
Index: Source/FreeImage/PluginDDS.cpp
===================================================================
diff --git a/Source/FreeImage/PluginDDS.cpp b/Source/FreeImage/PluginDDS.cpp
--- a/Source/FreeImage/PluginDDS.cpp	(revision 1876)
+++ b/Source/FreeImage/PluginDDS.cpp	(revision 1877)
@@ -617,7 +617,7 @@
 	// read the file
 	// -------------------------------------------------------------------------
 
-	const int line = CalculateLine(width, bpp);
+	const int line = CalculateLine(width, FreeImage_GetBPP(dib));
 	const int filePitch = ((desc->dwFlags & DDSD_PITCH) == DDSD_PITCH) ? (int)desc->dwPitchOrLinearSize : line;
 	const long delta = (long)filePitch - (long)line;
 

A gnu/packages/patches/freeimage-CVE-2020-22524.patch => gnu/packages/patches/freeimage-CVE-2020-22524.patch +229 -0
@@ 0,0 1,229 @@
https://sources.debian.org/data/main/f/freeimage/3.18.0%2Bds2-10/debian/patches/r1848-improved-PFM-plugin-against-malicious-images.patch

Origin: upstream, r1848
Index: Source/FreeImage/PluginPFM.cpp
---
diff --git a/Source/FreeImage/PluginPFM.cpp b/Source/FreeImage/PluginPFM.cpp
--- a/Source/FreeImage/PluginPFM.cpp	(revision 1847)
+++ b/Source/FreeImage/PluginPFM.cpp	(revision 1848)
@@ -23,6 +23,12 @@
 #include "Utilities.h"
 
 // ==========================================================
+// Plugin Interface
+// ==========================================================
+
+static int s_format_id;
+
+// ==========================================================
 // Internal functions
 // ==========================================================
 
@@ -59,6 +65,9 @@
 
 /**
 Get an integer value from the actual position pointed by handle
+@param io
+@param handle
+@return Returns -1 in case of failure, returns the found number otherwise
 */
 static int
 pfm_get_int(FreeImageIO *io, fi_handle handle) {
@@ -65,70 +74,72 @@
     char c = 0;
 	BOOL bFirstChar;
 
-    // skip forward to start of next number
+	try {
 
-	if(!io->read_proc(&c, 1, 1, handle)) {
-		throw FI_MSG_ERROR_PARSING;
-	}
+		// skip forward to start of next number
 
-    while (1) {
-        // eat comments
+		if (io->read_proc(&c, 1, 1, handle) != 1) {
+			throw FI_MSG_ERROR_PARSING;
+		}
 
-        if (c == '#') {
-			// if we're at a comment, read to end of line
+		while (1) {
+			// eat comments
 
-            bFirstChar = TRUE;
+			if (c == '#') {
+				// if we're at a comment, read to end of line
 
-            while (1) {
-				if(!io->read_proc(&c, 1, 1, handle)) {
-					throw FI_MSG_ERROR_PARSING;
-				}
+				bFirstChar = TRUE;
 
-				if (bFirstChar && c == ' ') {
-					// loop off 1 sp after #
-					bFirstChar = FALSE;
-				} else if (c == '\n') {
-					break;
+				while (1) {
+					if (io->read_proc(&c, 1, 1, handle) != 1) {
+						throw FI_MSG_ERROR_PARSING;
+					}
+
+					if (bFirstChar && c == ' ') {
+						// loop off 1 sp after #
+						bFirstChar = FALSE;
+					}
+					else if (c == '\n') {
+						break;
+					}
 				}
 			}
-		}
 
-        if (c >= '0' && c <='9') {
-			// we've found what we were looking for
-            break;
-		}
+			if (c >= '0' && c <= '9') {
+				// we've found what we were looking for
+				break;
+			}
 
-		if(!io->read_proc(&c, 1, 1, handle)) {
-			throw FI_MSG_ERROR_PARSING;
+			if (io->read_proc(&c, 1, 1, handle) != 1) {
+				throw FI_MSG_ERROR_PARSING;
+			}
 		}
-    }
 
-    // we're at the start of a number, continue until we hit a non-number
+		// we're at the start of a number, continue until we hit a non-number
 
-    int i = 0;
+		int i = 0;
 
-    while (1) {
-        i = (i * 10) + (c - '0');
+		while (1) {
+			i = (i * 10) + (c - '0');
 
-		if(!io->read_proc(&c, 1, 1, handle)) {
-			throw FI_MSG_ERROR_PARSING;
-		}
+			if (io->read_proc(&c, 1, 1, handle) != 1) {
+				throw FI_MSG_ERROR_PARSING;
+			}
 
-		if (c < '0' || c > '9') {
-			break;
+			if (c < '0' || c > '9') {
+				break;
+			}
 		}
-    }
 
-    return i;
+		return i;
+	}
+	catch (const char *message) {
+		FreeImage_OutputMessageProc(s_format_id, message);
+		return -1;
+	}
 }
 
 // ==========================================================
-// Plugin Interface
-// ==========================================================
-
-static int s_format_id;
-
-// ==========================================================
 // Plugin Implementation
 // ==========================================================
 
@@ -230,8 +241,12 @@
 		}
 
 		// Read the header information: width, height and the scale value
-		unsigned width  = (unsigned) pfm_get_int(io, handle);
-		unsigned height = (unsigned) pfm_get_int(io, handle);
+		int width = pfm_get_int(io, handle);
+		int height = pfm_get_int(io, handle);
+		if ((width <= 0) || (height <= 0)) {
+			throw FI_MSG_ERROR_PARSING;
+		}
+
 		float scalefactor = 1;
 
 		BOOL bResult = pfm_get_line(io, handle, line_buffer, PFM_MAXLINE);
@@ -262,7 +277,7 @@
 				throw FI_MSG_ERROR_MEMORY;
 			}
 
-			for (unsigned y = 0; y < height; y++) {	
+			for (int y = 0; y < height; y++) {	
 				FIRGBF *bits = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
 
 				if(io->read_proc(lineBuffer, sizeof(float), lineWidth, handle) != lineWidth) {
@@ -271,7 +286,7 @@
 				float *channel = lineBuffer;
 				if(scalefactor > 0) {
 					// MSB
-					for (unsigned x = 0; x < width; x++) {
+					for (int x = 0; x < width; x++) {
 						REVERSEBYTES(channel++, &bits[x].red);
 						REVERSEBYTES(channel++, &bits[x].green);
 						REVERSEBYTES(channel++, &bits[x].blue);
@@ -278,7 +293,7 @@
 					}
 				} else {
 					// LSB					
-					for (unsigned x = 0; x < width; x++) {
+					for (int x = 0; x < width; x++) {
 						bits[x].red		= *channel++;
 						bits[x].green	= *channel++;
 						bits[x].blue	= *channel++;
@@ -296,7 +311,7 @@
 				throw FI_MSG_ERROR_MEMORY;
 			}
 
-			for (unsigned y = 0; y < height; y++) {	
+			for (int y = 0; y < height; y++) {	
 				float *bits = (float*)FreeImage_GetScanLine(dib, height - 1 - y);
 
 				if(io->read_proc(lineBuffer, sizeof(float), lineWidth, handle) != lineWidth) {
@@ -305,12 +320,12 @@
 				float *channel = lineBuffer;
 				if(scalefactor > 0) {
 					// MSB - File is Big endian
-					for (unsigned x = 0; x < width; x++) {
+					for (int x = 0; x < width; x++) {
 						REVERSEBYTES(channel++, &bits[x]);
 					}
 				} else {
 					// LSB - File is Little Endian
-					for (unsigned x = 0; x < width; x++) {
+					for (int x = 0; x < width; x++) {
 						bits[x] = *channel++;
 					}
 				}
@@ -323,9 +338,12 @@
 		return dib;
 
 	} catch (const char *text)  {
-		if(lineBuffer) free(lineBuffer);
-		if(dib) FreeImage_Unload(dib);
-
+		if (lineBuffer) {
+			free(lineBuffer);
+		}
+		if (dib) {
+			FreeImage_Unload(dib);
+		}
 		if(NULL != text) {
 			FreeImage_OutputMessageProc(s_format_id, text);
 		}