Lucene search

K
talosTalos IntelligenceTALOS-2017-0395
HistoryOct 10, 2017 - 12:00 a.m.

Simple DirectMedia Layer Create RGB Surface Code Execution Vulnerability

2017-10-1000:00:00
Talos Intelligence
www.talosintelligence.com
44

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

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

6.8 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:M/Au:N/C:P/I:P/A:P

0.006 Low

EPSS

Percentile

78.3%

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/&gt;

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-&gt;w = width;
57	surface-&gt;h = height;
58	surface-&gt;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-&gt;w && surface-&gt;h) {
83        surface-&gt;pixels = SDL_malloc(surface-&gt;h * surface-&gt;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-&gt;width       = SDL_ReadBE32 (src);
303  h-&gt;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-&gt;width, head-&gt;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 &gt; 0; i--) {
757	    SDL_Rect rs, rd;
758	    SDL_RWseek (src, head-&gt;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 &lt; ty+oy; y++) {
  591  row = (Uint32 *)((Uint8 *)surface-&gt;pixels + y*surface-&gt;pitch + tx*4);
  592  switch (hierarchy-&gt;bpp) {
  593   case 4:
  594    for (x=tx; x &lt; 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

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

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

6.8 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:M/Au:N/C:P/I:P/A:P

0.006 Low

EPSS

Percentile

78.3%