Talos Vulnerability Report

TALOS-2017-0395

Simple DirectMedia Layer Create RGB Surface Code Execution Vulnerability

October 10, 2017
CVE Number

CVE-2017-2888

Summary

An exploitable integer overflow vulnerability exists when creating a new RGB Surface in SDL 2.0.5. A specially crafted file can cause an integer overflow resulting in too little memory being allocated which can lead to a buffer overflow and potential code execution. An attacker can provide a specially crafted image file to trigger this vulnerability.

Tested Versions

Simple DirectMedia Layer 2.0.5

Product URLs

https://www.libsdl.org/

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-190: Integer Overflow or Wraparound

Details

SDL is a cross-platform library that is designed to provide low-level access to various hardware using OpenGL and Direct3D. The various users of the library include games, video playback software (including VLC), and emulators.

An integer overflow vulnerability exits when creating new RGB surfaces via the call to CreateRGBSurface. The function is defined at line 114 in src\video\SDL_surface.c:

113	SDL_Surface *
114	    SDL_CreateRGBSurface(Uint32 flags,
115           int width, int height, int depth,
116           Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)

This function will subsequently call the function: SDL_CreateRGBSurfaceWithFormat():

127	SDL_CreateRGBSurfaceWithFormat(flags, width, height, depth, format);

This function will take the width and height arguments as well as the bytes\_per\_pixel, passed in by the file format, and use them all to allocate memory:

56	surface->w = width;
57	surface->h = height;
58	surface->pitch = SDL_CalculatePitch(surface);

It will calculate the pitch at line 58, which is essentially a multiplication of the width with the bytes_per_pixel with alignment.

Then at line 83, it uses the pitch and the height to calculate the amount of memory that should be allocated:

82	if (surface->w && surface->h) {
83        surface->pixels = SDL_malloc(surface->h * surface->pitch);

Given that there are no checks to make sure the multiplications don’t overflow, this will result in an integer overflow where too little memory might be allocated, resulting in a heap-based buffer overflow when attempting to write to this memory.

The CreateRGBSurface function is used in many image formats in SDL_Image and can thus result in potential buffer overflows in many file formats. As an example here we provide the use of the function in the XCF format.

In SDL_image in IMG_xcf.c the height and width will be read directly from the file in the function read_xcf_header, defined at line 296:

302  h->width       = SDL_ReadBE32 (src);
303  h->height      = SDL_ReadBE32 (src);

This function will be used in the function IMG_LoadXCF_RW defined at line 692:

714 head = read_xcf_header (src);

Next it will allocate a surface for the various layers that may exist in the file:

747 lays = SDL_CreateRGBSurface(SDL_SWSURFACE, head->width, head->height, 32,
  748                         0x00FF0000,0x0000FF00,0x000000FF,0xFF000000);

And will then for each layer in the file, read in the layer and save it to the surface:

756 for (i = offsets; i > 0; i--) {
757	    SDL_Rect rs, rd;
758	    SDL_RWseek (src, head->layer_file_offsets [i-1], RW_SEEK_SET);
760	    layer = read_xcf_layer (src);
761	    do_layer_surface (lays, src, head, layer, load_tile);

The function do_layer_surface will subsequently write to the memory allocated in the pixels variable in loops:

  590 for (y=ty; y < ty+oy; y++) {
  591  row = (Uint32 *)((Uint8 *)surface->pixels + y*surface->pitch + tx*4);
  592  switch (hierarchy->bpp) {
  593   case 4:
  594    for (x=tx; x < tx+ox; x++)
  595       *row++ = Swap32 (*p++);
  596    break;

If an attacker has selected the height and width in such a way that the multiplication causes an integer overflow, then too little memory will have been allocated and the code at line 595 will result in an out of bounds write, potentially resulting in code execution.

Timeline

2017-10-06 - Vendor Disclosure
2017-10-10 - Public Release

Credit

Discovered by Yves Younan of Cisco Talos.