summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gnu/local.mk2
-rw-r--r--gnu/packages/image.scm4
-rw-r--r--gnu/packages/patches/freeimage-CVE-2020-21428.patch17
-rw-r--r--gnu/packages/patches/freeimage-CVE-2020-22524.patch229
4 files changed, 251 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index ccc3c233bb..0a5ecd97dc 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -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		\
diff --git a/gnu/packages/image.scm b/gnu/packages/image.scm
index d237bf689c..8a8e1eacb7 100644
--- a/gnu/packages/image.scm
+++ b/gnu/packages/image.scm
@@ -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)
diff --git a/gnu/packages/patches/freeimage-CVE-2020-21428.patch b/gnu/packages/patches/freeimage-CVE-2020-21428.patch
new file mode 100644
index 0000000000..49f427360b
--- /dev/null
+++ b/gnu/packages/patches/freeimage-CVE-2020-21428.patch
@@ -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;

+ 

diff --git a/gnu/packages/patches/freeimage-CVE-2020-22524.patch b/gnu/packages/patches/freeimage-CVE-2020-22524.patch
new file mode 100644
index 0000000000..47368d7d91
--- /dev/null
+++ b/gnu/packages/patches/freeimage-CVE-2020-22524.patch
@@ -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);
+ 		}