diff options
author | Jakub Adam <jakub.adam@ktknet.cz> | 2016-06-10 18:22:28 +0200 |
---|---|---|
committer | Jakub Adam <jakub.adam@ktknet.cz> | 2016-06-10 18:22:28 +0200 |
commit | 4ebe17b240c6904cf4157a912151b1dea3a47921 (patch) | |
tree | c8404479bd30d52c1a4846398eaf9f975efe37d3 /libpurple/mediamanager.c | |
parent | 9c24ebe3b424febc46e77450674afee86297b9bd (diff) | |
download | pidgin-4ebe17b240c6904cf4157a912151b1dea3a47921.tar.gz |
mediamanager: fix invalid access to freed PurpleMediaAppDataInfo
appsrc_destroyed() and appsink_destroyed() may have read from/written to
appdata info after it had been freed. Reported by Valgrind.
Backport of Pidgin 3 commit 76f0178e3479.
Diffstat (limited to 'libpurple/mediamanager.c')
-rw-r--r-- | libpurple/mediamanager.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/libpurple/mediamanager.c b/libpurple/mediamanager.c index 34f066c3fd..3a17a323ac 100644 --- a/libpurple/mediamanager.c +++ b/libpurple/mediamanager.c @@ -562,9 +562,24 @@ purple_media_manager_get_private_media_by_account(PurpleMediaManager *manager, static void free_appdata_info_locked (PurpleMediaAppDataInfo *info) { + GstAppSrcCallbacks null_src_cb = { NULL, NULL, NULL, { NULL } }; + GstAppSinkCallbacks null_sink_cb = { NULL, NULL, NULL , { NULL } }; + if (info->notify) info->notify (info->user_data); + info->media = NULL; + if (info->appsrc) { + /* Will call appsrc_destroyed. */ + gst_app_src_set_callbacks (info->appsrc, &null_src_cb, + NULL, NULL); + } + if (info->appsink) { + /* Will call appsink_destroyed. */ + gst_app_sink_set_callbacks (info->appsink, &null_sink_cb, + NULL, NULL); + } + /* Make sure no other thread is using the structure */ g_free (info->session_id); g_free (info->participant); @@ -871,7 +886,14 @@ appsrc_seek_data (GstAppSrc *appsrc, guint64 offset, gpointer user_data) static void appsrc_destroyed (PurpleMediaAppDataInfo *info) { - PurpleMediaManager *manager = purple_media_manager_get (); + PurpleMediaManager *manager; + + if (!info->media) { + /* PurpleMediaAppDataInfo is being freed. Return at once. */ + return; + } + + manager = purple_media_manager_get (); g_mutex_lock (&manager->priv->appdata_mutex); info->appsrc = NULL; @@ -1029,7 +1051,14 @@ appsink_new_sample (GstAppSink *appsink, gpointer user_data) static void appsink_destroyed (PurpleMediaAppDataInfo *info) { - PurpleMediaManager *manager = purple_media_manager_get (); + PurpleMediaManager *manager; + + if (!info->media) { + /* PurpleMediaAppDataInfo is being freed. Return at once. */ + return; + } + + manager = purple_media_manager_get (); g_mutex_lock (&manager->priv->appdata_mutex); info->appsink = NULL; |