-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Advisory: GStreamer Heap Overflow and Array Index out of Bounds Vulnerabilities Advisory ID: TKADV2009-003 Revision: 1.0 Release Date: 2009/01/22 Last Modified: 2009/01/22 Date Reported: 2009/01/17 Author: Tobias Klein (tk at trapkit.de) Affected Software: GStreamer gst-plugins-good < version 0.10.12 Remotely Exploitable: Yes Locally Exploitable: No Vendor URL: http://gstreamer.freedesktop.org/ Vendor Status: Vendor has released an updated version Patch development time: 5 days ====================== Vulnerability Details: ====================== GStreamer contains several heap buffer overflows and an array index out of bounds vulnerability while parsing malformed QuickTime media files. The vulnerabilities may be exploited by a (remote) attacker to execute arbitrary code in the context of an application using the GStreamer multimedia framework. The GStreamer framework is used by a lot of popular media players like Songbird [1], Totem [2] and Amarok [3]. ================== Technical Details: ================== Source code file: gst-plugins-good\gst\qtdemux\qtdemux.c Description of the first heap buffer overflow vulnerability (vuln #1): QuickTime 'ctts' Atom parsing [..] 2915 static gboolean 2916 qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, 2917 GNode * stbl) 2918 { .. 3145 /* composition time to sample */ 3146 if ((ctts = qtdemux_tree_get_child_by_type (stbl, FOURCC_ctts))) { 3147 const guint8 *ctts_data = (const guint8 *) ctts->data; 3148 guint32 n_entries = QT_UINT32 (ctts_data + 12); 3149 guint32 count; 3150 gint32 soffset; 3151 3152 /* Fill in the pts_offsets */ 3153 for (i = 0, j = 0; (j < stream->n_samples) && (i < n_entries); i++) { 3154 [1] count = QT_UINT32 (ctts_data + 16 + i * 8); 3155 [2] soffset = QT_UINT32 (ctts_data + 20 + i * 8); 3156 [3] for (k = 0; k < count; k++, j++) { 3157 /* we operate with very small soffset values here, it shouldn't overflow */ 3158 [4] samples[j].pts_offset = soffset * GST_SECOND / stream->timescale; 3159 } 3160 } 3161 } [..] [1] The unsigned int variable "count" is filled with user supplied data from the media file [2] The int variable "soffset" is also filled with user supplied data from the media file [3] The (loop) counters "k", "count" and "j" can be controlled by the user [4] User controlled data ("soffset * GST_SECOND / stream->timescale") gets copied into the heap buffer "samples[]" while "j" is used as an array index This leads to a heap buffer overflow vulnerability that may be exploited to execute arbitrary code in the context of an application using the GStreamer framework. Exploitation is not easy and may even be impossible as the written data can only be controlled to some extend. Description of the array index out of bounds vulnerability (vuln #2): QuickTime 'stss' Atom parsing [..] 3045 if (stss) { 3046 /* mark keyframes */ 3047 guint32 n_sample_syncs; 3048 3049 [1] n_sample_syncs = QT_UINT32 ((guint8 *) stss->data + 12); 3050 if (n_sample_syncs == 0) { 3051 stream->all_keyframe = TRUE; 3052 } else { 3053 offset = 16; 3054 [2] for (i = 0; i < n_sample_syncs; i++) { 3055 /* note that the first sample is index 1, not 0 */ 3056 [3] index = QT_UINT32 ((guint8 *) stss->data + offset); 3057 if (index > 0) { 3058 [4] samples[index - 1].keyframe = TRUE; 3059 offset += 4; 3060 } 3061 } 3062 } 3063 } else { [..] [1] The unsigned int variable "n_sample_syncs" is filled with user supplied data from the media file [2] "n_sample_syncs" is used as a loop counter [3] The int variable "index" is filled with user supplied data from the media file [4] As the user controlled value of "index" is used as an array index for the "samples[]" buffer it is possible to write the int value 0x00000001 to (nearly) any location in memory. A malicious party may exploit this issue to execute arbitrary code by overwriting a sensitive memory location (such as a buffer length or boolean variable). Description of the second heap buffer overflow vulnerability (vuln #3): QuickTime 'stts' Atom parsing [..] 3018 [1] n_sample_times = QT_UINT32 ((guint8 *) stts->data + 12); 3019 timestamp = 0; 3020 stream->min_duration = 0; 3021 time = 0; 3022 index = 0; 3023 [2] for (i = 0; i < n_sample_times; i++) { 3024 guint32 n; 3025 guint32 duration; 3026 3027 [3] n = QT_UINT32 ((guint8 *) stts->data + 16 + 8 * i); 3028 [8] duration = QT_UINT32 ((guint8 *) stts->data + 16 + 8 * i + 4); 3029 [4] for (j = 0; j < n; j++) { 3030 GST_DEBUG_OBJECT (qtdemux, "sample %d: timestamp %" GST_TIME_FORMAT, 3031 index, GST_TIME_ARGS (timestamp)); 3032 3033 [5] samples[index].timestamp = timestamp; 3034 /* take first duration for fps */ 3035 if (stream->min_duration == 0) 3036 stream->min_duration = duration; 3037 /* add non-scaled values to avoid rounding errors */ 3038 [9] time += duration; 3039 [10] timestamp = gst_util_uint64_scale (time, GST_SECOND, stream->timescale); 3040 [6] samples[index].duration = timestamp - samples[index].timestamp; 3041 3042 [7] index++; 3043 } 3044 } [..] [1] The int variable "n_sample_times" is filled with user supplied data from the media file [2] "n_sample_times" is used as a loop counter [3] The unsigned int variable "n" is filled with user supplied data from the media file [4] "n" is used as a loop counter [5] + [6] Partly user controlled data (see [8], [9] and [10]) is copied into the "samples[]" buffer while "index" is used as an array index. As "index" is incremented with each loop (see [7]) -- and the loop counter "n" is user controlled, see [3] and [4] -- it is possible to write beyond the bounds of the "samples[]" buffer This leads to a heap buffer overflow vulnerability that may be exploited to execute arbitrary code in the context of an application using the GStreamer framework. Exploitation is not easy and may even be impossible as the written data can only be controlled to some extend. ========= Solution: ========= Upgrade to GStreamer gst-plugins-good version >= 0.10.12. ======== History: ======== 2009/01/17 - GStreamer maintainers notified 2009/01/20 - Patch developed by GStreamer maintainers 2009/01/22 - Release date of new (fixed) version of GStreamer 2009/01/22 - Release date of this security advisory ======== Credits: ======== Vulnerability found and advisory written by Tobias Klein. =========== References: =========== [1] http://getsongbird.com/ [2] http://projects.gnome.org/totem/ [3] http://amarok.kde.org/ [4] http://cgit.freedesktop.org/gstreamer/gst-plugins- good/commit/?id=bdc20b9baf13564d9a061343416395f8f9a92b53 [5] http://www.trapkit.de/advisories/TKADV2009-003.txt ======== Changes: ======== Revision 0.1 - Initial draft release to the vendor Revision 1.0 - Public release =========== Disclaimer: =========== The information within this advisory may change without notice. Use of this information constitutes acceptance for use in an AS IS condition. There are no warranties, implied or express, with regard to this information. In no event shall the author be liable for any direct or indirect damages whatsoever arising out of or in connection with the use or spread of this information. Any use of this information is at the user's own risk. ================== PGP Signature Key: ================== http://www.trapkit.de/advisories/tk-advisories-signature-key.asc Copyright 2009 Tobias Klein. All rights reserved. -----BEGIN PGP SIGNATURE----- Version: GnuPG iD8DBQFJeOFVkXxgcAIbhEERAj1JAKCcH8fTcU75KjBgLOABD9wqUq+y1gCgnH5s O6PAKd1FPZy4ver1GQ3CRB0= =XQyw -----END PGP SIGNATURE-----