mediamanager: fix invalid access to freed PurpleMediaAppDataInfo

Fri, 10 Jun 2016 18:22:28 +0200

author
Jakub Adam <jakub.adam@ktknet.cz>
date
Fri, 10 Jun 2016 18:22:28 +0200
changeset 37708
76f0178e3479
parent 37707
457ce85caedc
child 37709
e9a51548cdcb

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.

libpurple/mediamanager.c file | annotate | diff | comparison | revisions
--- a/libpurple/mediamanager.c	Fri Jun 10 16:47:02 2016 +0200
+++ b/libpurple/mediamanager.c	Fri Jun 10 18:22:28 2016 +0200
@@ -529,9 +529,24 @@
 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);
@@ -826,7 +841,14 @@
 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;
@@ -984,7 +1006,14 @@
 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;

mercurial