From fffbe61c236500ec7600e3fbe248ebecfe799817 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 23 Jul 2015 17:13:54 +0200 Subject: [PATCH] broadway: fix use-after-free on read errors Call chain: - input_data_cb - broadway_server_read_all_input_nonblocking (input) - broadway_input_free (input) (now input is invalid) attempt to use input->active -> use-after-free Make broadway_server_read_all_input_nonblocking return a boolean, TRUE if the input was valid, FALSE otherwise. This allows input_data_cb to detect whether the input was gone or not. https://bugzilla.gnome.org/show_bug.cgi?id=741685 --- gdk/broadway/broadway-server.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c index 42bc50a43a..9e659fff18 100644 --- a/gdk/broadway/broadway-server.c +++ b/gdk/broadway/broadway-server.c @@ -661,7 +661,7 @@ queue_process_input_at_idle (BroadwayServer *server) g_idle_add_full (G_PRIORITY_DEFAULT, (GSourceFunc)process_input_idle_cb, server, NULL); } -static void +static gboolean broadway_server_read_all_input_nonblocking (BroadwayInput *input) { GInputStream *in; @@ -670,7 +670,7 @@ broadway_server_read_all_input_nonblocking (BroadwayInput *input) GError *error = NULL; if (input == NULL) - return; + return FALSE; in = g_io_stream_get_input_stream (input->connection); @@ -683,7 +683,7 @@ broadway_server_read_all_input_nonblocking (BroadwayInput *input) g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_error_free (error); - return; + return TRUE; } if (input->server->input == input) @@ -694,12 +694,13 @@ broadway_server_read_all_input_nonblocking (BroadwayInput *input) g_printerr ("input error %s\n", error->message); g_error_free (error); } - return; + return FALSE; } g_byte_array_append (input->buffer, buffer, res); parse_input (input); + return TRUE; } static void @@ -720,7 +721,8 @@ input_data_cb (GObject *stream, { BroadwayServer *server = input->server; - broadway_server_read_all_input_nonblocking (input); + if (!broadway_server_read_all_input_nonblocking (input)) + return FALSE; if (input->active) process_input_messages (server);