jabber: Avoid a use-after-free in an error path release-2.x.y

Wed, 20 Sep 2017 09:48:24 -0400

author
Debarshi Ray <rishi@gnu.org>
date
Wed, 20 Sep 2017 09:48:24 -0400
branch
release-2.x.y
changeset 38693
12476654da77
parent 38657
b185e9184501
child 38694
9e24abcbf166

jabber: Avoid a use-after-free in an error path
If jabber_buddy_find_resource returned NULL, 'resource' was being used
to print an error after it had already been freed. The easiest way to
prevent that is to consolidate all the local resource deallocation and
exit paths in one place.

Fixes #17200

libpurple/protocols/jabber/jingle/rtp.c file | annotate | diff | comparison | revisions
--- a/libpurple/protocols/jabber/jingle/rtp.c	Mon Sep 18 22:10:58 2017 -0500
+++ b/libpurple/protocols/jabber/jingle/rtp.c	Wed Sep 20 09:48:24 2017 -0400
@@ -950,6 +950,7 @@
 	JingleTransport *transport;
 	JabberBuddy *jb;
 	JabberBuddyResource *jbr;
+	gboolean ret = FALSE;
 	const gchar *transport_type;
 
 	gchar *resource = NULL, *me = NULL, *sid = NULL;
@@ -958,16 +959,15 @@
 	jb = jabber_buddy_find(js, who, FALSE);
 	if (!jb) {
 		purple_debug_error("jingle-rtp", "Could not find Jabber buddy\n");
-		return FALSE;
+		goto out;
 	}
 
 	resource = jabber_get_resource(who);
 	jbr = jabber_buddy_find_resource(jb, resource);
-	g_free(resource);
 
 	if (!jbr) {
 		purple_debug_error("jingle-rtp", "Could not find buddy's resource - %s\n", resource);
-		return FALSE;
+		goto out;
 	}
 
 	if (jabber_resource_has_capability(jbr, JINGLE_TRANSPORT_ICEUDP)) {
@@ -977,7 +977,7 @@
 	} else {
 		purple_debug_error("jingle-rtp", "Resource doesn't support "
 				"the same transport types\n");
-		return FALSE;
+		goto out;
 	}
 
 	/* set ourselves as initiator */
@@ -985,7 +985,6 @@
 
 	sid = jabber_get_next_id(js);
 	session = jingle_session_create(js, sid, me, who, TRUE);
-	g_free(sid);
 
 
 	if (type & PURPLE_MEDIA_AUDIO) {
@@ -1005,13 +1004,17 @@
 		jingle_rtp_init_media(content);
 	}
 
-	g_free(me);
-
 	if (jingle_rtp_get_media(session) == NULL) {
-		return FALSE;
+		goto out;
 	}
 
-	return TRUE;
+	ret = TRUE;
+
+out:
+	g_free(me);
+	g_free(resource);
+	g_free(sid);
+	return ret;
 }
 
 void

mercurial