summaryrefslogtreecommitdiff
path: root/libpurple/mediamanager.c
diff options
context:
space:
mode:
authorJakub Adam <jakub.adam@ktknet.cz>2016-06-10 18:22:28 +0200
committerJakub Adam <jakub.adam@ktknet.cz>2016-06-10 18:22:28 +0200
commit4ebe17b240c6904cf4157a912151b1dea3a47921 (patch)
treec8404479bd30d52c1a4846398eaf9f975efe37d3 /libpurple/mediamanager.c
parent9c24ebe3b424febc46e77450674afee86297b9bd (diff)
downloadpidgin-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.c33
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;