<<< Date Index >>>     <<< Thread Index >>>

[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-----