[TKADV2009-003] GStreamer Heap Overflow and Array Index out of Bounds Vulnerabilities
Please find attached a detailed advisory of the vulnerabilities.
Alternatively, the advisory can also be found at:
http://www.trapkit.de/advisories/TKADV2009-003.txt
-----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-----