Sophie

Sophie

distrib > Mageia > 8 > x86_64 > by-pkgid > a48407b9ae23d07a9f26b820f1a114a4 > files > 18

SDL_image-1.2.12-14.mga8.src.rpm

Backport of upstream fix:

# HG changeset patch
# User Sam Lantinga <slouken@libsdl.org>
# Date 1560237306 25200
# Node ID 26061e601c8157427ca319d943a715174dadce8c
# Parent  95fc7da55247a4368848144b9374a88a6494fd5c
Fixed TALOS-2019-0844 - XPM image colorhash parsing Code Execution Vulnerability

The table entry in the color_hash is created in the create_colorhash function based on the number of colors passed into the function. The size of the color_hash table is the first value in the powers of 2 larger than the passed in number of colors [2]. The size of the allocation is this calculated value * 8 (sizeof(struct hash_entry **)) [3]. This multiplication can cause an overflow, resulting in a very small allocation.

--- sdl-image1.2-1.2.12.orig/IMG_xpm.c
+++ sdl-image1.2-1.2.12/IMG_xpm.c
@@ -106,7 +106,7 @@ static struct color_hash *create_colorha
 
 	/* we know how many entries we need, so we can allocate
 	   everything here */
-	hash = malloc(sizeof *hash);
+	hash = calloc(1, sizeof *hash);
 	if(!hash)
 		return NULL;
 
@@ -115,13 +115,27 @@ static struct color_hash *create_colorha
 		;
 	hash->size = s;
 	hash->maxnum = maxnum;
+
 	bytes = hash->size * sizeof(struct hash_entry **);
-	hash->entries = NULL;	/* in case malloc fails */
-	hash->table = malloc(bytes);
+	/* Check for overflow */
+	if ((bytes / sizeof(struct hash_entry **)) != hash->size) {
+		IMG_SetError("memory allocation overflow");
+		free(hash);
+		return NULL;
+	}
+	hash->table = (struct hash_entry **)calloc(1, bytes);
 	if(!hash->table)
 		return NULL;
-	memset(hash->table, 0, bytes);
-	hash->entries = malloc(maxnum * sizeof(struct hash_entry));
+
+	bytes = maxnum * sizeof(struct hash_entry);
+	/* Check for overflow */
+	if ((bytes / sizeof(struct hash_entry)) != maxnum) {
+		IMG_SetError("memory allocation overflow");
+		free(hash->table);
+		free(hash);
+		return NULL;
+	}
+	hash->entries = (struct hash_entry *)calloc(1, bytes);
 	if(!hash->entries) {
 		free(hash->table);
 		return NULL;