CVE-2017-2888
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.
Simple DirectMedia Layer 2.0.5
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-190: Integer Overflow or Wraparound
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.
2017-10-06 - Vendor Disclosure
2017-10-10 - Public Release
Discovered by Yves Younan of Cisco Talos.