Wed, 05 Feb 2020 02:20:05 +0000
Merged in fbellet/pidgin/use-after-free (pull request #634)
Use after free
Approved-by: Gary Kramlich <grim@reaperworld.com>
Approved-by: Elliott Sales de Andrade <quantum.analyst@gmail.com>
| libpurple/protocols/jabber/jabber.c | file | annotate | diff | comparison | revisions |
--- 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; }