File gd-CVE-2016-6905.patch of Package gd.10570

6aa343e6e195bf65fb47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@sury.org>
Date: Tue, 12 Jul 2016 14:20:16 +0200
Subject: [PATCH] bug #248, fix Out-Of-Bounds Read in read_image_tga

---
 src/gd_tga.c | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

Index: libgd-2.1.0/src/gd_tga.c
===================================================================
--- libgd-2.1.0.orig/src/gd_tga.c	2016-08-08 13:15:15.053952732 +0200
+++ libgd-2.1.0/src/gd_tga.c	2016-08-08 13:16:53.639592199 +0200
@@ -196,7 +196,6 @@ int read_image_tga( gdIOCtx *ctx, oTga *
 	int buffer_caret = 0;
 	int bitmap_caret = 0;
 	int i = 0;
-	int j = 0;
 	uint8_t encoded_pixels;
 
 	if(overflow2(tga->width, tga->height)) {
@@ -281,27 +280,36 @@ int read_image_tga( gdIOCtx *ctx, oTga *
 		buffer_caret = 0;
 
 		while( bitmap_caret < image_block_size ) {
-
+			
 			if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) {
-				encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & 127 ) + 1 );
+				encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & !TGA_RLE_FLAG ) + 1 );
 				buffer_caret++;
 
+				if ((bitmap_caret + (encoded_pixels * pixel_block_size)) >= image_block_size) {
+					gdFree( decompression_buffer );
+					gdFree( conversion_buffer );
+					return -1;
+				}
+
 				for (i = 0; i < encoded_pixels; i++) {
-					for (j = 0; j < pixel_block_size; j++, bitmap_caret++) {
-						tga->bitmap[ bitmap_caret ] = decompression_buffer[ buffer_caret + j ];
-					}
+					memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size);
+					bitmap_caret += pixel_block_size;
 				}
 				buffer_caret += pixel_block_size;
+
 			} else {
 				encoded_pixels = decompression_buffer[ buffer_caret ] + 1;
 				buffer_caret++;
 
-				for (i = 0; i < encoded_pixels; i++) {
-					for( j = 0; j < pixel_block_size; j++, bitmap_caret++ ) {
-						tga->bitmap[ bitmap_caret ] = decompression_buffer[ buffer_caret + j ];
-					}
-					buffer_caret += pixel_block_size;
+				if ((bitmap_caret + (encoded_pixels * pixel_block_size)) >= image_block_size) {
+					gdFree( decompression_buffer );
+					gdFree( conversion_buffer );
+					return -1;
 				}
+
+				memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size);
+				bitmap_caret += (encoded_pixels * pixel_block_size);
+				buffer_caret += (encoded_pixels * pixel_block_size);
 			}
 		}