diff options
author | Peter Wu <peter@lekensteyn.nl> | 2015-07-23 17:13:54 +0200 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2015-07-26 00:46:13 -0400 |
commit | fffbe61c236500ec7600e3fbe248ebecfe799817 (patch) | |
tree | 819dc9ed50299cf2e155dc2041f90b4641d23b72 | |
parent | 030aa540ef9dbd405b422cb18305ff62c090c386 (diff) | |
download | gtk+-fffbe61c236500ec7600e3fbe248ebecfe799817.tar.gz |
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
-rw-r--r-- | gdk/broadway/broadway-server.c | 12 |
1 files 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); |