summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/freeimage-CVE-2015-0852.patch
blob: 34d538e92591839795a83a3eac3e7aee21aa1153 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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 ?