Description: Fix security issue CVE-2012-2845
Author: Dan Fandrich <dan@coneharvesters.com>
Origin: backport
Bug-Debian: http://bugs.debian.org/681465
Applied-Upstream: 0.6.21
Forwarded: not-needed
--- a/libjpeg/jpeg-data.c
+++ b/libjpeg/jpeg-data.c
@@ -205,7 +205,7 @@
 		for (i = 0; i < MIN(7, size - o); i++)
 			if (d[o + i] != 0xff)
 				break;
-		if (!JPEG_IS_MARKER (d[o + i])) {
+		if ((i >= size - o) || !JPEG_IS_MARKER (d[o + i])) {
 			exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "jpeg-data",
 					_("Data does not follow JPEG specification."));
 			return;
@@ -226,10 +226,11 @@
 		default:
 
 			/* Read the length of the section */
+			if (2 > size - o) { o = size; break; }
 			len = ((d[o] << 8) | d[o + 1]) - 2;
 			if (len > size) { o = size; break; }
 			o += 2;
-			if (o + len > size) { o = size; break; }
+			if (len > size - o) { o = size; break; }
 
 			switch (s->marker) {
 			case JPEG_MARKER_APP1:
@@ -245,14 +246,18 @@
 
 				/* In case of SOS, image data will follow. */
 				if (s->marker == JPEG_MARKER_SOS) {
-					/* -2 means 'take all but the last 2 bytes which are hoped to be JPEG_MARKER_EOI */
-					data->size = size - 2 - o - len;
-					if (d[o + len + data->size] != 0xFF) {
-						/* A truncated file (i.e. w/o JPEG_MARKER_EOI at the end).
-						   Instead of trying to use the last two bytes as marker,
-						   touching memory beyond allocated memory and posssibly saving
-						   back screwed file, we rather take the rest of the file. */
-						data->size += 2;
+					data->size = size - o - len;
+					if (data->size >= 2) {
+						/* -2 means 'take all but the last 2 bytes which are
+						   hoped to be JPEG_MARKER_EOI */
+						data->size -= 2;
+						if (d[o + len + data->size] != 0xFF) {
+							/* A truncated file (i.e. w/o JPEG_MARKER_EOI at the end).
+							   Instead of trying to use the last two bytes as marker,
+							   touching memory beyond allocated memory and posssibly saving
+							   back screwed file, we rather take the rest of the file. */
+							data->size += 2;
+						}
 					}
 					data->data = malloc (
 						sizeof (char) * data->size);
