Wed, 20 Sep 2017 09:48:24 -0400
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