diff options
author | Jan Schmidt <thaytan@noraisin.net> | 2009-02-24 15:58:42 +0000 |
---|---|---|
committer | Jan Schmidt <thaytan@noraisin.net> | 2009-03-12 15:02:07 +0000 |
commit | 566583e87147f774e7fc4c78b5f7e61d427e40a9 (patch) | |
tree | 21dc3bbf5f70b649cbd89ad5b0828d18714ad12e | |
parent | 02339d2d4c50a5a4cc81614cf05ef6dd17252d65 (diff) |
vorbistag: Protect memory allocation calculation from overflow.
Patch by: Tomas Hoger <thoger@redhat.com> Fixes CVE-2009-0586
-rw-r--r-- | gst-libs/gst/tag/gstvorbistag.c | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/gst-libs/gst/tag/gstvorbistag.c b/gst-libs/gst/tag/gstvorbistag.c index 0999368e3..9401e61cc 100644 --- a/gst-libs/gst/tag/gstvorbistag.c +++ b/gst-libs/gst/tag/gstvorbistag.c @@ -305,30 +305,32 @@ gst_vorbis_tag_add (GstTagList * list, const gchar * tag, const gchar * value) } static void -gst_vorbis_tag_add_coverart (GstTagList * tags, const gchar * img_data_base64, +gst_vorbis_tag_add_coverart (GstTagList * tags, gchar * img_data_base64, gint base64_len) { GstBuffer *img; - guchar *img_data; gsize img_len; + guchar *out; guint save = 0; gint state = 0; if (base64_len < 2) goto not_enough_data; - img_data = g_try_malloc0 (base64_len * 3 / 4); - - if (img_data == NULL) - goto alloc_failed; - - img_len = g_base64_decode_step (img_data_base64, base64_len, img_data, - &state, &save); + /* img_data_base64 points to a temporary copy of the base64 encoded data, so + * it's safe to do inpace decoding here + * TODO: glib 2.20 and later provides g_base64_decode_inplace, so change this + * to use glib's API instead once it's in wider use: + * http://bugzilla.gnome.org/show_bug.cgi?id=564728 + * http://svn.gnome.org/viewvc/glib?view=revision&revision=7807 */ + out = (guchar *) img_data_base64; + img_len = g_base64_decode_step (img_data_base64, base64_len, + out, &state, &save); if (img_len == 0) goto decode_failed; - img = gst_tag_image_data_to_image_buffer (img_data, img_len, + img = gst_tag_image_data_to_image_buffer (out, img_len, GST_TAG_IMAGE_TYPE_NONE); if (img == NULL) @@ -338,7 +340,6 @@ gst_vorbis_tag_add_coverart (GstTagList * tags, const gchar * img_data_base64, GST_TAG_PREVIEW_IMAGE, img, NULL); gst_buffer_unref (img); - g_free (img_data); return; /* ERRORS */ @@ -347,21 +348,14 @@ not_enough_data: GST_WARNING ("COVERART tag with too little base64-encoded data"); return; } -alloc_failed: - { - GST_WARNING ("Couldn't allocate enough memory to decode COVERART tag"); - return; - } decode_failed: { - GST_WARNING ("Couldn't decode bas64 image data from COVERART tag"); - g_free (img_data); + GST_WARNING ("Couldn't decode base64 image data from COVERART tag"); return; } convert_failed: { GST_WARNING ("Couldn't extract image or image type from COVERART tag"); - g_free (img_data); return; } } @@ -457,6 +451,7 @@ error: return NULL; #undef ADVANCE } + typedef struct { guint count; |