Fixed bug 1821 - IMG_LoadLBM/PNM/XCF_RW() crash with a heap corruption on loading LBM, PNM or XCF images
authorSam Lantinga <slouken@libsdl.org>
Thu, 25 Apr 2013 00:22:51 -0700
changeset 367b2aa197f6774
parent 366 f58b3461c128
child 368 8a61842d00ce
Fixed bug 1821 - IMG_LoadLBM/PNM/XCF_RW() crash with a heap corruption on loading LBM, PNM or XCF images

Marcus von Appen

Trying to load a LBM image via any of the IMG_* functions will lead to a heap corruption on Windows 7, causing the application to crash.

The problem is caused by the usage of SDL_malloc on Win32, which by default uses dlmalloc, which in turn redefines malloc and free within the SDL address space.

The CRT heap manager hence is unaware of the pointer being allocated and will try to free an unmanaged memory segment by calling free() on the temporary buffer in IMG_LoadLBM_RW().
IMG_lbm.c
IMG_pcx.c
IMG_pnm.c
IMG_xcf.c
     1.1 --- a/IMG_lbm.c	Tue Apr 23 20:15:22 2013 -0700
     1.2 +++ b/IMG_lbm.c	Thu Apr 25 00:22:51 2013 -0700
     1.3 @@ -467,7 +467,7 @@
     1.4  
     1.5  done:
     1.6  
     1.7 -	if ( MiniBuf ) free( MiniBuf );
     1.8 +	if ( MiniBuf ) SDL_free( MiniBuf );
     1.9  
    1.10  	if ( error )
    1.11  	{
     2.1 --- a/IMG_pcx.c	Tue Apr 23 20:15:22 2013 -0700
     2.2 +++ b/IMG_pcx.c	Thu Apr 25 00:22:51 2013 -0700
     2.3 @@ -149,7 +149,7 @@
     2.4  	if (bpl > surface->pitch) {
     2.5  		error = "bytes per line is too large (corrupt?)";
     2.6  	}
     2.7 -	buf = (Uint8 *)malloc(bpl);
     2.8 +	buf = (Uint8 *)SDL_malloc(bpl);
     2.9  	row = (Uint8 *)surface->pixels;
    2.10  	for ( y=0; y<surface->h; ++y ) {
    2.11  		/* decode a scan line to a temporary buffer first */
    2.12 @@ -247,7 +247,7 @@
    2.13  	}
    2.14  
    2.15  done:
    2.16 -	free(buf);
    2.17 +	SDL_free(buf);
    2.18  	if ( error ) {
    2.19  		SDL_RWseek(src, start, RW_SEEK_SET);
    2.20  		if ( surface ) {
     3.1 --- a/IMG_pnm.c	Tue Apr 23 20:15:22 2013 -0700
     3.2 +++ b/IMG_pnm.c	Thu Apr 25 00:22:51 2013 -0700
     3.3 @@ -229,7 +229,7 @@
     3.4  		row += surface->pitch;
     3.5  	}
     3.6  done:
     3.7 -	free(buf);
     3.8 +	SDL_free(buf);
     3.9  	if(error) {
    3.10  		SDL_RWseek(src, start, RW_SEEK_SET);
    3.11  		if ( surface ) {
     4.1 --- a/IMG_xcf.c	Tue Apr 23 20:15:22 2013 -0700
     4.2 +++ b/IMG_xcf.c	Thu Apr 25 00:22:51 2013 -0700
     4.3 @@ -231,7 +231,7 @@
     4.4  
     4.5    tmp = SDL_ReadBE32 (src);
     4.6    if (tmp > 0) {
     4.7 -    data = (char *) malloc (sizeof (char) * tmp);
     4.8 +    data = (char *) SDL_malloc (sizeof (char) * tmp);
     4.9      SDL_RWread (src, data, tmp, 1);
    4.10    }
    4.11    else {
    4.12 @@ -261,7 +261,7 @@
    4.13    switch (prop->id) {
    4.14    case PROP_COLORMAP:
    4.15      prop->data.colormap.num = SDL_ReadBE32 (src);
    4.16 -    prop->data.colormap.cmap = (char *) malloc (sizeof (char) * prop->data.colormap.num * 3);
    4.17 +    prop->data.colormap.cmap = (char *) SDL_malloc (sizeof (char) * prop->data.colormap.num * 3);
    4.18      SDL_RWread (src, prop->data.colormap.cmap, prop->data.colormap.num*3, 1);
    4.19      break;
    4.20  
    4.21 @@ -287,16 +287,16 @@
    4.22  
    4.23  static void free_xcf_header (xcf_header * h) {
    4.24    if (h->cm_num)
    4.25 -    free (h->cm_map);
    4.26 +    SDL_free (h->cm_map);
    4.27  
    4.28 -  free (h);
    4.29 +  SDL_free (h);
    4.30  }
    4.31  
    4.32  static xcf_header * read_xcf_header (SDL_RWops * src) {
    4.33    xcf_header * h;
    4.34    xcf_prop prop;
    4.35  
    4.36 -  h = (xcf_header *) malloc (sizeof (xcf_header));
    4.37 +  h = (xcf_header *) SDL_malloc (sizeof (xcf_header));
    4.38    SDL_RWread (src, h->sign, 14, 1);
    4.39    h->width       = SDL_ReadBE32 (src);
    4.40    h->height      = SDL_ReadBE32 (src);
    4.41 @@ -318,7 +318,7 @@
    4.42        h->cm_num = prop.data.colormap.num;
    4.43        h->cm_map = (unsigned char *) SDL_malloc (sizeof (unsigned char) * 3 * h->cm_num);
    4.44        memcpy (h->cm_map, prop.data.colormap.cmap, 3*sizeof (char)*h->cm_num);
    4.45 -      free (prop.data.colormap.cmap);
    4.46 +      SDL_free (prop.data.colormap.cmap);
    4.47      }
    4.48    } while (prop.id != PROP_END);
    4.49  
    4.50 @@ -326,15 +326,15 @@
    4.51  }
    4.52  
    4.53  static void free_xcf_layer (xcf_layer * l) {
    4.54 -  free (l->name);
    4.55 -  free (l);
    4.56 +  SDL_free (l->name);
    4.57 +  SDL_free (l);
    4.58  }
    4.59  
    4.60  static xcf_layer * read_xcf_layer (SDL_RWops * src) {
    4.61    xcf_layer * l;
    4.62    xcf_prop    prop;
    4.63  
    4.64 -  l = (xcf_layer *) malloc (sizeof (xcf_layer));
    4.65 +  l = (xcf_layer *) SDL_malloc (sizeof (xcf_layer));
    4.66    l->width  = SDL_ReadBE32 (src);
    4.67    l->height = SDL_ReadBE32 (src);
    4.68    l->layer_type = SDL_ReadBE32 (src);
    4.69 @@ -358,8 +358,8 @@
    4.70  }
    4.71  
    4.72  static void free_xcf_channel (xcf_channel * c) {
    4.73 -  free (c->name);
    4.74 -  free (c);
    4.75 +  SDL_free (c->name);
    4.76 +  SDL_free (c);
    4.77  }
    4.78  
    4.79  static xcf_channel * read_xcf_channel (SDL_RWops * src) {
    4.80 @@ -401,15 +401,15 @@
    4.81  }
    4.82  
    4.83  static void free_xcf_hierarchy (xcf_hierarchy * h) {
    4.84 -  free (h->level_file_offsets);
    4.85 -  free (h);
    4.86 +  SDL_free (h->level_file_offsets);
    4.87 +  SDL_free (h);
    4.88  }
    4.89  
    4.90  static xcf_hierarchy * read_xcf_hierarchy (SDL_RWops * src) {
    4.91    xcf_hierarchy * h;
    4.92    int i;
    4.93  
    4.94 -  h = (xcf_hierarchy *) malloc (sizeof (xcf_hierarchy));
    4.95 +  h = (xcf_hierarchy *) SDL_malloc (sizeof (xcf_hierarchy));
    4.96    h->width  = SDL_ReadBE32 (src);
    4.97    h->height = SDL_ReadBE32 (src);
    4.98    h->bpp    = SDL_ReadBE32 (src);
    4.99 @@ -425,8 +425,8 @@
   4.100  }
   4.101  
   4.102  static void free_xcf_level (xcf_level * l) {
   4.103 -  free (l->tile_file_offsets);
   4.104 -  free (l);
   4.105 +  SDL_free (l->tile_file_offsets);
   4.106 +  SDL_free (l);
   4.107  }
   4.108  
   4.109  static xcf_level * read_xcf_level (SDL_RWops * src) {
   4.110 @@ -448,7 +448,7 @@
   4.111  }
   4.112  
   4.113  static void free_xcf_tile (unsigned char * t) {
   4.114 -  free (t);
   4.115 +  SDL_free (t);
   4.116  }
   4.117  
   4.118  static unsigned char * load_xcf_tile_none (SDL_RWops * src, Uint32 len, int bpp, int x, int y) {
   4.119 @@ -469,7 +469,7 @@
   4.120    t = load = (unsigned char *) SDL_malloc (len);
   4.121    reallen = SDL_RWread (src, t, 1, len);
   4.122  
   4.123 -  data = (unsigned char *) malloc (x*y*bpp);
   4.124 +  data = (unsigned char *) SDL_malloc (x*y*bpp);
   4.125    for (i = 0; i < bpp; i++) {
   4.126      d    = data + i;
   4.127      size = x*y;