On Fri, Mar 22, 2019 at 08:22:05PM +0100, Stefan Sperling wrote: > For some time now I have noticed that logging into gnome from gdm > sometimes failed on my systems, even with my user account in the > 'staff' group to avoid the known problems with default resource limits. > Gnome failed to start, and often gdm would not restart properly when > this happened, leaving me with just a console screen. > > Today I found a core file from gnome-session-binary and with this > I could track the above problem down to a use-after-free in glib2.
This patch has been added to the ports tree, and then submitted upstream where problems were caught by regression tests: https://gitlab.gnome.org/GNOME/glib/merge_requests/741/ This updates our port to a new version of my patch which passes upstream's regression tests. Index: Makefile =================================================================== RCS file: /cvs/ports/devel/glib2/Makefile,v retrieving revision 1.297 diff -u -p -r1.297 Makefile --- Makefile 23 Mar 2019 08:51:15 -0000 1.297 +++ Makefile 25 Mar 2019 08:43:08 -0000 @@ -9,7 +9,7 @@ COMMENT= general-purpose utility librar GNOME_PROJECT= glib GNOME_VERSION= 2.58.3 PKGNAME= ${DISTNAME:S/glib/glib2/} -REVISION= 6 +REVISION= 7 CATEGORIES= devel Index: patches/patch-gio_gdbusprivate_c =================================================================== RCS file: /cvs/ports/devel/glib2/patches/patch-gio_gdbusprivate_c,v retrieving revision 1.1 diff -u -p -r1.1 patch-gio_gdbusprivate_c --- patches/patch-gio_gdbusprivate_c 23 Mar 2019 08:51:15 -0000 1.1 +++ patches/patch-gio_gdbusprivate_c 25 Mar 2019 08:43:28 -0000 @@ -1,5 +1,6 @@ $OpenBSD: patch-gio_gdbusprivate_c,v 1.1 2019/03/23 08:51:15 stsp Exp $ Fix use-after-free triggered by gnome-session-binary when Gnome restarts. +https://gitlab.gnome.org/GNOME/glib/merge_requests/741/ ostream_flush_cb() was calling flush_data_list_complete() with a single element list with an item that had already been freed: @@ -20,7 +21,45 @@ https://developer.gnome.org/glib/stable/ Index: gio/gdbusprivate.c --- gio/gdbusprivate.c.orig +++ gio/gdbusprivate.c -@@ -1788,10 +1788,17 @@ _g_dbus_worker_flush_sync (GDBusWorker *worker, +@@ -1190,13 +1190,6 @@ ostream_flush_cb (GObject *source_object, + } + } + +- g_assert (data->flushers != NULL); +- flush_data_list_complete (data->flushers, error); +- g_list_free (data->flushers); +- +- if (error != NULL) +- g_error_free (error); +- + /* Make sure we tell folks that we don't have additional + flushes pending */ + g_mutex_lock (&data->worker->write_lock); +@@ -1205,6 +1198,12 @@ ostream_flush_cb (GObject *source_object, + data->worker->output_pending = PENDING_NONE; + g_mutex_unlock (&data->worker->write_lock); + ++ g_assert (data->flushers != NULL); ++ flush_data_list_complete (data->flushers, error); ++ g_list_free (data->flushers); ++ if (error != NULL) ++ g_error_free (error); ++ + /* OK, cool, finally kick off the next write */ + continue_writing (data->worker); + +@@ -1373,6 +1372,10 @@ iostream_close_cb (GObject *source_object, + g_assert (worker->output_pending == PENDING_CLOSE); + worker->output_pending = PENDING_NONE; + ++ /* Ensure threads waiting for pending flushes to finish will be unblocked. */ ++ worker->write_num_messages_flushed = ++ worker->write_num_messages_written + g_list_length(pending_flush_attempts); ++ + g_mutex_unlock (&worker->write_lock); + + while (pending_close_attempts != NULL) +@@ -1788,10 +1791,17 @@ _g_dbus_worker_flush_sync (GDBusWorker *worker, if (data != NULL) {
