pidgin/pidgin

294012def01e
Merged in fbellet/pidgin/use-after-free (pull request #634)

Use after free

Approved-by: Gary Kramlich
Approved-by: Elliott Sales de Andrade
--- a/libpurple/prefs.c Tue Feb 04 03:05:18 2020 +0000
+++ b/libpurple/prefs.c Wed Feb 05 02:20:05 2020 +0000
@@ -789,12 +789,15 @@
}
child = pref->first_child;
+ pref->first_child = NULL;
while (child) {
struct purple_pref *next;
if (child->first_child) {
next = child->first_child;
+ child->first_child = NULL;
} else if (child->sibling) {
next = child->sibling;
+ child->sibling = NULL;
free_pref(child);
} else {
if (child->parent != pref) {
--- a/libpurple/protocols/jabber/jabber.c Tue Feb 04 03:05:18 2020 +0000
+++ b/libpurple/protocols/jabber/jabber.c Wed Feb 05 02:20:05 2020 +0000
@@ -1599,8 +1599,18 @@
jabber_bosh_connection_destroy(js->bosh);
js->bosh = NULL;
} else if (js->output != NULL) {
- jabber_send_raw(js, "</stream:stream>", -1);
-
+ /* We should emit the stream termination message here
+ * normally, but since we destroy the jabber stream just
+ * after, it has no way to effectively go out on the
+ * wire. Moreover, it causes a connection lost error in
+ * the output queued stream that triggers an
+ * heap-use-after-free error in jabber_push_bytes_cb().
+ *
+ * This case happens when disabling the jabber account
+ * from the dialog box.
+ *
+ * jabber_send_raw(js, "</stream:stream>", -1);
+ */
if(js->inpa) {
g_source_remove(js->inpa);
js->inpa = 0;
--- a/pidgin/gtkutils.c Tue Feb 04 03:05:18 2020 +0000
+++ b/pidgin/gtkutils.c Wed Feb 05 02:20:05 2020 +0000
@@ -1463,9 +1463,9 @@
callback(object, data);
}
-GtkWidget *
-pidgin_append_menu_action(GtkWidget *menu, PurpleActionMenu *act,
- gpointer object)
+static GtkWidget *
+do_pidgin_append_menu_action(GtkWidget *menu, PurpleActionMenu *act,
+ gpointer object)
{
GtkWidget *menuitem;
GList *list;
@@ -1522,11 +1522,17 @@
for (l = list; l; l = l->next) {
PurpleActionMenu *act = (PurpleActionMenu *)l->data;
- pidgin_append_menu_action(submenu, act, object);
+ do_pidgin_append_menu_action(submenu, act, object);
}
- g_list_free(list);
- purple_action_menu_set_children(act, NULL);
}
+ return menuitem;
+}
+
+GtkWidget *
+pidgin_append_menu_action(GtkWidget *menu, PurpleActionMenu *act,
+ gpointer object)
+{
+ GtkWidget *menuitem = do_pidgin_append_menu_action(menu, act, object);
purple_action_menu_free(act);
return menuitem;
}