Fixed TALOS-2019-0844 - XPM image colorhash parsing Code Execution Vulnerability
authorSam Lantinga <slouken@libsdl.org>
Tue, 11 Jun 2019 00:15:06 -0700
changeset 65826061e601c81
parent 657 95fc7da55247
child 659 92ff8280a823
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.
IMG_xpm.c
     1.1 --- a/IMG_xpm.c	Mon Jun 10 23:50:21 2019 -0700
     1.2 +++ b/IMG_xpm.c	Tue Jun 11 00:15:06 2019 -0700
     1.3 @@ -101,7 +101,7 @@
     1.4  
     1.5      /* we know how many entries we need, so we can allocate
     1.6         everything here */
     1.7 -    hash = (struct color_hash *)SDL_malloc(sizeof *hash);
     1.8 +    hash = (struct color_hash *)SDL_calloc(1, sizeof(*hash));
     1.9      if (!hash)
    1.10          return NULL;
    1.11  
    1.12 @@ -110,15 +110,29 @@
    1.13          ;
    1.14      hash->size = s;
    1.15      hash->maxnum = maxnum;
    1.16 +
    1.17      bytes = hash->size * sizeof(struct hash_entry **);
    1.18 -    hash->entries = NULL;   /* in case malloc fails */
    1.19 -    hash->table = (struct hash_entry **)SDL_malloc(bytes);
    1.20 +    /* Check for overflow */
    1.21 +    if ((bytes / sizeof(struct hash_entry **)) != hash->size) {
    1.22 +        IMG_SetError("memory allocation overflow");
    1.23 +        SDL_free(hash);
    1.24 +        return NULL;
    1.25 +    }
    1.26 +    hash->table = (struct hash_entry **)SDL_calloc(1, bytes);
    1.27      if (!hash->table) {
    1.28          SDL_free(hash);
    1.29          return NULL;
    1.30      }
    1.31 -    SDL_memset(hash->table, 0, bytes);
    1.32 -    hash->entries = (struct hash_entry *)SDL_malloc(maxnum * sizeof(struct hash_entry));
    1.33 +
    1.34 +    bytes = maxnum * sizeof(struct hash_entry);
    1.35 +    /* Check for overflow */
    1.36 +    if ((bytes / sizeof(struct hash_entry)) != maxnum) {
    1.37 +        IMG_SetError("memory allocation overflow");
    1.38 +        SDL_free(hash->table);
    1.39 +        SDL_free(hash);
    1.40 +        return NULL;
    1.41 +    }
    1.42 +    hash->entries = (struct hash_entry *)SDL_calloc(1, bytes);
    1.43      if (!hash->entries) {
    1.44          SDL_free(hash->table);
    1.45          SDL_free(hash);