mediamanager: fix invalid access to freed PurpleMediaAppDataInfo release-2.x.y

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

author
Jakub Adam <jakub.adam@ktknet.cz>
date
Fri, 10 Jun 2016 18:22:28 +0200
branch
release-2.x.y
changeset 37796
160437508477
parent 37795
d9aac4128ad2
child 37797
c82feeaefec2

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.

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
@@ -562,9 +562,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);
@@ -871,7 +886,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;
@@ -1029,7 +1051,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