Talos Vulnerability Report

TALOS-2017-0394

Simple DirectMedia Layer SDL_image XCF Property Handling Code Execution Vulnerability

October 10, 2017
CVE Number

CVE-2017-2887

Summary

An exploitable buffer overflow vulnerability exists in the XCF property handling functionality of SDL_image 2.0.1. A specially crafted xcf file can cause a stack-based buffer overflow resulting in potential code execution. An attacker can provide a specially crafted XCF file to trigger this vulnerability.

Tested Versions

Simple DirectMedia Layer SDL_image 2.0.1

Product URLs

https://www.libsdl.org/projects/SDL_image/

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-121: Stack-based Buffer Overflow

Details

SDL_image is a library that handles image loading for the Simple DirectMedia Layer (SDL) library. 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.

A vulnerability exits in the SDL_image library’s handling of XCF images. When an XCF image is read, its properties will be read from the file and used directly in a read operation, potentially resulting in a stack-based buffer overflow. This problem occurs in the read_xcf_property function of the IMG_xcf.c file:

253   static void xcf_read_property (SDL_RWops * src, xcf_prop * prop) {
254		prop->id = SDL_ReadBE32 (src);
255		prop->length = SDL_ReadBE32 (src); ...
261	    switch (prop->id) {
...
275		case PROP_COMPRESSION:
276		case PROP_COLOR:
277			SDL_RWread (src, &prop->data, prop->length, 1);
278			break; ...

At line 254, it will read the id of the property from the file and then at line 255, it will read the length of the property. This length will then be used at line 277 to copy data from src into prop->data which is 24 bytes in length, causing a buffer overflow if the length provided in the file is larger than 24.

Mitigation

Adding a check to ensure that prop->length <= sizeof(prop->data) would fix the issue: — IMG_xcf.c.orig 2017-07-28 10:39:49.983264935 -0700 +++ IMG_xcf.c 2017-07-28 10:43:42.664540348 -0700 @@ -251,6 +251,7 @@

 static void xcf_read_property (SDL_RWops * src, xcf_prop * prop) {
+  unsigned int len;
prop->id = SDL_ReadBE32 (src);
prop->length = SDL_ReadBE32 (src);  
 
@@ -274,7 +275,11 @@
 break;
 case PROP_COMPRESSION:
case PROP_COLOR:
-    SDL_RWread (src, &prop->data, prop->length, 1);
+    if (prop->length>sizeof(prop->data))
+	len = sizeof(prop->data);
+    else
+	len = prop->length;
+    SDL_RWread (src, &prop->data, len, 1);
 break;
 case PROP_VISIBLE:
 prop->data.visible = SDL_ReadBE32 (src);

Timeline

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

Credit

Discovered by Yves Younan of Cisco Talos