Fix crash when cancelling an XMPP file transfer release-2.x.y

Thu, 02 Jun 2022 20:17:31 -0500

author
Belgin Știrbu <belginstirbu@hotmail.com>
date
Thu, 02 Jun 2022 20:17:31 -0500
branch
release-2.x.y
changeset 41421
4e0059800ba9
parent 41420
6fe6bf9a695b
child 41422
594d72369304

Fix crash when cancelling an XMPP file transfer

When an XMPP account has file transfers and the
connection to the XMPP server drops, the JabberStream object
gets g_free()'d, but the PurpleXfers still have pointers to it,
so when the file transfer finishes or is canceled, it tries
to remove itself from the JabberStream object and it ends up
accessing invalid memory, causing a crash.

This patch closes all file transfers associated to
a JabberStream object, right before the object gets g_free()'d.

Testing Done:
Reliably reproduced the crash by closing internet connection while a transfer was in progress. After the patch, the crash no longer occurs because the transfers all end when the internet connection drops.

Bugs closed: PIDGIN-17189

Reviewed at https://reviews.imfreedom.org/r/1485/

libpurple/protocols/jabber/jabber.c file | annotate | diff | comparison | revisions
--- a/libpurple/protocols/jabber/jabber.c	Thu Jun 02 20:15:50 2022 -0500
+++ b/libpurple/protocols/jabber/jabber.c	Thu Jun 02 20:17:31 2022 -0500
@@ -1579,6 +1579,27 @@
 	jabber_unregister_account_cb(js);
 }
 
+static void
+jabber_terminate_transfers(JabberStream *js)
+{
+	while(js->file_transfers != NULL) {
+		gpointer data = js->file_transfers->data;
+
+		purple_xfer_end(data);
+
+		if(js->file_transfers == NULL) {
+			break;
+		}
+
+		/* Forcefully remove the link if jabber_si_xfer_free doesn't
+		   remove the link. */
+		if(js->file_transfers->data == data) {
+			js->file_transfers = g_list_delete_link(js->file_transfers,
+								js->file_transfers);
+		}
+	}
+}
+
 /* TODO: As Will pointed out in IRC, after being notified by the core to
  * shutdown, we should async. wait for the server to send us the stream
  * termination before destorying everything. That seems like it would require
@@ -1591,6 +1612,8 @@
 	/* Close all of the open Jingle sessions on this stream */
 	jingle_terminate_sessions(js);
 
+	jabber_terminate_transfers(js);
+
 	if (js->bosh)
 		jabber_bosh_connection_close(js->bosh);
 	else if ((js->gsc && js->gsc->fd > 0) || js->fd > 0) {

mercurial